/**
 * Copyright (c) 2005-2013 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Eclipse Public License (EPL).
 * Please see the license.txt included with this distribution for details.
 * Any modifications to this file must keep this entire header intact.
 */
package org.python.pydev.ui.dialogs;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.python.pydev.editor.codecompletion.revisited.PythonPathHelper;
import org.python.pydev.plugin.PydevPlugin;

/**
 * Dialog to choose a Python module from a project
 * 
 * @author Mikko Ohtamaa
 */
public class PythonModulePickerDialog extends ElementTreeSelectionDialog {

    public PythonModulePickerDialog(Shell parent, String title, String message, IProject project, boolean unitTesting) {
        super(parent, new WorkbenchLabelProvider(), new PythonModuleContentProvider());
        setAllowMultiple(unitTesting);
        this.setEmptyListMessage("No Python modules in project " + project.getName());
        this.setInput(project);
        this.setTitle(title);
        this.setMessage(message);

        // Do not allow multiple selection of packages / modules for non-Unittest runs
        if (!unitTesting) {
            this.setValidator(new ISelectionStatusValidator() {
                @Override
                public IStatus validate(Object selection[]) {
                    if (selection.length >= 1) {
                        if (selection[0] instanceof IFile) {
                            IFile file = (IFile) selection[0];
                            return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module  "
                                    + file.getName() + " selected", null);

                        } else if (selection[0] instanceof IFolder) {
                            IFolder folder = (IFolder) selection[0];

                            if (folder.findMember("__main__.py") == null) {
                                return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR,
                                        "Can't find '__main__' module in this folder.",
                                        null);
                            } else {
                                return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module "
                                        + folder.getName() + " selected", null);
                            }
                        }
                    }
                    return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR,
                            "No Python module selected",
                            null);

                }
            });
        }
        else {
            this.setValidator(new ISelectionStatusValidator() {
                @Override
                public IStatus validate(Object selection[]) {
                    for (int i = 0; i < selection.length; i++) {
                        if (!(selection[i] instanceof IFolder)) {
                            continue;
                        }
                        IFolder folder = (IFolder) selection[i];
                        // Ignore .* folders, like .settings
                        if (folder.getFileExtension() != null)
                        {
                            return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR,
                                    "Invalid selection: " + folder.getFileExtension(), null);
                        }
                    }
                    if (selection.length == 1) {
                        if (selection[0] instanceof IFile) {
                            IFile file = (IFile) selection[0];
                            return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Module "
                                    + file.getName() + " selected", null);
                        }
                        else if (selection[0] instanceof IFolder) {
                            IFolder folder = (IFolder) selection[0];
                            return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Package "
                                    + folder.getName() + " selected", null);
                        }
                    }
                    else if (selection.length > 1) {
                        return new Status(IStatus.OK, PydevPlugin.getPluginID(), IStatus.OK, "Multiple items selected",
                                null);
                    }
                    return new Status(IStatus.ERROR, PydevPlugin.getPluginID(), IStatus.ERROR, "Nothing selected",
                            null);

                }
            });
        }
    }
}

class PythonModuleContentProvider implements ITreeContentProvider {

    /**
     * Creates a new ContainerContentProvider.
     */
    PythonModuleContentProvider() {
    }

    /**
     * The visual part that is using this content provider is about
     * to be disposed. Deallocate all allocated SWT resources.
     */
    @Override
    public void dispose() {
    }

    /*
     * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
     */
    @Override
    public Object[] getChildren(Object element) {

        if (element instanceof IContainer) {
            IContainer container = (IContainer) element;

            if (container.isAccessible()) {
                try {
                    List<IResource> children = new ArrayList<IResource>();

                    IResource[] members = container.members();

                    for (int i = 0; i < members.length; i++) {

                        if (members[i] instanceof IFile) {

                            IFile file = (IFile) members[i];

                            if (PythonPathHelper.isValidSourceFile(file)) {
                                children.add(file);
                            }
                        } else if (members[i] instanceof IContainer) {
                            children.add(members[i]);
                        }
                    }
                    return children.toArray();
                } catch (CoreException e) {
                    // this should never happen because we call #isAccessible before invoking #members
                }
            }
        }

        return new Object[0];
    }

    /*
     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
     */
    @Override
    public Object[] getElements(Object element) {
        return getChildren(element);
    }

    /*
     * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
     */
    @Override
    public Object getParent(Object element) {
        if (element instanceof IResource) {
            return ((IResource) element).getParent();
        }
        return null;
    }

    /*
     * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
     */
    @Override
    public boolean hasChildren(Object element) {
        return getChildren(element).length > 0;
    }

    /*
     * @see org.eclipse.jface.viewers.IContentProvider#inputChanged
     */
    @Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
    }

}
