/*******************************************************************************
 * Copyright (c) 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.sse.ui.preferences;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.Command;
import org.eclipse.core.commands.CommandManager;
import org.eclipse.core.commands.ParameterizedCommand;
import org.eclipse.core.commands.common.NotDefinedException;
import org.eclipse.core.commands.contexts.ContextManager;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.bindings.BindingManager;
import org.eclipse.jface.bindings.Scheme;
import org.eclipse.jface.bindings.TriggerSequence;
import org.eclipse.jface.layout.PixelConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.commands.ICommandService;
import org.eclipse.ui.keys.IBindingService;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
import org.eclipse.wst.sse.ui.internal.contentassist.CompletionProposalCategory;
import org.eclipse.wst.sse.ui.internal.contentassist.CompletionProposalComputerRegistry;
import org.eclipse.wst.sse.ui.internal.util.SWTUtil;


/**
 * <p>A helpful preference configuration block implementation for allowing a user to
 * set their preferences for which content assist categories to show on the default
 * content assist page as well as on their own separate page and page ordering for
 * a specific content type</p>
 * 
 * @base org.eclipse.jdt.internal.ui.preferences.CodeAssistAdvancedConfigurationBlock
 */
public final class CodeAssistCyclingConfigurationBlock  {

	/**
	 * <p>Used to compare categories based on their assigned page rank</p>
	 */
	private final Comparator fCategoryPageComparator = new Comparator() {
		private int getRank(Object o) {
			return ((ModelElement) o).getOwnPageRank();
		}

		public int compare(Object o1, Object o2) {
			int result = getRank(o1) - getRank(o2);
			if(result == 0) {
				result = ((ModelElement) o1).getId().compareTo(((ModelElement) o2).getId());
			}
			return result;
		}
	};
	
	/**
	 * <p>Used to compare categories based on their assigned default page rank</p>
	 */
	private final Comparator fCategoryDefaultPageComparator = new Comparator() {
		private int getRank(Object o) {
			return ((ModelElement) o).getDefaultPageRank();
		}

		public int compare(Object o1, Object o2) {
			int result = getRank(o1) - getRank(o2);
			if(result == 0) {
				result = ((ModelElement) o1).getId().compareTo(((ModelElement) o2).getId());
			}
			return result;
		}
	};

	/** the preference model for this block */
	private final PreferenceModel fModel;
	
	/**
	 * <code>{@link Map}<{@link ImageDescriptor}, {@link Image}></code>
	 */
	private final Map fImages= new HashMap();

	/** table viewer to configure which categories are displayed on the default page */
	private CheckboxTableViewer fDefaultPageViewer;
	
	/**
	 * table viewer to configure which categories are displayed
	 * on their own page, as well as their ordering
	 */
	private CheckboxTableViewer fOwnPageViewer;
	
	/** categories pages sort order up button */
	private Button fPageOrderUpButton;
	
	/** categories pages sort order down button */
	private Button fPageOrderDownButton;
	
	/** categories default page sort order up button */
	private Button fDefaultPageOrderUpButton;
	
	/** categories default page  sort order down button */
	private Button fDefaultPageOrderDownButton;
	
	/** The content type ID this configuration block is for */
	private String fContentTypeID;
	
	/** The writable categories configuration */
	private ICompletionProposalCategoriesConfigurationWriter fConfigurationWriter;

	/**
	 * <p>Creates a new content assist preference block for the given content type
	 * using the given configuration writer</p>
	 * 
	 * @param contentTypeID content type this content assist preference block is for
	 * @param configurationWriter {@link ICompletionProposalCategoriesConfigurationWriter} used
	 * to read and write the user preferences 
	 */
	public CodeAssistCyclingConfigurationBlock(String contentTypeID, ICompletionProposalCategoriesConfigurationWriter configurationWriter) {
		this.fContentTypeID = contentTypeID;
		this.fConfigurationWriter = configurationWriter;
		
		List categories = CompletionProposalComputerRegistry.getDefault().getProposalCategories(this.fContentTypeID);
		this.fModel = new PreferenceModel(categories);
	}
	
