/*******************************************************************************
 * 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.html.core.htmlcss;



import org.eclipse.wst.css.core.adapters.IModelProvideAdapter;
import org.eclipse.wst.css.core.adapters.IStyleSheetListAdapter;
import org.eclipse.wst.css.core.document.ICSSModel;
import org.eclipse.wst.html.core.HTML40Namespace;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.sse.core.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.events.NoChangeEvent;
import org.eclipse.wst.sse.core.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegionList;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 */
public class StyleElementAdapter extends AbstractStyleSheetAdapter implements IStructuredDocumentListener {

	private boolean replaceModel = true;
	private boolean ignoreNotification = false;

	/**
	 */
	protected StyleElementAdapter() {
		super();
	}

	/**
	 * Preparation of applying changes from CSS sub-model to HTML model
	 */
	private void changeStructuredDocumentRegion(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return;
		Element element = getElement();
		if (element == null)
			return;
		ICSSModel model = getExistingModel();
		if (model == null)
			return;
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		if (structuredDocument == null)
			return;

		// get old content length
		Node child = element.getFirstChild();
		if (child == null || child.getNodeType() != Node.TEXT_NODE)
			return;
		XMLNode content = (XMLNode) child;
		int oldLength = content.getEndOffset() - content.getStartOffset();

		// get new content length
		int newLength = 0;
		IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList();
		if (flatNodes != null) {
			int count = flatNodes.getLength();
			if (count > 0) {
				IStructuredDocumentRegion last = flatNodes.item(count - 1);
				if (last != null)
					newLength = last.getEnd();
			}
		}

		int offset = flatNode.getStart();
		int end = flatNode.getEnd();
		int diff = oldLength - newLength;
		int length = end - offset + diff;
		String data = flatNode.getText();

		replaceData(offset, length, data);
	}

	/**
	 * Apply changes from HTML model to CSS sub-model
	 */
	private void contentChanged() {
		Element element = getElement();
		if (element == null)
			return;
		ICSSModel model = getExistingModel();
		if (model == null)
			return;
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		if (structuredDocument == null)
			return;

		String data = null;
		Node child = element.getFirstChild();
		if (child != null && child.getNodeType() == Node.TEXT_NODE && child.getNextSibling() == null) {
			data = child.getNodeValue();
		}
		if (data == null)
			data = "";//$NON-NLS-1$

		// minimize replace range
		int start = 0, end = 0;
		String oldData = structuredDocument.get();
		if (oldData == null)
			oldData = "";//$NON-NLS-1$

		// search differenct character position from first
		for (; start < oldData.length() && start < data.length(); start++)
			if (oldData.charAt(start) != data.charAt(start))
				break;

		if (start == oldData.length() && start == data.length())
			return; // no change
		else if (start == oldData.length()) {
			structuredDocument.replaceText(getRequesterH2C(), start, 0, data.substring(start)); // append text to last
		}
		else if (start == data.length()) {
			structuredDocument.replaceText(getRequesterH2C(), start, oldData.length() - start, ""); // remove text of last //$NON-NLS-1$
		}
		else {
			// search differenct character position from last
			for (; start < oldData.length() - end && start < data.length() - end; end++) {
				if (oldData.charAt(oldData.length() - end - 1) != data.charAt(data.length() - end - 1))
					break;
			}
			structuredDocument.replaceText(getRequesterH2C(), start, oldData.length() - end - start, data.substring(start, data.length() - end));
		}

	}

	/**
	 */
	public ICSSModel getModel() {
		ICSSModel model = getExistingModel();
		if (this.replaceModel) {
			ICSSModel oldModel = model;
			model = createModel();

			setModel(model); // need to set before contentChanged()
			contentChanged();

			if (oldModel != null) {
				// get ModelProvideAdapter
				IModelProvideAdapter adapter = (IModelProvideAdapter) ((INodeNotifier) getElement()).getAdapterFor(IModelProvideAdapter.class);
				if (adapter != null) {
					adapter.modelRemoved(oldModel);
				}
			}

			this.replaceModel = false;
		}
		return model;
	}

	/**
	 */
	protected boolean isValidAttribute() {
		Element element = getElement();
		if (element == null) {
			return false;
		}
		String type = element.getAttribute(HTML40Namespace.ATTR_NAME_TYPE);
		if (type != null && type.length() > 0 &&!type.equalsIgnoreCase("text/css")) { //$NON-NLS-1$
			return false;
		}
		return true;
	}

	/**
	 */
	protected ICSSModel createModel() {
		if (!isValidAttribute()) {
			return null;
		}

		ICSSModel model = super.createModel();
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		if (structuredDocument == null)
			return null;
		structuredDocument.addDocumentChangedListener(this);

		return model;
	}

	/**
	 */
	//  public ICSSModel getModel() {
	//  	ICSSModel model = getExistingModel();
	//  	if (model == null) {
	//  		model = createModel();
	//  		if (model == null) return null;
	//  		IStructuredDocument structuredDocument = model.getStructuredDocument();
	//  		if (structuredDocument == null) return null;
	//  		structuredDocument.addModelChangedListener(this);
	//  		setModel(model); // need to set before contentChanged()
	//  		contentChanged();
	//  	}
	//  	return model;
	//  }
	/**
	 */
	private Object getRequesterH2C() {
		return (getElement() != null && ((XMLNode) getElement()).getModel() != null) ? (Object) ((XMLNode) getElement()).getModel() : this;
	}

	/**
	 */
	private Object getRequesterC2H() {
		return (getModel() != null) ? (Object) getModel() : this;
	}

