/*****************************************************************************
 * Copyright (c) 2004 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.xml.ui.internal.tabletree;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.wst.common.contentmodel.CMDocument;
import org.eclipse.wst.common.contentmodel.modelquery.CMDocumentManager;
import org.eclipse.wst.common.contentmodel.modelquery.CMDocumentManagerListener;
import org.eclipse.wst.common.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.common.contentmodel.util.CMDocumentCache;
import org.eclipse.wst.sse.core.AbstractAdapterFactory;
import org.eclipse.wst.sse.core.INodeAdapter;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.xml.core.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.util.SharedXMLEditorPluginImageHelper;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;


public class XMLTableTreeContentProvider implements ITreeContentProvider, ITableLabelProvider, ILabelProvider, CMDocumentManagerListener {

	protected ViewerNotifyingAdapterFactory viewerNotifyingAdapterFactory = new ViewerNotifyingAdapterFactory();
	protected XMLTableTreePropertyDescriptorFactory propertyDescriptorFactory;
	//	protected ImageFactory imageFactory =
	// XMLCommonUIPlugin.getInstance().getImageFactory();
	protected List viewerList = new Vector();
	protected TreeContentHelper treeContentHelper = new TreeContentHelper();

	protected CMDocumentManager documentManager;

	public XMLTableTreeContentProvider() {
	}

	public void getDecendantList(Object element, List list) {
		Object[] children = getChildren(element);
		if (children != null) {
			for (int i = 0; i < children.length; i++) {
				Object child = children[i];
				list.add(child);
				getDecendantList(child, list);
			}
		}
	}

	public void addViewer(Viewer viewer) {
		viewerList.add(viewer);
	}

	public Object[] getChildren(Object element) {
		viewerNotifyingAdapterFactory.doAdapt(element);
		return treeContentHelper.getChildren(element);
	}

	public Object getParent(Object o) {
		Object result = null;
		if (o instanceof Node) {
			Node node = (Node) o;
			if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
				result = ((Attr) node).getOwnerElement();
			} else {
				result = node.getParentNode();
			}
		}
		return result;
	}

	public boolean hasChildren(Object element) {
		viewerNotifyingAdapterFactory.doAdapt(element);
		return getChildren(element).length > 0;
	}

	public Object[] getElements(Object element) {
		viewerNotifyingAdapterFactory.doAdapt(element);
		return getChildren(element);
	}

	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		// remove our listeners to the old state
		if (oldInput != null) {
			propertyDescriptorFactory = null;
			Document domDoc = (Document) oldInput;
			ModelQuery mq = ModelQueryUtil.getModelQuery(domDoc);
			if (mq != null) {
				documentManager = mq.getCMDocumentManager();
				if (documentManager != null) {
					documentManager.removeListener(this);
				}
			}
		}

		if (newInput != null) {
			Document domDoc = (Document) newInput;
			ModelQuery mq = ModelQueryUtil.getModelQuery(domDoc);

			if (mq != null) {
				propertyDescriptorFactory = new XMLTableTreePropertyDescriptorFactory(mq);
				documentManager = mq.getCMDocumentManager();
				if (documentManager != null) {
					documentManager.setPropertyEnabled(CMDocumentManager.PROPERTY_ASYNC_LOAD, true);
					documentManager.addListener(this);
				}
			}
		}
	}

	public boolean isDeleted(Object element) {
		return element != null;
	}

	//
	// ILabelProvider stuff
	//
	public void addListener(ILabelProviderListener listener) {
	}

	public void dispose() {
		viewerList = new Vector();
	}

	public Element getRootElement(Document document) {
		Element rootElement = null;

		for (Node childNode = document.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) {
			if (childNode.getNodeType() == Node.ELEMENT_NODE) {
				rootElement = (Element) childNode;
				break;
			}
		}
		return rootElement;
	}

	public Image getImage(Object object) {
		viewerNotifyingAdapterFactory.doAdapt(object);
		Image image = null;
		if (object instanceof Node) {
			Node node = (Node) object;
			switch (node.getNodeType()) {
				case Node.ATTRIBUTE_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_ATTRIBUTE);
					break;
				}
				case Node.CDATA_SECTION_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_CDATASECTION);
					break;
				}
				case Node.COMMENT_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_COMMENT);
					break;
				}
				case Node.DOCUMENT_TYPE_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_DOCTYPE);
					break;
				}
				case Node.ELEMENT_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_ELEMENT);
					break;
				}
				case Node.PROCESSING_INSTRUCTION_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_PROCESSINGINSTRUCTION);
					break;
				}
				case Node.TEXT_NODE : {
					image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_TXTEXT);
					break;
				}
				case Node.ENTITY_REFERENCE_NODE : {
					image = image = SharedXMLEditorPluginImageHelper.getImage(SharedXMLEditorPluginImageHelper.IMG_OBJ_ENTITY_REFERENCE);
					break;
				}
			}

			//			if (image != null) {
			//				Image markerOverlayImage =
			// overlayIconManager.getOverlayImageForObject(node);
			//				if (markerOverlayImage != null) {
			//					image = imageFactory.createCompositeImage(image,
			// markerOverlayImage, ImageFactory.BOTTOM_LEFT);
			//				}
			//			}
		}
		return image;
	}

	public String getText(Object object) {
		viewerNotifyingAdapterFactory.doAdapt(object);
		String result = null;
		if (object instanceof Node) {
			Node node = (Node) object;
			switch (node.getNodeType()) {
				case Node.ATTRIBUTE_NODE : {
					result = node.getNodeName();
					break;
				}
				case Node.DOCUMENT_TYPE_NODE : {
					result = "DOCTYPE"; //$NON-NLS-1$
					break;
				}
				case Node.ELEMENT_NODE : {
					result = node.getNodeName();
					break;
				}
				case Node.PROCESSING_INSTRUCTION_NODE : {
					result = ((ProcessingInstruction) node).getTarget();
					break;
				}
			}
		}
		return result != null ? result : ""; //$NON-NLS-1$
	}

	//
	// ITableLabelProvider stuff
	//
	public String getColumnText(Object object, int column) {
		viewerNotifyingAdapterFactory.doAdapt(object);
		String result = null;
		if (column == 0) {
			result = getText(object);
		} else if (column == 1 && object instanceof Node) {
			result = treeContentHelper.getNodeValue((Node) object);
		}
		return result != null ? result : ""; //$NON-NLS-1$
	}

	public Image getColumnImage(Object object, int columnIndex) {
		viewerNotifyingAdapterFactory.doAdapt(object);
		return (columnIndex == 0) ? getImage(object) : null;
	}

	public boolean isLabelProperty(Object object, String property) {
		return false;
	}

	public void removeListener(ILabelProviderListener listener) {
	}

	// There is only 1 adapter associated with this factory. This single
	// adapter gets added
	// to the adapter lists of many nodes.
	public class ViewerNotifyingAdapterFactory extends AbstractAdapterFactory {
		protected ViewerNotifyingAdapter viewerNotifyingAdapter = new ViewerNotifyingAdapter();

		protected INodeAdapter createAdapter(INodeNotifier target) {
			return viewerNotifyingAdapter;
		}

		protected ViewerNotifyingAdapter doAdapt(Object object) {
			ViewerNotifyingAdapter result = null;
			if (object instanceof INodeNotifier) {
				result = (ViewerNotifyingAdapter) adapt((INodeNotifier) object);
			}
			return result;
		}
	}

	public class ViewerNotifyingAdapter implements INodeAdapter {
		public boolean isAdapterForType(Object type) {
			return type.equals(viewerNotifyingAdapterFactory);
		}

		public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
			switch (eventType) {
				//case INodeNotifier.ADD: // ignore
				//case INodeNotifier.REMOVE: // ignore
				case INodeNotifier.CHANGE :
				case INodeNotifier.STRUCTURE_CHANGED :
				case INodeNotifier.CONTENT_CHANGED : {
					Node node = (Node) notifier;
					if (node.getNodeType() == Node.ELEMENT_NODE || node.getNodeType() == Node.DOCUMENT_NODE) {
						for (Iterator i = viewerList.iterator(); i.hasNext();) {
							Viewer viewer = (Viewer) i.next();

							if (viewer instanceof StructuredViewer) {
								((StructuredViewer) viewer).refresh(node);
							} else {
								// todo... consider doing a time delayed
								// refresh here!!
								viewer.refresh();
							}
						}
					}
					break;
				}
			}
		}
	}

	// the following methods handle filtering aspects of the viewer
	//
	//
	public boolean isIgnorableText(Node node) {
		boolean result = false;
		try {
			if (node.getNodeType() == Node.TEXT_NODE) {
				String data = ((Text) node).getData();
				result = (data == null || data.trim().length() == 0);
			}
		} catch (Exception e) {
			Logger.logException(e);
		}
		return result;
	}

	public static Text getHiddenChildTextNode(Node node) {
		return null;
	}

	// CMDocumentManagerListener
	//
	public void cacheCleared(CMDocumentCache cache) {
		doDelayedRefreshForViewers();
	}

	public void cacheUpdated(CMDocumentCache cache, final String uri, int oldStatus, int newStatus, CMDocument cmDocument) {
		if (newStatus == CMDocumentCache.STATUS_LOADED || newStatus == CMDocumentCache.STATUS_ERROR) {
			doDelayedRefreshForViewers();
		}
	}

	public void propertyChanged(CMDocumentManager cmDocumentManager, String propertyName) {
		if (cmDocumentManager.getPropertyEnabled(CMDocumentManager.PROPERTY_AUTO_LOAD)) {
			doDelayedRefreshForViewers();
		}
	}

	protected void doDelayedRefreshForViewers() {
		List list = new Vector();
		list.addAll(viewerList);

		for (Iterator i = list.iterator(); i.hasNext();) {
			final Viewer viewer = (Viewer) i.next();
			Control control = viewer.getControl();
			Runnable runnable = new Runnable() {
				public void run() {
					viewer.refresh();
				}
			};
			// we need to ensure that this is run via 'asyncExec' since these
			// notifications can come from a non-ui thread
			control.getDisplay().asyncExec(runnable);
		}
	}
}