/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.commands.range;

import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.commands.CommandResources;
import org.eclipse.jst.pagedesigner.dom.DOMRange;
import org.eclipse.jst.pagedesigner.dom.DOMRefPosition;
import org.eclipse.jst.pagedesigner.dom.DOMUtil;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class ApplyStyleCommand extends RangeModeCommand {
	private String _tag;

	private String _cssProperty;

	private String _cssPropertyValue;

	protected Element _applyingNode;

	/**
	 * @param viewer
	 * @param tag 
	 * @param property 
	 * @param value 
	 */
	public ApplyStyleCommand(IHTMLGraphicalViewer viewer, String tag,
			String property, String value) {
		super(
				CommandResources
						.getString("ApplyStyleCommand.Label.ApplyStyle"), viewer); //$NON-NLS-1$
		this._tag = tag;
		this._cssProperty = property;
		this._cssPropertyValue = value;
	}

	public ApplyStyleCommand(IHTMLGraphicalViewer viewer, Element node,
			String property, String value) {
		super(
				CommandResources
						.getString("ApplyStyleCommand.Label.ApplyStyle"), viewer); //$NON-NLS-1$
		this._applyingNode = node;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.commands.DesignerCommand#doExecute()
	 */
	protected DOMRange doRangeExecute(DOMRange range) {
		if (range == null || range.isEmpty()) {
			return null;
		}

		boolean ordered = range.isOrdered();
		IDOMPosition start = ordered ? range.getStartPosition() : range
				.getEndPosition();
		IDOMPosition end = ordered ? range.getEndPosition() : range
				.getStartPosition();

		Node startContainer = start.getContainerNode();
		Node endContainer = end.getContainerNode();

		Node common = DOMUtil.findCommonAncester(start.getContainerNode(), end
				.getContainerNode());
		if (common == null) {
			// should not happen.
			return null;
		}

		if (common instanceof Text) {
			// under the same Text scope
			range = doTextNodeStyleApply((Text) common, start.getOffset(), end
					.getOffset());

			return range;
		}
        
        if (startContainer instanceof Text) {
        	// if the start offset is 0,then skip split the Text
        	if (start.getOffset() > 0) {
        		startContainer = ((Text) startContainer).splitText(start
        				.getOffset());
        		start = new DOMRefPosition(startContainer, false);
        	}
        } else {
        	startContainer = start.getNextSiblingNode();
        }
        if (endContainer instanceof Text) {
        	if (end.getOffset() > 0) {
        		endContainer = ((Text) endContainer).splitText(end
        				.getOffset());
        		endContainer = endContainer.getPreviousSibling();
        	} else {
        		endContainer = endContainer.getPreviousSibling();
        	}
        } else {
        	endContainer = end.getPreviousSiblingNode();
        }

        for (Node node = startContainer; node != endContainer; node = EditModelQuery
        		.getInstance().getNextLeafNeighbor(node)) {
        	if (EditModelQuery.hasAncestor(node, getTag(), true)) {
        		continue;
        	}
        	Element newnode = createStyleElement();
        	node.getParentNode().insertBefore(newnode, node);
        	newnode.appendChild(node);
        }
        if (!EditModelQuery.hasAncestor(endContainer, getTag(), true)) {
        	Element newnode = createStyleElement();
        	endContainer.getParentNode()
        			.insertBefore(newnode, endContainer);
        	newnode.appendChild(endContainer);
        }

		// merge the style tags

		for (Node node = startContainer; node != endContainer; node = EditModelQuery
				.getInstance().getNextLeafNeighbor(node)) {
			Node stylenode = node;
			while (stylenode != null
					&& !stylenode.getNodeName().equalsIgnoreCase(getTag())) {
				stylenode = stylenode.getParentNode();
			}
			if (stylenode == null) {
				continue;
			}
			if (stylenode.getNextSibling() != null
					&& stylenode.getNextSibling().getNodeName()
							.equalsIgnoreCase(getTag())) {
				Node sibling = stylenode.getNextSibling();
				while (sibling.getFirstChild() != null) {
					stylenode.appendChild(sibling.getFirstChild());
				}
				stylenode.getParentNode().removeChild(sibling);
				node = startContainer;
			}
		}

		return new DOMRange(start, end);

		/*
		 * boolean ordered = range.isOrdered(); IDOMPosition start = ordered ?
		 * range.getStartPosition() : range.getEndPosition(); IDOMPosition end =
		 * ordered ? range.getEndPosition() : range.getStartPosition();
		 * 
		 * Node common = DOMUtil.findCommonAncester(start.getContainerNode(),
		 * end.getContainerNode()); if (common == null) { // should not happen.
		 * return null; }
		 * 
		 * DOMRange result = null; if (common instanceof Text) { result =
		 * doTextNodeStyleApply((Text) common, start.getOffset(),
		 * end.getOffset()); } else { IDOMPosition startPosition = start;
		 * IDOMPosition endPosition = end; Node ancester = common; DOMRange[]
		 * leftRange = new DOMRange[1]; DOMRange[] rightRange = new DOMRange[1];
		 * 
		 * startPosition = partialApply(startPosition, ancester, true,
		 * leftRange); endPosition = partialApply(endPosition, ancester, false,
		 * rightRange); DOMRange middle = middleApply(ancester, startPosition,
		 * endPosition);
		 * 
		 * IDOMPosition startref = null; if (leftRange[0] != null &&
		 * leftRange[0].getStartPosition() != null) { startref =
		 * leftRange[0].getStartPosition(); } else if (middle != null &&
		 * middle.getStartPosition() != null) { startref =
		 * middle.getStartPosition(); } else if (rightRange[0] != null &&
		 * rightRange[0].getStartPosition() != null) { startref =
		 * rightRange[0].getStartPosition(); }
		 * 
		 * IDOMPosition endref = null; if (rightRange[0] != null &&
		 * rightRange[0].getEndPosition() != null) { endref =
		 * rightRange[0].getEndPosition(); } else if (middle != null &&
		 * middle.getEndPosition() != null) { endref = middle.getEndPosition(); }
		 * else if (leftRange[0] != null && leftRange[0].getEndPosition() !=
		 * null) { endref = leftRange[0].getEndPosition(); }
		 * 
		 * if (startref == null) { result = null; } else { startref = new
		 * DOMPosition(EditModelQuery.getInstance().getNextLeafNeighbor(startref.getContainerNode()),
		 * 0); System.out.println(startref.toString()); endref = new
		 * DOMPosition(endref.getContainerNode(), 0); result = new
		 * DOMRange(startref, endref); } }
		 * 
		 * if (result == null) { return null; }
		 * 
		 * if (ordered) { return result; } else { return new
		 * DOMRange(result.getEndPosition(), result.getStartPosition()); }
		 */
	}

    // TODO: unused code.  Dead?
//	private DOMRange middleApply(Node ancester, IDOMPosition startPosition,
//			IDOMPosition endPosition) {
//		startPosition = skip(startPosition, true);
//		if (startPosition.getNextSiblingNode() == null
//				|| startPosition.getOffset() >= endPosition.getOffset()) {
//			return null;
//		} else {
//			List needMove = new ArrayList();
//			Node startNext = startPosition.getNextSiblingNode();
//			Node endNext = endPosition.getNextSiblingNode();
//			while (startNext != null && startNext != endNext) {
//				needMove.add(startNext);
//				startNext = startNext.getNextSibling();
//			}
//			Element newEle = createStyleElement();
//			ancester.insertBefore(newEle, startPosition.getNextSiblingNode());
//			for (int i = 0, n = needMove.size(); i < n; i++) {
//				newEle.appendChild((Node) needMove.get(i));
//			}
//			return new DOMRange(new DOMRefPosition(newEle, false),
//					new DOMRefPosition(newEle, true));
//		}
//	}

    // TODO: unused code.  Dead?
//	private IDOMPosition partialApply(IDOMPosition position, Node ancester,
//			boolean forward, DOMRange[] result) {
//		IDOMPosition startRef = null, endRef = null;
//
//		while (position != null && position.getContainerNode() != ancester) {
//			Node container = position.getContainerNode();
//			if (container instanceof Text) {
//				// splitText will move the position up one level
//				position = splitText(position);
//			} else {
//				// skip those nodes that can't have the style applied.
//				position = skip(position, forward);
//				Node sibling = position.getSibling(forward);
//				if (sibling != null) {
//					List needMove = new ArrayList();
//					while (sibling != null) {
//						needMove.add(sibling);
//						sibling = forward ? sibling.getNextSibling() : sibling
//								.getPreviousSibling();
//					}
//
//					// ok, there is nodes that need the style
//					Element newEle = createStyleElement();
//					container.insertBefore(newEle, position
//							.getNextSiblingNode());
//					for (int i = 0, size = needMove.size(); i < size; i++) {
//						newEle.appendChild((Node) needMove.get(i));
//					}
//					if (startRef == null) {
//						startRef = new DOMRefPosition(newEle, !forward);
//					}
//					endRef = new DOMRefPosition(newEle, forward);
//				}
//				// move the position up one level
//				position = new DOMRefPosition(container, forward);
//			}
//		}
//		if (startRef == null) {
//			result[0] = null;
//		} else {
//			result[0] = forward ? new DOMRange(startRef, endRef)
//					: new DOMRange(endRef, startRef);
//		}
//		return position;
//	}

	/**
	 * @param position
	 * @return
	 */
    // TODO: dead?
//	private IDOMPosition splitText(IDOMPosition position) {
//		Text text = (Text) position.getContainerNode();
//		int offset = position.getOffset();
//		if (offset <= 0) {
//			return new DOMRefPosition(text, false);
//		} else if (offset >= text.getData().length()) {
//			return new DOMRefPosition(text, true);
//		} else {
//			text.splitText(offset);
//			return new DOMRefPosition(text, true);
//		}
//	}

	/**
	 * @param start
	 * @param end
	 * @param common
	 */
	private DOMRange doTextNodeStyleApply(Text textNode, int startOffset,
			int endOffset) {
		String data = textNode.getData();
		String before = data.substring(0, startOffset);
		String middle = data.substring(startOffset, endOffset);
		String tail = data.substring(endOffset);

		Text middleText = getModel().getDocument().createTextNode(middle);

		// case 1: normal one
		if (!isEmptyString(before) && !isEmptyString(tail)) {
			Node parent = textNode.getParentNode();
			parent.insertBefore(
					getModel().getDocument().createTextNode(before), textNode);
			Element bnode = createStyleElement();
			bnode.appendChild(middleText);
			parent.insertBefore(bnode, textNode);
			textNode.setNodeValue(tail);
		}

		if (isEmptyString(before) && !isEmptyString(tail)) {
			Node sibling = textNode.getPreviousSibling();
			if (sibling != null
					&& sibling.getNodeName().equalsIgnoreCase(getTag())) {
				sibling.appendChild(middleText);
			} else {
				Node parent = textNode.getParentNode();
				parent.insertBefore(getModel().getDocument().createTextNode(
						before), textNode);
				Element bnode = createStyleElement();
				bnode.appendChild(middleText);
				parent.insertBefore(bnode, textNode);
			}
			textNode.setNodeValue(tail);
		}

		if (!isEmptyString(before) && isEmptyString(tail)) {
			Node sibling = textNode.getNextSibling();
			textNode.setNodeValue(before);
			if (sibling != null
					&& sibling.getNodeName().equalsIgnoreCase(getTag())) {
				sibling.insertBefore(middleText, sibling.getFirstChild());
			} else {
				Element bnode = createStyleElement();
				bnode.appendChild(middleText);
				textNode.getParentNode().insertBefore(bnode, sibling);
			}
		}

		if (isEmptyString(before) && isEmptyString(tail)) {

			Node previousSibling = textNode.getPreviousSibling();
			Node nextSibling = textNode.getNextSibling();
			//
			if (getTag().equalsIgnoreCase(IHTMLConstants.TAG_P)) {
				Element bnode = createStyleElement();
				bnode.appendChild(middleText);
				textNode.getParentNode().insertBefore(bnode, textNode);
				textNode.getParentNode().removeChild(textNode);
			}
			//
			else {
				if (previousSibling != null
						&& previousSibling.getNodeName().equalsIgnoreCase(
								getTag()) && nextSibling != null
						&& nextSibling.getNodeName().equalsIgnoreCase(getTag())) {
					previousSibling.appendChild(middleText);
					while (nextSibling.getFirstChild() != null) {
						previousSibling
								.appendChild(nextSibling.getFirstChild());
					}
					nextSibling.getParentNode().removeChild(nextSibling);
				} else if (previousSibling != null
						&& previousSibling.getNodeName().equalsIgnoreCase(
								getTag())) {
					previousSibling.appendChild(middleText);
				} else if (nextSibling != null
						&& nextSibling.getNodeName().equalsIgnoreCase(getTag())) {
					nextSibling.insertBefore(middleText, nextSibling
							.getFirstChild());
				} else {
					Element bnode = createStyleElement();
					bnode.appendChild(middleText);
					textNode.getParentNode().insertBefore(bnode, textNode);
				}
				textNode.getParentNode().removeChild(textNode);
			}
		}

		return new DOMRange(new DOMRefPosition(middleText, false),
				new DOMRefPosition(middleText, true));
	}

	private boolean isEmptyString(String str) {
		if (str == null || str.length() == 0) {
			return true;
		}
		return false;
	}

	/**
	 * @return a style element (cached on create)
	 */
	protected Element createStyleElement() {
		if (_applyingNode != null) {
			return _applyingNode;
		}
        Element element = getModel().getDocument().createElement(getTag());
        if (_cssProperty != null && _cssPropertyValue != null) {
        	element.setAttribute(_cssProperty, _cssPropertyValue);
        }
        return element;
	}

	/**
	 * @param position
	 * @param b
	 * @return
	 */
    // TODO: dead?
//	private IDOMPosition skip(IDOMPosition position, boolean forward) {
//		Node node = position.getSibling(forward);
//
//		if (node == null) {
//			return position;
//		}
//		boolean canSkip = false;
//		if (node instanceof Text) {
//			canSkip = ((IDOMText) node).isElementContentWhitespace();
//		} else if (node instanceof Element) {
//			if (getTag().equalsIgnoreCase(((Element) node).getTagName())) {
//				canSkip = true;
//			} else {
//				canSkip = false;
//			}
//		} else {
//			canSkip = true;
//		}
//		if (canSkip) {
//			return new DOMRefPosition(node, forward);
//		} else {
//			return position;
//		}
//	}

	/**
	 * @return Returns the _cssProperty.
	 */
	public final String getCssProperty() {
		return _cssProperty;
	}

	/**
	 * @param property
	 *            The _cssProperty to set.
	 */
	public final void setCssProperty(String property) {
		_cssProperty = property;
	}

	/**
	 * @return Returns the _cssPropertyValue.
	 */
	public final String getCssPropertyValue() {
		return _cssPropertyValue;
	}

	/**
	 * @param propertyValue
	 *            The _cssPropertyValue to set.
	 */
	public final void setCssPropertyValue(String propertyValue) {
		_cssPropertyValue = propertyValue;
	}

	/**
	 * @return Returns the _tag.
	 */
	public final String getTag() {
		if (_tag != null) {
			return _tag;
		}
        return _applyingNode.getNodeName();
	}

	/**
	 * @param _tag
	 *            The _tag to set.
	 */
	public final void setTag(String _tag) {
		this._tag = _tag;
	}
}