	/**
	 * <p>Saves the user configuration</p>
	 * @return <code>true</code> if store was successful, <code>false</code> otherwise
	 */
	public boolean storeValues() {
		return this.fConfigurationWriter.saveConfiguration();
	}
	
	/**
	 * <p>Loads the preference defaults</p>
	 */
	public void performDefaults() {
		this.fConfigurationWriter.loadDefaults();
		this.initializeValues();
		this.fModel.performDefaults();
	}
	
	/**
	 * <p>Disposes of this preference block</p>
	 */
	public void dispose() {
		for (Iterator it= fImages.values().iterator(); it.hasNext();) {
			Image image= (Image) it.next();
			image.dispose();
		}
	}

	/**
	 * <p>Creates the contents of this configuration block using a {@link Group} if
	 * the given <code>groupTitle</code> is not <code>null</code> else creates it
	 * as a composite and in either case adds itself to the given parent</p>
	 * 
	 * @param parent {@link Composite} parent to add this configuration block to
	 * @param groupTitle Title to use for the configuration block group, if
	 * <code>null</code> then a {@link Composite} will be used instead of a
	 * {@link Group}
	 * 
	 * @return the created configuration block that has already been added to the parent
	 */
	public Control createContents(Composite parent, String groupTitle) {
		Composite container;
		if(groupTitle != null) {
			container = new Group(parent, SWT.NULL);
			((Group)container).setText(groupTitle);
		} else {
			container = new Composite(parent, SWT.NULL);
		}
		int columns= 2;
		GridLayout layout= new GridLayout(columns, false);
		container.setLayout(layout);
		
		GridData data = new GridData(GridData.FILL);
		data.horizontalIndent = 0;
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		container.setLayoutData(data);

		createDefaultPageLabel(container, columns);
		createDefaultPageSection(container);

		createFiller(container, columns);

		createOwnPageLabel(container, columns);
        createOwnPageSection(container);

        createFiller(container, columns);

		if (fModel.pageElements.size() > 0) {
			fDefaultPageViewer.getTable().select(0);
			fOwnPageViewer.getTable().select(0);
			handleOwnPageTableSelection();
			handleDefaultPageTableSelection();
		}
		
		return container;
	}
	
	/**
	 * <p>Initialize the values of the configuration block</p>
	 */
	public void initializeValues() {
		updateCheckedState();
		fDefaultPageViewer.refresh();
		fOwnPageViewer.refresh();
		handleOwnPageTableSelection();
		handleDefaultPageTableSelection();
	}
	
	private void createDefaultPageSection(Composite composite) {
		createDefaultPageViewer(composite);
		createDefaultPageButtonList(composite);
	}

	private void createDefaultPageLabel(Composite composite, int h_span) {
	    final ICommandService commandSvc= (ICommandService) PlatformUI.getWorkbench().getAdapter(ICommandService.class);
		final Command command= commandSvc.getCommand(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		ParameterizedCommand pCmd= new ParameterizedCommand(command, null);
		String key= getKeyboardShortcut(pCmd);
		if (key == null) {
			key= SSEUIMessages.CodeAssistAdvancedConfigurationBlock_no_shortcut;
		}

		PixelConverter pixelConverter= new PixelConverter(composite);
		int width= pixelConverter.convertWidthInCharsToPixels(40);

		Label label= new Label(composite, SWT.NONE | SWT.WRAP);
		label.setText(NLS.bind(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_page_description, new Object[] { key }));
		GridData gd= new GridData(GridData.FILL, GridData.FILL, true, false, h_span, 1);
		gd.widthHint= width;
		label.setLayoutData(gd);

		createFiller(composite, h_span);

		label= new Label(composite, SWT.NONE | SWT.WRAP);
		label.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_default_table_description);
		gd= new GridData(GridData.FILL, GridData.FILL, true, false, h_span, 1);
		gd.widthHint= width;
		label.setLayoutData(gd);
    }