	/**
	 * Implementing IStructuredDocumentListener's method
	 * Event from CSS Flat Model
	 */
	public void newModel(NewDocumentEvent event) {
		if (event == null)
			return;
		if (event.getOriginalSource() == getRequesterH2C())
			return;
		IStructuredDocument structuredDocument = event.getStructuredDocument();
		if (structuredDocument == null)
			return;
		IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList();
		if (flatNodes == null)
			return;

		replaceStructuredDocumentRegions(flatNodes, null);
	}

	/**
	 * Implementing IStructuredDocumentListener's method
	 * Event from CSS Flat Model
	 */
	public void noChange(NoChangeEvent structuredDocumentEvent) {
	}

	/**
	 * Implementing IStructuredDocumentListener's method
	 * Event from CSS Flat Model
	 */
	public void nodesReplaced(StructuredDocumentRegionsReplacedEvent event) {
		if (event == null)
			return;
		if (event.getOriginalSource() == getRequesterH2C())
			return;
		IStructuredDocumentRegionList oldStructuredDocumentRegions = event.getOldStructuredDocumentRegions();
		IStructuredDocumentRegionList newStructuredDocumentRegions = event.getNewStructuredDocumentRegions();
		if (oldStructuredDocumentRegions == null && newStructuredDocumentRegions == null)
			return;

		replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions);
	}

	/**
	 * Overriding INodeAdapter's method
	 * Event from <STYLE> element
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
		if (this.ignoreNotification)
			return;

		if (eventType == INodeNotifier.ADD || eventType == INodeNotifier.REMOVE || eventType == INodeNotifier.CONTENT_CHANGED) {
			contentChanged();
		}
		else if (eventType == INodeNotifier.CHANGE) {
			Attr attr = (Attr) changedFeature;
			if (attr == null)
				return;
			String name = attr.getName();
			if (name.equalsIgnoreCase("type")) { //$NON-NLS-1$
				this.replaceModel = true;

				Element element = getElement();
				if (element == null) {
					return;
				}
				Document document = element.getOwnerDocument();
				if (document == null) {
					return;
				}
				HTMLDocumentAdapter adapter = (HTMLDocumentAdapter) ((INodeNotifier) document).getAdapterFor(IStyleSheetListAdapter.class);
				if (adapter != null) {
					adapter.childReplaced();
				}
			}
		}
	}

	/**
	 * Implementing IStructuredDocumentListener's method
	 * Event from CSS Flat Model
	 */
	public void regionChanged(RegionChangedEvent event) {
		if (event == null)
			return;
		if (event.getOriginalSource() == getRequesterH2C())
			return;
		IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion();
		if (flatNode == null)
			return;

		changeStructuredDocumentRegion(flatNode);
	}

	/**
	 * Implementing IStructuredDocumentListener's method
	 * Event from CSS Flat Model
	 */
	public void regionsReplaced(RegionsReplacedEvent event) {
		if (event == null)
			return;
		if (event.getOriginalSource() == getRequesterH2C())
			return;
		IStructuredDocumentRegion flatNode = event.getStructuredDocumentRegion();
		if (flatNode == null)
			return;

		changeStructuredDocumentRegion(flatNode);
	}

	/**
	 * Apply changes from CSS sub-model to HTML model
	 */
	private void replaceData(int offset, int length, String data) {
		XMLNode element = (XMLNode) getElement();
		if (element == null)
			return;
		XMLModel ownerModel = element.getModel();
		if (ownerModel == null)
			return;
		IStructuredDocument structuredDocument = ownerModel.getStructuredDocument();
		if (structuredDocument == null)
			return;
		IStructuredDocumentRegion flatNode = element.getStartStructuredDocumentRegion();
		if (flatNode == null)
			return;

		int contentOffset = flatNode.getEndOffset();
		if (data == null)
			data = "";//$NON-NLS-1$

		this.ignoreNotification = true;
		structuredDocument.replaceText(getRequesterC2H(), contentOffset + offset, length, data);
		this.ignoreNotification = false;
	}

	/**
	 * Preparation of applying changes from CSS sub-model to HTML model
	 */
	private void replaceStructuredDocumentRegions(IStructuredDocumentRegionList newStructuredDocumentRegions, IStructuredDocumentRegionList oldStructuredDocumentRegions) {
		int offset = 0;
		int length = 0;
		if (oldStructuredDocumentRegions != null) {
			int count = oldStructuredDocumentRegions.getLength();
			if (count > 0) {
				IStructuredDocumentRegion first = oldStructuredDocumentRegions.item(0);
				if (first != null)
					offset = first.getStart();
				IStructuredDocumentRegion last = oldStructuredDocumentRegions.item(count - 1);
				if (last != null)
					length = last.getEnd() - offset;
			}
		}
		String data = null;
		if (newStructuredDocumentRegions != null) {
			int count = newStructuredDocumentRegions.getLength();
			if (count > 0) {
				StringBuffer buffer = new StringBuffer();
				for (int i = 0; i < count; i++) {
					IStructuredDocumentRegion flatNode = newStructuredDocumentRegions.item(i);
					if (flatNode == null)
						continue;
					buffer.append(flatNode.getText());
					if (i == 0)
						offset = flatNode.getStart();
				}
				data = buffer.toString();
			}
		}

		replaceData(offset, length, data);
	}

	/**
	 */
	protected void setModel(ICSSModel model) {
		ICSSModel oldModel = getExistingModel();
		if (model == oldModel)
			return;
		super.setModel(model);
		if (oldModel != null)
			oldModel.removeStyleListener(this);
		if (model != null)
			model.addStyleListener(this);
	}
}