/*
 * Copyright (c) 2005 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *   IBM - Initial API and implementation
 *   Jens Lukowski/Innoopract - initial renaming/restructuring
 * 
 */
package org.eclipse.wst.xsd.ui.internal;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IContentProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.wst.sse.ui.internal.contentoutline.PropertyChangeUpdateAction;
import org.eclipse.wst.sse.ui.internal.contentoutline.PropertyChangeUpdateActionContributionItem;
import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xsd.ui.internal.actions.OpenSchemaAction;
import org.eclipse.wst.xsd.ui.internal.provider.CategoryAdapter;
import org.eclipse.wst.xsd.ui.internal.provider.XSDAdapterFactoryLabelProvider;
import org.eclipse.wst.xsd.ui.internal.provider.XSDContentProvider;
import org.eclipse.wst.xsd.ui.internal.provider.XSDModelAdapterFactoryImpl;
import org.eclipse.wst.xsd.ui.internal.text.XSDModelAdapter;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.XSDSchemaDirective;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Outline configuration for XSD
 */
public class XSDContentOutlineConfiguration extends ContentOutlineConfiguration {
	private XSDContentProvider fContentProvider;
	private ILabelProvider fLabelProvider;
	private KeyListener[] fKeyListeners = null;
	private IMenuListener fMenuListener = null;
	private XSDEditor fEditor = null;
	private TreeViewer treeViewer;
	protected SelectionManagerSelectionChangeListener selectionManagerSelectionChangeListener = new SelectionManagerSelectionChangeListener();
	
	public XSDContentOutlineConfiguration()
	{
		super();
	}

	public IContentProvider getContentProvider(TreeViewer viewer) {
		if (fContentProvider == null) {
			fContentProvider = new XSDContentProvider(XSDModelAdapterFactoryImpl.getInstance());
		}
		this.treeViewer = viewer;
		getXSDEditor().getSelectionManager().addSelectionChangedListener(selectionManagerSelectionChangeListener);
		return fContentProvider;
	}

	public ILabelProvider getLabelProvider(TreeViewer viewer) {
		if (fLabelProvider == null) {
			fLabelProvider = new XSDAdapterFactoryLabelProvider(XSDModelAdapterFactoryImpl.getInstance());
		}
		return fLabelProvider;
	}

	public IMenuListener getMenuListener(TreeViewer viewer) {
		if (fMenuListener == null) {
			// ISSUE: what happens if cannot get XSD Editor? (See
			// getXSDEditor comment)
			if (getXSDEditor() != null)
				fMenuListener = new XSDMenuListener(getXSDEditor().getSelectionManager());
		}
		return fMenuListener;
	}

	public KeyListener[] getKeyListeners(TreeViewer viewer) {
		if (fKeyListeners == null) {
			final TreeViewer finalViewer = viewer;
			KeyAdapter keyListener = new KeyAdapter() {
				public void keyReleased(KeyEvent e) {
					if (e.character == SWT.DEL) {
						IMenuListener menuListener = getMenuListener(finalViewer);
						if (menuListener instanceof XSDMenuListener)
							((XSDMenuListener) menuListener).getDeleteAction().run();
					}
					else if (e.keyCode == SWT.F3) // open editor on any
					// include/import/redefine
					{
						if (e.widget instanceof Tree) {
							Tree tree = (Tree) e.widget;
							TreeItem[] selection = tree.getSelection();
							if (selection.length > 0) {
								if (selection[0].getData() instanceof XSDSchemaDirective) {
									XSDSchemaDirective comp = (XSDSchemaDirective) selection[0].getData();
									OpenSchemaAction openSchema = new OpenSchemaAction(XSDEditorPlugin.getXSDString("_UI_ACTION_OPEN_SCHEMA"), comp);
									openSchema.run();
								}
							}
						}
					}
				}
			};
			fKeyListeners = new KeyListener[]{keyListener};
		}

		return fKeyListeners;
	}

	public ISelection getSelection(TreeViewer viewer, ISelection selection) {
		ISelection sel = selection;

		if (selection instanceof IStructuredSelection) {
			List xsdSelections = new ArrayList();
			for (Iterator i = ((IStructuredSelection) selection).iterator(); i.hasNext();) {
				Object domNode = i.next();
				Object xsdNode = getXSDNode(domNode, viewer);
				if (xsdNode != null) {
					xsdSelections.add(xsdNode);
				}
			}

			if (!xsdSelections.isEmpty()) {
				sel = new StructuredSelection(xsdSelections);
			}
		}
		return sel;
	}

