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



import org.eclipse.wst.css.core.internal.provisional.adapters.IModelProvideAdapter;
import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.html.core.internal.provisional.HTML40Namespace;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
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;
		IDOMNode content = (IDOMNode) 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 && ((IDOMNode) getElement()).getModel() != null) ? (Object) ((IDOMNode) 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.getOriginalRequester() == 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.getOriginalRequester() == 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.getOriginalRequester() == 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.getOriginalRequester() == 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) {
		IDOMNode element = (IDOMNode) getElement();
		if (element == null)
			return;
		IDOMModel 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);
	}
}