package com.redhat.ceylon.eclipse.imp.editor;

import java.util.Comparator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.imp.editor.UniversalEditor;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;

import com.redhat.ceylon.compiler.typechecker.context.PhasedUnit;
import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.eclipse.imp.builder.CeylonBuilder;
import com.redhat.ceylon.eclipse.imp.contentProposer.CeylonContentProposer;
import com.redhat.ceylon.eclipse.imp.treeModelBuilder.CeylonLabelProvider;
import com.redhat.ceylon.eclipse.ui.CeylonPlugin;

public class FilteredTypesSelectionDialog extends FilteredItemsSelectionDialog {
    private UniversalEditor editor;
    
    public FilteredTypesSelectionDialog(Shell shell, UniversalEditor editor) {
        super(shell);
        this.editor = editor;
        setListLabelProvider(new ILabelProvider() {
            @Override
            public void addListener(ILabelProviderListener listener) {}
            @Override
            public void dispose() {}
            @Override
            public boolean isLabelProperty(Object element, String property) {
                // TODO Auto-generated method stub
                return false;
            }
            @Override
            public void removeListener(ILabelProviderListener listener) {}
            @Override
            public Image getImage(Object element) {
                return CeylonLabelProvider.getImage((Declaration) element);
            }
            @Override
            public String getText(Object element) {
                return CeylonContentProposer.getDescriptionFor((Declaration) element);
            }            
        });
        setDetailsLabelProvider(new ILabelProvider() {
            @Override
            public void removeListener(ILabelProviderListener listener) {}
            @Override
            public boolean isLabelProperty(Object element, String property) {
                return false;
            }
            @Override
            public void dispose() {}
            @Override
            public void addListener(ILabelProviderListener listener) {}
            @Override
            public String getText(Object element) {
                return "[" + CeylonDocumentationProvider.getPackageLabel((Declaration) element) + "]" +
                        " - " + ((Declaration) element).getUnit().getFilename();
            }
            @Override
            public Image getImage(Object element) {
                return CeylonLabelProvider.PACKAGE;
            }
        });
    }
    
    public FilteredTypesSelectionDialog(Shell shell, boolean multi) {
        super(shell, multi);
    }
    
    @Override
    protected Control createExtendedContentArea(Composite parent) {
        return null;
    }
    
    @Override
    protected IDialogSettings getDialogSettings() {
        return CeylonPlugin.getInstance().getDialogSettings();
    }
    
    @Override
    protected IStatus validateItem(Object item) {
        return Status.OK_STATUS; //(IStatus.OK, CeylonPlugin.kPluginID, 0, "", null); //$NON-NLS-1$
    }
    
    @Override
    protected ItemsFilter createFilter() {
        return new ItemsFilter() {
            @Override
            public boolean matchItem(Object item) {
                return matchesRawNamePattern(item);
            }
            @Override
            public boolean isConsistentItem(Object item) {
                return true;
            }
        };
    }
    
    @Override
    protected Comparator getItemsComparator() {
        return new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((Declaration) o1).getName().compareTo(((Declaration) o2).getName());
            }
        };
    }
    
    @Override
    protected void fillContentProvider(AbstractContentProvider contentProvider,
            ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException {
        IFileEditorInput input = (IFileEditorInput) editor.getEditorInput();
        for (PhasedUnit unit: CeylonBuilder.getUnits(input.getFile().getProject())) {
            for (Declaration dec: unit.getPackage().getMembers()) {
                contentProvider.add(dec, itemsFilter);
            }
        }
    }
    
    @Override
    public String getElementName(Object item) {
        return ((Declaration) item).getName();
    }
    
    @Override
    protected void setResult(List newResult) {
        super.setResult(newResult);
    }
}

@@ -673,16 +673,48 @@
 rInput;%0A
+import org.eclipse.ui.IMemento;%0A
 import o
@@ -765,16 +765,16 @@
 Dialog;%0A
-
 %0Aimport 
@@ -1277,24 +1277,1411 @@
 ditor;%0A    %0A
+    private class TypeSelectionHistory extends SelectionHistory %7B%0A        protected Object restoreItemFromMemento(IMemento element) %7B%0A            String qualifiedName = element.getString(%22qualifiedName%22);%0A            String unitFileName = element.getString(%22unitFileName%22);%0A            String packageName = element.getString(%22packageName%22);%0A            IFileEditorInput input = (IFileEditorInput) editor.getEditorInput();%0A            for (PhasedUnit unit: CeylonBuilder.getUnits(input.getFile().getProject())) %7B%0A                if (unit.getUnit().getFilename().equals(unitFileName)%0A                        && unit.getPackage().getQualifiedNameString().equals(packageName)) %7B%0A                    for (Declaration dec: unit.getPackage().getMembers()) %7B%0A                        if (dec.getQualifiedNameString().equals(qualifiedName)) %7B%0A                            return dec;%0A                        %7D%0A                    %7D%0A                %7D%0A           %7D%0A           return null; %0A        %7D%0A        protected void storeItemToMemento(Object item, IMemento element) %7B%0A            Declaration dec = (Declaration) item;%0A            element.putString(%22qualifiedName%22, dec.getQualifiedNameString());%0A            element.putString(%22unitFileName%22, dec.getUnit().getFilename());%0A            element.putString(%22packageName%22, dec.getUnit().getPackage().getQualifiedNameString());%0A        %7D%0A     %7D%0A    %0A
     public F
@@ -2769,16 +2769,16 @@
 shell);%0A
-
         
@@ -2795,24 +2795,81 @@
 r = editor;%0A
+        setSelectionHistory(new TypeSelectionHistory());%0A
         setL

add history