	/**
	 * Determines XSD node based on object (DOM node)
	 * 
	 * @param object
	 * @return
	 */
	private Object getXSDNode(Object object, TreeViewer viewer) {
		// get the element node
		Element element = null;
		if (object instanceof Node) {
			Node node = (Node) object;
			if (node != null) {
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					element = (Element) node;
				}
				else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
					element = ((Attr) node).getOwnerElement();
				}
			}
		}
		Object o = element;
		if (element != null) {
			Object modelObject = getXSDSchema(viewer).getCorrespondingComponent(element);
			if (modelObject != null) {
				o = modelObject;
			}
		}
		return o;
	}

	/**
	 * Gets the xsd schema from treeviewer's input
	 * 
	 * @param model
	 *            (of type Object but really should be IStructuredModel)
	 * @return Definition
	 */
	private XSDSchema getXSDSchema(TreeViewer viewer) {
		XSDSchema xsdSchema = null;
		Object model = null;
		if (viewer != null)
			model = viewer.getInput();

		if (model instanceof IDOMModel) {
			IDOMDocument domDoc = ((IDOMModel) model).getDocument();
			if (domDoc != null) {
				XSDModelAdapter modelAdapter = (XSDModelAdapter) domDoc.getExistingAdapter(XSDModelAdapter.class);
				/*
				 * ISSUE: Didn't want to go through initializing schema if it
				 * does not already exist, so just attempted to get existing
				 * adapter. If doesn't exist, just don't bother working.
				 */
				if (modelAdapter != null)
					xsdSchema = modelAdapter.getSchema();
			}
		}
		return xsdSchema;
	}

	// ISSUE: There are some cases where outline comes up before editor
	private XSDEditor getXSDEditor() {
		if (fEditor == null) {
			IWorkbench workbench = PlatformUI.getWorkbench();
			if (workbench != null) {
				IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
				if (window != null) {
					IWorkbenchPage page = window.getActivePage();
					if (page != null) {
						IEditorPart editor = page.getActiveEditor();
						if (editor instanceof XSDEditor)
							fEditor = (XSDEditor) editor;
					}
				}
			}
		}
		return fEditor;
	}

	protected IContributionItem[] createMenuContributions(TreeViewer viewer) {
       IContributionItem[] items = super.createMenuContributions(viewer);
		
	   referenceAction = new FilterAction(XSDEditorPlugin.getPlugin().getPreferenceStore(), "referenceContentAction", new ReferenceFilter("Reference Content"), XSDEditorPlugin.getXSDString("_UI_OUTLINE_SHOW_REFERENCES"), ImageDescriptor.createFromFile(XSDEditorPlugin.getPlugin().getClass(), "icons/XSDElementRef.gif"));
       boolean initialRef = getXSDEditor().getXSDModelAdapterFactory().getShowReferences();
       referenceAction.setChecked(initialRef);

       inheritedAction = new FilterAction(XSDEditorPlugin.getPlugin().getPreferenceStore(), "inheritedContentAction", new ReferenceFilter("Inherited Content"), XSDEditorPlugin.getXSDString("_UI_OUTLINE_SHOW_INHERITED"), ImageDescriptor.createFromFile(XSDEditorPlugin.getPlugin().getClass(), "icons/XSDComplexContent.gif"));
		
	   IContributionItem toggleReferenceItem = new PropertyChangeUpdateActionContributionItem(referenceAction);
	   IContributionItem toggleInheritedItem = new PropertyChangeUpdateActionContributionItem(inheritedAction);
	    
	   List list = new ArrayList();
	   list.addAll(Arrays.asList(items));
	   list.add(toggleReferenceItem);
	   list.add(toggleInheritedItem);
	   
	   int length = list.size();
	   IContributionItem[] newItems = new IContributionItem[length];
	   int i = 0;
	   for (Iterator iter = list.iterator(); iter.hasNext(); i++)
	   {
	     newItems[i] = (IContributionItem)iter.next();
	   }
	   
	   return newItems;
	}
	
	  // expose
	  public TreeViewer getTreeViewer()
	  {
	    return treeViewer;
	  }

	  FilterAction referenceAction, inheritedAction;
	  
	  private void updateActions(Action current)
	  {
	    if (referenceAction.isChecked())
	    {
	      getXSDEditor().getXSDModelAdapterFactory().setShowReferences(true);
	    }
	    else
	    {
	      getXSDEditor().getXSDModelAdapterFactory().setShowReferences(false);
	    }
	    if (inheritedAction.isChecked())
	    {
	      getXSDEditor().getXSDModelAdapterFactory().setShowInherited(true);
	    }
	    else
	    {
	      getXSDEditor().getXSDModelAdapterFactory().setShowInherited(false);
	    }
	    getTreeViewer().refresh();
	  }

	  public class FilterAction extends PropertyChangeUpdateAction
	  {
	    ViewerFilter filter;

	    public FilterAction(IPreferenceStore store, String preference, ViewerFilter filter, String label, ImageDescriptor image)
	    {
	      super(label, store, preference, true);
	      setImageDescriptor(image);
	      setUpdateFromPropertyChange(false);
	      this.filter = filter;
	      setChecked(false);
	    }

	    public void update()
	    {
	      super.update();
	      updateActions(this);
	    }
	  }
	  
	  class ReferenceFilter extends ViewerFilter // Dummy filter
	  {
	    public ReferenceFilter(String elementTag)
	    {
	      this.elementTag = elementTag;
	    }
	    protected String elementTag;

	    public boolean select(Viewer viewer, Object parentElement, Object element)
	    {
	      return true;
	    }
	  }
	
	  class SelectionManagerSelectionChangeListener implements ISelectionChangedListener
	  {
	    public void selectionChanged(SelectionChangedEvent event)
	    {
	      if (event.getSelectionProvider() != getTreeViewer())
	      {
	    	StructuredSelection selection = (StructuredSelection)event.getSelection();
	    	if (selection.getFirstElement() instanceof XSDSchema)
	    	{
	    	   StructuredSelection s = (StructuredSelection)getTreeViewer().getSelection();
	    	   if (!(s.getFirstElement() instanceof CategoryAdapter))
	    	   {
	    		 getTreeViewer().setSelection(event.getSelection(), true);
	    	   }
	    	}
	    	else
	    	{
	          getTreeViewer().setSelection(event.getSelection(), true);
	    	}
	      }
	    }
	  }

	  public void unconfigure(TreeViewer viewer) {
		  super.unconfigure(viewer);
		  System.out.println("UNCONFIGURE OUTLINE");
		  getXSDEditor().getSelectionManager().removeSelectionChangedListener(selectionManagerSelectionChangeListener);
	  }
}
