/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.views.properties;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.IPropertySource;
import org.eclipse.ui.views.properties.IPropertySourceProvider;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManager;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.CMDocumentManagerListener;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.eclipse.wst.xml.ui.internal.properties.XMLPropertySource;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Configuration for property sheet page which shows XML content.
 * 
 * @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration
 * @since 1.0
 */
public class XMLPropertySheetConfiguration extends PropertySheetConfiguration {
	private class CMDocumentManagerListenerImpl implements CMDocumentManagerListener {
		public void cacheCleared(CMDocumentCache cache) {
			// nothing to do
		}

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

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

		private void refreshPages() {
			getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
			getPropertiesRefreshJob().schedule(PropertiesRefreshJob.UPDATE_DELAY);
		}
	}

	private class PropertiesRefreshJob extends UIJob {
		public static final int UPDATE_DELAY = 200;

		private Set propertySheetPages = null;

		public PropertiesRefreshJob() {
			super(XMLUIMessages.JFaceNodeAdapter_1);
			setSystem(true);
			setPriority(Job.SHORT);
			propertySheetPages = new HashSet(1);
		}

		void addPropertySheetPage(IPropertySheetPage page) {
			propertySheetPages.add(page);
			schedule(UPDATE_DELAY);
		}

		public IStatus runInUIThread(IProgressMonitor monitor) {
			Object[] pages = propertySheetPages.toArray();
			propertySheetPages.clear();

			for (int i = 0; i < pages.length; i++) {
				PropertySheetPage page = (PropertySheetPage) pages[i];
				if (page.getControl() != null && !page.getControl().isDisposed()) {
					page.refresh();
				}
			}

			return Status.OK_STATUS;
		}
	}

	private class XMLPropertySheetRefreshAdapter implements INodeAdapter {
		public boolean isAdapterForType(Object type) {
			return false;
		}

		public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
			if (fPropertySheetPage != null) {
				getPropertiesRefreshJob().addPropertySheetPage(fPropertySheetPage);
			}
		}
	}

	private class XMLPropertySourceProvider implements IPropertySourceProvider {
		private IPropertySource fPropertySource = null;
		private INodeNotifier fSource = null;

		public IPropertySource getPropertySource(Object object) {
			if (fSource != null && object.equals(fSource)) {
				return fPropertySource;
			}

			if (object instanceof IDOMNode) {
				fSource = (INodeNotifier) object;
				fPropertySource = (IPropertySource) fSource.getAdapterFor(IPropertySource.class);
				if (fPropertySource == null) {
					fPropertySource = new XMLPropertySource((INodeNotifier) object);
				}
			}
			else {
				fSource = null;
				fPropertySource = null;
			}
			return fPropertySource;
		}
	}

	private CMDocumentManagerListenerImpl fCMDocumentManagerListener = new CMDocumentManagerListenerImpl();
	private PropertiesRefreshJob fPropertiesRefreshJob = null;
	IPropertySheetPage fPropertySheetPage = null;
	private IPropertySourceProvider fPropertySourceProvider = null;
	private INodeAdapter fRefreshAdapter = new XMLPropertySheetRefreshAdapter();
	private CMDocumentManager[] fSelectedCMDocumentManagers = new CMDocumentManager[0];
	private INodeNotifier[] fSelectedNotifiers = new INodeNotifier[0];


	/**
	 * Create new instance of XMLPropertySheetConfiguration
	 */
	public XMLPropertySheetConfiguration() {
		// Must have empty constructor to createExecutableExtension
		super();
	}

	public ISelection getInputSelection(IWorkbenchPart selectingPart, ISelection selection) {
		if (fSelectedNotifiers != null) {
			for (int i = 0; i < fSelectedNotifiers.length; i++) {
				fSelectedNotifiers[i].removeAdapter(fRefreshAdapter);
			}
			fSelectedNotifiers = null;
		}
		for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
			fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
		}

		ISelection preferredSelection = selection;
		if (selection instanceof IStructuredSelection) {
			IStructuredSelection structuredSel = (IStructuredSelection) selection;

			/*
			 * On Attr nodes, select the owner Element. On Text nodes, select
			 * the parent Element.
			 */
			Object[] selectedObjects = new Object[structuredSel.size()];
			System.arraycopy(structuredSel.toArray(), 0, selectedObjects, 0, selectedObjects.length);
			for (int i = 0; i < selectedObjects.length; i++) {
				Object inode = selectedObjects[i];
				if (inode instanceof Node) {
					Node node = (Node) inode;
					// replace Attribute Node with its owner
					Node parentNode = node.getParentNode();
					if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
						Element ownerElement = ((Attr) node).getOwnerElement();
						selectedObjects[i] = ownerElement;
					}
					// replace Text Node with its parent
					else if ((node.getNodeType() == Node.TEXT_NODE || (node.getNodeType() == Node.CDATA_SECTION_NODE)) && parentNode != null) {
						selectedObjects[i] = parentNode;
					}
				}
			}

			if (selectedObjects.length > 0) {
				Set managers = new HashSet(1);
				Set selectedNotifiers = new HashSet(1);

				for (int i = 0; i < selectedObjects.length; i++) {
					if (selectedObjects[i] instanceof Node) {
						ModelQuery query = ModelQueryUtil.getModelQuery(((Node) selectedObjects[i]).getOwnerDocument());
						if (query != null) {
							CMDocumentManager mgr = query.getCMDocumentManager();
							if (mgr != null) {
								managers.add(mgr);
								mgr.addListener(fCMDocumentManagerListener);
							}
						}
					}
					/*
					 * Add UI refresh adapters and remember notifiers for
					 * later removal
					 */
					if (selectedObjects[i] instanceof INodeNotifier) {
						selectedNotifiers.add(selectedObjects[i]);
						((INodeNotifier) selectedObjects[i]).addAdapter(fRefreshAdapter);
					}
				}
				fSelectedCMDocumentManagers = (CMDocumentManager[]) managers.toArray(new CMDocumentManager[managers.size()]);
				fSelectedNotifiers = (INodeNotifier[]) selectedNotifiers.toArray(new INodeNotifier[selectedNotifiers.size()]);
			}


			preferredSelection = new StructuredSelection(selectedObjects);
		}
		return preferredSelection;
	}

	PropertiesRefreshJob getPropertiesRefreshJob() {
		if (fPropertiesRefreshJob == null) {
			fPropertiesRefreshJob = new PropertiesRefreshJob();
		}
		return fPropertiesRefreshJob;
	}

	public IPropertySourceProvider getPropertySourceProvider(IPropertySheetPage page) {
		if (fPropertySourceProvider == null) {
			fPropertySheetPage = page;
			fPropertySourceProvider = new XMLPropertySourceProvider();
		}
		return fPropertySourceProvider;
	}


	public void unconfigure() {
		super.unconfigure();
		for (int i = 0; i < fSelectedCMDocumentManagers.length; i++) {
			fSelectedCMDocumentManagers[i].removeListener(fCMDocumentManagerListener);
		}
		fPropertySheetPage = null;
	}
}