	private void createDefaultPageViewer(Composite composite) {
		fDefaultPageViewer= CheckboxTableViewer.newCheckList(composite, SWT.SINGLE | SWT.BORDER);
		Table table= fDefaultPageViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(false);
		table.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, false, false, 1, 1));

		TableColumn nameColumn= new TableColumn(table, SWT.NONE);
		nameColumn.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_default_table_category_column_title);
		nameColumn.setResizable(false);

		fDefaultPageViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				boolean checked= event.getChecked();
				ModelElement element= (ModelElement) event.getElement();
				element.setShouldDisplayOnDefaultPage(checked);
			}
		});

		fDefaultPageViewer.setContentProvider(new ArrayContentProvider());

		DefaultPageTableLabelProvider labelProvider= new DefaultPageTableLabelProvider();
		fDefaultPageViewer.setLabelProvider(labelProvider);
		fDefaultPageViewer.setInput(fModel.defaultPageElements);
		fDefaultPageViewer.setComparator(new ModelViewerComparator(fCategoryDefaultPageComparator));

		final int ICON_AND_CHECKBOX_WITH= 50;
		final int HEADER_MARGIN= 20;
		int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN;
		for (int i= 0; i < fModel.defaultPageElements.size(); i++) {
			minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.defaultPageElements.get(i), 0)) + ICON_AND_CHECKBOX_WITH);
		}

		nameColumn.setWidth(minNameWidth);
		
		table.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleDefaultPageTableSelection();
			}
		});
	}
	
	/**
	 * <p>Create the Up and Down buttons for the default page viewer</p>
	 * @param parent {@link Composite} to add the button list to 
	 */
	private void createDefaultPageButtonList(Composite parent) {
		Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));

		GridLayout layout= new GridLayout();
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		composite.setLayout(layout);

		fDefaultPageOrderUpButton= new Button(composite, SWT.PUSH | SWT.CENTER);
		fDefaultPageOrderUpButton.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_Up);
		fDefaultPageOrderUpButton.addSelectionListener(new SelectionAdapter() {
        	public void widgetSelected(SelectionEvent e) {
        		int index = fDefaultPageViewer.getTable().getSelectionIndex();
        		if (index != -1) {
        			fModel.moveDefaultPageCategoryUp(index);
        			fDefaultPageViewer.refresh();
        			handleDefaultPageTableSelection();
        		}
        	}
        });
		fDefaultPageOrderUpButton.setLayoutData(new GridData());
        
        SWTUtil.setButtonDimensionHint(fDefaultPageOrderUpButton);

        fDefaultPageOrderDownButton= new Button(composite, SWT.PUSH | SWT.CENTER);
        fDefaultPageOrderDownButton.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_Down);
        fDefaultPageOrderDownButton.addSelectionListener(new SelectionAdapter() {
        	public void widgetSelected(SelectionEvent e) {
        		int index= fDefaultPageViewer.getTable().getSelectionIndex();
        		if (index != -1) {
        			fModel.moveDefaultPageCategoryDown(index);
        			fDefaultPageViewer.refresh();
        			handleDefaultPageTableSelection();
        		}
        	}
        });
        fDefaultPageOrderDownButton.setLayoutData(new GridData());
        SWTUtil.setButtonDimensionHint(fDefaultPageOrderDownButton);
	}

	private void createFiller(Composite composite, int h_span) {
	    Label filler= new Label(composite, SWT.NONE);
		filler.setVisible(false);
		filler.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, h_span, 1));
    }

	private void createOwnPageLabel(Composite composite, int h_span) {
		PixelConverter pixelConverter= new PixelConverter(composite);
		int width= pixelConverter.convertWidthInCharsToPixels(40);

		Label label= new Label(composite, SWT.NONE | SWT.WRAP);
		label.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_separate_table_description);
		GridData gd= new GridData(GridData.FILL, GridData.FILL, false, false, h_span, 1);
		gd.widthHint= width;
		label.setLayoutData(gd);
	}

	private void createOwnPageSection(Composite composite) {
		createOwnPageViewer(composite);
		createOwnPageButtonList(composite);
	}

	private void createOwnPageViewer(Composite composite) {
		fOwnPageViewer= CheckboxTableViewer.newCheckList(composite, SWT.SINGLE | SWT.BORDER);
		Table table= fOwnPageViewer.getTable();
		table.setHeaderVisible(true);
		table.setLinesVisible(false);
		table.setLayoutData(new GridData(GridData.FILL, GridData.BEGINNING, true, false, 1, 1));

		TableColumn nameColumn= new TableColumn(table, SWT.NONE);
		nameColumn.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_separate_table_category_column_title);
		nameColumn.setResizable(false);

		fOwnPageViewer.setContentProvider(new ArrayContentProvider());

		ITableLabelProvider labelProvider= new OwnPageTableLabelProvider();
		fOwnPageViewer.setLabelProvider(labelProvider);
		fOwnPageViewer.setInput(fModel.pageElements);
		fOwnPageViewer.setComparator(new ModelViewerComparator(fCategoryPageComparator));

		final int ICON_AND_CHECKBOX_WITH= 50;
		final int HEADER_MARGIN= 20;
		int minNameWidth= computeWidth(table, nameColumn.getText()) + HEADER_MARGIN;
		for (int i= 0; i < fModel.pageElements.size(); i++) {
			minNameWidth= Math.max(minNameWidth, computeWidth(table, labelProvider.getColumnText(fModel.pageElements.get(i), 0)) + ICON_AND_CHECKBOX_WITH);
		}

		nameColumn.setWidth(minNameWidth);

		fOwnPageViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent event) {
				boolean checked= event.getChecked();
				ModelElement element= (ModelElement) event.getElement();
				element.setShouldDisplayOnOwnPage(checked);
			}
		});

		table.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleOwnPageTableSelection();
			}
		});

	}

	/**
	 * <p>Create the Up and Down buttons for the own page viewer</p>
	 * @param parent {@link Composite} to add the button list to 
	 */
	private void createOwnPageButtonList(Composite parent) {
		Composite composite= new Composite(parent, SWT.NONE);
		composite.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));

		GridLayout layout= new GridLayout();
		layout.marginWidth= 0;
		layout.marginHeight= 0;
		composite.setLayout(layout);

		fPageOrderUpButton= new Button(composite, SWT.PUSH | SWT.CENTER);
        fPageOrderUpButton.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_PagesUp);
        fPageOrderUpButton.addSelectionListener(new SelectionAdapter() {
        	public void widgetSelected(SelectionEvent e) {
        		int index = fOwnPageViewer.getTable().getSelectionIndex();
        		if (index != -1) {
        			fModel.movePageUp(index);
        			fOwnPageViewer.refresh();
        			handleOwnPageTableSelection();
        		}
        	}
        });
        fPageOrderUpButton.setLayoutData(new GridData());
        
        SWTUtil.setButtonDimensionHint(fPageOrderUpButton);

        fPageOrderDownButton= new Button(composite, SWT.PUSH | SWT.CENTER);
        fPageOrderDownButton.setText(SSEUIMessages.CodeAssistAdvancedConfigurationBlock_PagesDown);
        fPageOrderDownButton.addSelectionListener(new SelectionAdapter() {
        	public void widgetSelected(SelectionEvent e) {
        		int index= fOwnPageViewer.getTable().getSelectionIndex();
        		if (index != -1) {
        			fModel.movePageDown(index);
        			fOwnPageViewer.refresh();
        			handleOwnPageTableSelection();
        		}
        	}
        });
        fPageOrderDownButton.setLayoutData(new GridData());
        SWTUtil.setButtonDimensionHint(fPageOrderDownButton);
	}

	/**
	 * <p>Update the enablement of the Up and Down buttons for the own page table viewer</p>
	 */
	private void handleOwnPageTableSelection() {
		ModelElement item= (ModelElement) ((IStructuredSelection) fOwnPageViewer.getSelection()).getFirstElement();
		if (item != null) {
			int index= fOwnPageViewer.getTable().getSelectionIndex();
			fPageOrderUpButton.setEnabled(index > 0);
			fPageOrderDownButton.setEnabled(index < fModel.pageElements.size() - 1);
		} else {
			fPageOrderUpButton.setEnabled(false);
			fPageOrderDownButton.setEnabled(false);
		}
	}
	
	/**
	 * <p>Update the enablement of the Up and Down buttons for the default page table viewer</p>
	 */
	private void handleDefaultPageTableSelection() {
		ModelElement item= (ModelElement) ((IStructuredSelection) fDefaultPageViewer.getSelection()).getFirstElement();
		if (item != null) {
			int index = fDefaultPageViewer.getTable().getSelectionIndex();
			fDefaultPageOrderUpButton.setEnabled(index > 0);
			fDefaultPageOrderDownButton.setEnabled(index < fModel.defaultPageElements.size() - 1);
		} else {
			fDefaultPageOrderUpButton.setEnabled(false);
			fDefaultPageOrderDownButton.setEnabled(false);
		}
	}

	private void updateCheckedState() {
		/* does not matter which set of elements we use here
		 * because order does not matter in this case
		 */
		final int size= fModel.pageElements.size();
		List defaultChecked= new ArrayList(size);
		List separateChecked= new ArrayList(size);

		for (Iterator it= fModel.pageElements.iterator(); it.hasNext();) {
			ModelElement element= (ModelElement) it.next();
			if (element.shouldDisplayOnDefaultPage())
				defaultChecked.add(element);
			if (element.shouldDisplayOnOwnPage())
				separateChecked.add(element);
		}

		fDefaultPageViewer.setCheckedElements(defaultChecked.toArray(new Object[defaultChecked.size()]));
		fOwnPageViewer.setCheckedElements(separateChecked.toArray(new Object[separateChecked.size()]));
	}

	private int computeWidth(Control control, String name) {
		if (name == null)
			return 0;
		GC gc= new GC(control);
		try {
			gc.setFont(JFaceResources.getDialogFont());
			return gc.stringExtent(name).x + 10;
		} finally {
			gc.dispose();
		}
	}

	private static BindingManager fgLocalBindingManager;
	static {
		fgLocalBindingManager= new BindingManager(new ContextManager(), new CommandManager());
		final IBindingService bindingService= (IBindingService)PlatformUI.getWorkbench().getService(IBindingService.class);
		final Scheme[] definedSchemes= bindingService.getDefinedSchemes();
		if (definedSchemes != null) {
			try {
				for (int i = 0; i < definedSchemes.length; i++) {
					final Scheme scheme= definedSchemes[i];
					final Scheme copy= fgLocalBindingManager.getScheme(scheme.getId());
					copy.define(scheme.getName(), scheme.getDescription(), scheme.getParentId());
				}
			} catch (final NotDefinedException e) {
				Logger.logException(e);
			}
		}
		fgLocalBindingManager.setLocale(bindingService.getLocale());
		fgLocalBindingManager.setPlatform(bindingService.getPlatform());
	}

	private static String getKeyboardShortcut(ParameterizedCommand command) {
		IBindingService bindingService= (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
		fgLocalBindingManager.setBindings(bindingService.getBindings());
		try {
			Scheme activeScheme= bindingService.getActiveScheme();
			if (activeScheme != null)
				fgLocalBindingManager.setActiveScheme(activeScheme);
		} catch (NotDefinedException e) {
			Logger.logException(e);
		}

		TriggerSequence[] bindings= fgLocalBindingManager.getActiveBindingsDisregardingContextFor(command);
		if (bindings.length > 0)
			return bindings[0].format();
		return null;
	}

	/**
	 * <p>Gets and image based on an image descriptor, and stores the image so it
	 * does not have to be created more then once</p>
	 * 
	 * @param imgDesc {@link ImageDescriptor} to get the {@link Image} for
	 * @return {@link Image} created from the {@link ImageDescriptor}, or stored
	 * {@link Image} associated with the given {@link ImageDescriptor} if an
	 * {@link Image} had already been created for the given {@link ImageDescriptor}
	 */
	private Image getImage(ImageDescriptor imgDesc) {
		if (imgDesc == null)
			return null;

		Image img= (Image) fImages.get(imgDesc);
		if (img == null) {
			img= imgDesc.createImage(false);
			fImages.put(imgDesc, img);
		}
		return img;
	}

	/**
	 * <p>Label provider for the table for configuring which categories should be displayed on the
	 * default assist page</p>
	 */
	private final class DefaultPageTableLabelProvider extends LabelProvider implements ITableLabelProvider {
		/**
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
		 */
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex == 0)
				return ((ModelElement) element).getImage();
			return null;
		}

		/**
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
		 */
		public String getColumnText(Object element, int columnIndex) {
			switch (columnIndex) {
	            case 0:
	            	return ((ModelElement) element).getName();
	            default:
	            	Assert.isTrue(false);
	            	return null;
            }
		}

		/**
		 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
		 */
		public String getText(Object element) {
		    return getColumnText(element, 0); // needed to make the sorter work
		}
	}

	/**
	 * <p>Label provider for the table for configuring which categories should be displayed on their
	 * own content assist page</p>
	 */
	private final class OwnPageTableLabelProvider extends LabelProvider implements ITableLabelProvider {
		/**
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
		 */
		public Image getColumnImage(Object element, int columnIndex) {
			if (columnIndex == 0)
				return ((ModelElement) element).getImage();
			return null;
		}

		/**
		 * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
		 */
		public String getColumnText(Object element, int columnIndex) {
			switch (columnIndex) {
				case 0:
					return ((ModelElement) element).getName();
				default:
					Assert.isTrue(false);
				return null;
			}
		}
	}
	
	/**
	 * <p>PreferenceModel used to read and write the user preferences
	 * using the {@link ICompletionProposalCategoriesConfigurationWriter}</p>
	 */
	private final class PreferenceModel {
		/** private modifiable page element list */
		private final List fPageElements;
		
		/** public unmodifiable page element list */
		final List pageElements;
		
		/** private modifiable default page element list */
		private final List fDefaultPageElements;
		
		/** public unmodifiable default page element list */
		final List defaultPageElements;

		/**
		 * <p>Create the preference model for the given categories</p>
		 * 
		 * @param categories <code>{@link List}<{@link CompletionProposalCategory}></code>
		 */
		public PreferenceModel(List categories) {
			//need separate lists because they will be ordered differently
			this.fPageElements = new ArrayList();
			this.fDefaultPageElements = new ArrayList();
			for (Iterator it= categories.iterator(); it.hasNext();) {
				CompletionProposalCategory category= (CompletionProposalCategory) it.next();
				if (category.hasComputers()) {
					ModelElement elem = new ModelElement(category);
					fPageElements.add(elem);
					fDefaultPageElements.add(elem);
				}
			}
			//sort the lists
			this.performDefaults();
			
			pageElements = Collections.unmodifiableList(fPageElements);
			defaultPageElements = Collections.unmodifiableList(fDefaultPageElements);
		}

		/**
		 * <p>Move the model element specified by the given index
		 * up in the content assist page order</p>
		 * 
		 * @param elementIndex the index of the model element to move up
		 */
        public void movePageUp(int elementIndex) {
        	Object removed = fPageElements.remove(elementIndex);
        	fPageElements.add(elementIndex-1, removed);
        	
        	fConfigurationWriter.setPageOrder(getPageOrderedCategoryIDs());
        }
        
        /**
		 * <p>Move the model element specified by the given index
		 * down in the content assist page order</p>
		 * 
		 * @param elementIndex the index of the model element to move up
		 */
        public void movePageDown(int elementIndex) {
        	Object removed = fPageElements.remove(elementIndex);
        	fPageElements.add(elementIndex+1, removed);
        	
        	fConfigurationWriter.setPageOrder(getPageOrderedCategoryIDs());
        }
        
        /**
		 * <p>Move the model element specified by the given index
		 * up in the content assist page order</p>
		 * 
		 * @param elementIndex the index of the model element to move up
		 */
        public void moveDefaultPageCategoryUp(int elementIndex) {
        	Object removed = fDefaultPageElements.remove(elementIndex);
        	fDefaultPageElements.add(elementIndex-1, removed);
        	
        	fConfigurationWriter.setDefaultPageOrder(getDefaultPageOrderedCategoryIDs());
        }
        
        /**
		 * <p>Move the model element specified by the given index
		 * down in the content assist page order</p>
		 * 
		 * @param elementIndex the index of the model element to move up
		 */
        public void moveDefaultPageCategoryDown(int elementIndex) {
        	Object removed = fDefaultPageElements.remove(elementIndex);
        	fDefaultPageElements.add(elementIndex+1, removed);
        	
        	fConfigurationWriter.setDefaultPageOrder(getDefaultPageOrderedCategoryIDs());
        }
        
        /**
         * @return <code>{@link List}<{@link String}></code> -
         * List of category IDs by page order
         */
        private List getPageOrderedCategoryIDs() {
        	List ordered = new ArrayList(pageElements.size());
        	for(int i = 0; i < pageElements.size(); ++i) {
        		ordered.add(((ModelElement)pageElements.get(i)).getId());
        	}
        	
        	return ordered;
        }
        
        /**
         * @return <code>{@link List}<{@link String}></code> -
         * List of category IDs by default page order
         */
        private List getDefaultPageOrderedCategoryIDs() {
        	List ordered = new ArrayList(defaultPageElements.size());
        	for(int i = 0; i < defaultPageElements.size(); ++i) {
        		ordered.add(((ModelElement)defaultPageElements.get(i)).getId());
        	}
        	
        	return ordered;
        }
        
        /**
         * <p>need to re-sort the lists after performing defaults</p>
         */
        public void performDefaults() {
        	Collections.sort(fPageElements, fCategoryPageComparator);
			Collections.sort(fDefaultPageElements, fCategoryDefaultPageComparator);
        }
	}
	
	/**
	 * <p>Wraps a {@link CompletionProposalCategory} for use in the {@link PreferenceModel}</p>
	 */
	private final class ModelElement {
		/** The wrapped category */
		private final CompletionProposalCategory fCategory;

		/**
		 * <p>Create a new model element wrapping the given category</p>
		 * 
		 * @param category {@link CompletionProposalCategory} to be wrapped by this model element
		 * for use in the {@link PreferenceModel}
		 */
		ModelElement(CompletionProposalCategory category) {
			fCategory= category;
		}
		
		/**
		 * @return {@link Image} associated with the wrapped category
		 */
		Image getImage() {
			return CodeAssistCyclingConfigurationBlock.this.getImage(fCategory.getImageDescriptor());
		}
		
		/**
		 * @return name of the wrapped category
		 */
		String getName() {
			return fCategory.getDisplayName();
		}
		
		String getId() {
			return fCategory.getId();
		}
		
		/**
		 * @return <code>true</code> if the wrapped category should be displayed on the
		 * default content assist page, <code>false</code> otherwise
		 */
		boolean shouldDisplayOnDefaultPage() {
			return fConfigurationWriter.shouldDisplayOnDefaultPage(this.getId());
		}
		
		/**
		 * @param included <code>true</code> if the wrapped category should be displayed on the
		 * default content assist page, <code>false</code> otherwise
		 */
		void setShouldDisplayOnDefaultPage(boolean included) {
			fConfigurationWriter.setShouldDisplayOnDefaultPage(this.getId(), included);
		}
		
		/**
		 * @return <code>true</code> if the wrapped category should be displayed on the
		 * its own content assist page, <code>false</code> otherwise
		 */
		boolean shouldDisplayOnOwnPage() {
			return fConfigurationWriter.shouldDisplayOnOwnPage(this.getId());
		}
		
		/**
		 * @param shouldDisplay <code>true</code> if the wrapped category should be displayed on the
		 * its own content assist page, <code>false</code> otherwise
		 */
		void setShouldDisplayOnOwnPage(boolean shouldDisplay) {
			fConfigurationWriter.setShouldDisplayOnOwnPage(this.getId(), shouldDisplay);
		}
		
		/**
		 * @return the wrapped categories content assist page sort rank compared to the
		 * other categories
		 */
		int getOwnPageRank() {
			return fConfigurationWriter.getPageSortOrder(this.getId());
		}
		
		/**
		 * @return the wrapped categories content assist page sort rank compared to the
		 * other categories
		 */
		int getDefaultPageRank() {
			return fConfigurationWriter.getDefaultPageSortOrder(this.getId());
		}
	}
	
	private class ModelViewerComparator extends ViewerComparator {
		/**
		 * 
		 */
		public ModelViewerComparator(Comparator comparator) {
			super(comparator);
		}
		
		/**
		 * @see org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
		 */
		public int compare(Viewer viewer, Object e1, Object e2) {
			return this.getComparator().compare(e1, e2);
		}
	}
}
