/*******************************************************************************
 * 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 java.util.Arrays;

import org.eclipse.core.runtime.Assert;
import org.eclipse.gef.EditPart;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.dom.DOMPosition;
import org.eclipse.jst.pagedesigner.dom.DOMPositionHelper;
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.EditHelper;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.dom.IDOMPosition;
import org.eclipse.jst.pagedesigner.dom.IDOMRefPosition;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * @author mengbo
 */
public class ParagraphApplyStyleCommand extends ApplyStyleCommand {

    /**
     * the list of possible html heading tags
     */
    private static final String[] HH = { "h1", "h2", "h3", "h4", "h5", "h6" };

    /**
	 * @param viewer
	 * @param tag
	 * @param property
	 * @param value
	 */
	public ParagraphApplyStyleCommand(IHTMLGraphicalViewer viewer, String tag,
			String property, String value) {
		super(viewer, tag, property, value);
	}

	/**
	 * @param viewer
	 * @param node
	 * @param property
	 * @param value
	 */
	public ParagraphApplyStyleCommand(IHTMLGraphicalViewer viewer,
			Element node, String property, String value) {
		super(viewer, node, property, value);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.commands.range.RangeModeCommand#doRangeExecute(org.eclipse.jst.pagedesigner.dom.DOMRange)
	 */
	protected DOMRange doRangeExecute(DOMRange range) {
		if (range != null) {
			boolean ordered = range.isOrdered();
			IDOMPosition start = ordered ? range.getStartPosition() : range
					.getEndPosition();
			IDOMPosition end = ordered ? range.getEndPosition() : range
					.getStartPosition();
			Node common = null;
			Node container = null;
			if (EditModelQuery.isSame(range)) {
				container = start.getContainerNode();
				ParagraphFinder finder = new ParagraphFinder(start);
				Paragraph p = finder.getParagraph(start);
				start = p.getStart();
				end = p.getEnd();
				common = p.getLowestContainer();
			} else {
				common = EditModelQuery.getInstance().getCommonAncestor(start,
						end);
			}
			DOMRange rt;
			// This code is for h1-h6 only, it may need to be replaced.
			if ((rt = replaceExistingH(start, end)) != null) {
				return rt;
			}
			// replace existing p
			if (getTag().equalsIgnoreCase(IHTMLConstants.TAG_P)) {
				rt = replaceExistingP(start, end);
				if (rt != null) {
					return rt;
				}
			}
			if (start.getContainerNode() == end.getContainerNode()) {
				int offset1 = start.getOffset();
				int offset2 = end.getOffset();
				IDOMPosition old = start;
				start = split(start);
				// parent is splited
				if (start != old) {
					container = start.getNextSiblingNode();
					offset2 -= offset1;
					end = new DOMPosition(container, offset2);
				}
				end = split(end);
			} else {
				start = split(common, start);
				end = split(common, end);
			}
			range = InsertStyleTag(new DOMRange(start, end));
		}
		return range;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.commands.Command#canExecute()
	 */
	public boolean canExecute() {
		return true;
	}

	/*
	 * Try to split the node so that we can avoid wrap its children directly.
	 * Begining from 'position' the split can reach as high as the level of
	 * 'common'.
	 */
	private IDOMPosition split(Node common, IDOMPosition position) {
		Assert.isTrue(EditModelQuery.isChild(common, position
				.getContainerNode()));
		Node container = position.getContainerNode();
		String[] styleNodes = new String[EditModelQuery.HTML_STYLE_NODES.size()];
		EditModelQuery.HTML_STYLE_NODES.toArray(styleNodes);
		while (EditModelQuery.isText(container) || (container != common && //
				EditModelQuery.containItem(styleNodes, container, true))) {
			IDOMPosition old = position;
			position = EditHelper.splitNode(position);
			if (old == position) {
				int pos = EditHelper.getLocation(position);
				switch (pos) {
				case -1:
					position = new DOMRefPosition(position.getContainerNode(),
							false);
					break;
				case 1:
					position = new DOMRefPosition(position.getContainerNode(),
							true);
				}
			}
			Node containerBackup = container;
			container = container.getParentNode();
			if (containerBackup.getNodeName().equalsIgnoreCase(
					IHTMLConstants.TAG_P)) {
				container.removeChild(containerBackup);
			}
		}
		return position;
	}

	/*
	 * Split the position's container node only.
	 */
	private IDOMPosition split(IDOMPosition position) {
		Node container = position.getContainerNode();
		String[] styleNodes = new String[EditModelQuery.HTML_STYLE_NODES.size()];
		EditModelQuery.HTML_STYLE_NODES.toArray(styleNodes);
		if (EditModelQuery.isText(container)
				|| EditModelQuery.containItem(styleNodes, container, true)) {
			return EditHelper.splitNode(position);
		}
		return position;
	}

	private DOMRange replaceExistingH(IDOMPosition start, IDOMPosition end) {
		Node common = EditModelQuery.getInstance()
				.getCommonAncestor(start, end);
		// Here we insert some code to avoid creating tags duplicated. but these
		// are not the entire cases.
		if (Arrays.asList(HH).contains(
				getAName(getTag()).toLowerCase())
				&& Arrays.asList(HH).contains(
						getAName(common.getNodeName()).toLowerCase())) {
			// uncheck action menu
			if (getAName(getTag()).toLowerCase().equalsIgnoreCase(
					getAName(common.getNodeName()).toLowerCase())) {
				NodeList nodes = common.getChildNodes();

				for (int i = 0, size = nodes.getLength(); i < size; i++) {
					common.getParentNode().insertBefore(nodes.item(i), common);
				}
				common.getParentNode().removeChild(common);
				return new DOMRange(start, end);
			}
			start = DOMPositionHelper.toDOMRefPosition(start);
			end = DOMPositionHelper.toDOMRefPosition(end);
			Node newHNode = EditModelQuery.getDocumentNode(common)
					.createElement(getTag());
			EditModelQuery.copyChildren(common, newHNode);
			common.getParentNode().replaceChild(newHNode, common);
			return new DOMRange(start, end);
		}
		return null;
	}

	private DOMRange replaceExistingP(IDOMPosition start, IDOMPosition end) {
		// find the selected startNode,endNode and start node's parent node
		Node startNode = start instanceof IDOMRefPosition ? start
				.getNextSiblingNode() : start.getContainerNode();
		Node endNode = end instanceof IDOMRefPosition ? end
				.getPreviousSiblingNode() : end.getContainerNode();
		Node parentNode = startNode.getParentNode();

		if (!(start.isText()) && start instanceof DOMPosition) {
			startNode = startNode.getChildNodes().item(start.getOffset());
			parentNode = start.getContainerNode();
		}
		if (!(end.isText()) && end instanceof DOMPosition) {
			// because the offset is based on the position between nodes,so we
			// need to reduce one from the offset
			// in order to get the correct end node.
			endNode = endNode.getChildNodes().item(end.getOffset() - 1);
		}

		// compute selected character number in the text or selected element
		// number under a node
		int len = 0;
//		if (start instanceof DOMPosition && end instanceof DOMPosition
//				|| start instanceof IDOMPosition && end instanceof IDOMPosition) {
        // TODO: as written, this will be the only statement run, since
        // both start and end are instanceof IDOMPosition by defn.
			len = end.getOffset() - start.getOffset();
//		} else {
//			IDOMRefPosition startRef = null;
//			IDOMRefPosition endRef = null;
//			if (!(start.isText()) && start instanceof DOMPosition) {
//				startRef = new DOMRefPosition(startNode, false);
//			} else if (!(end.isText()) && end instanceof DOMPosition) {
//				endRef = new DOMRefPosition(endNode, true);
//			}
//			len = (endRef != null ? endRef.getOffset() : end.getOffset())
//					- (startRef != null ? startRef.getOffset() : start
//							.getOffset());
//		}

		// if a full Text node is selected,and the Text node is the only child
		// of its parent
		if ((startNode == endNode) && (startNode instanceof Text)) {
			TextEditPart part = (TextEditPart) ((INodeNotifier) startNode)
					.getAdapterFor(EditPart.class);
			boolean condition = false;
			if (start instanceof IDOMRefPosition
					|| (start instanceof DOMPosition && !start.isText())) {
				condition = parentNode.getNodeName().equalsIgnoreCase(
						IHTMLConstants.TAG_P)
						&& parentNode.getChildNodes().getLength() == 1;
			} else {
				condition = parentNode.getNodeName().equalsIgnoreCase(
						IHTMLConstants.TAG_P)
						&& parentNode.getChildNodes().getLength() == 1
						&& part.getTextData().length() == len;
			}
			if (condition) {
				// if uncheck the align action
				if (this.getApplyingNode()
						.getAttribute(IHTMLConstants.ATTR_ALIGN)
						.equals(
								((Element) parentNode)
										.getAttribute(IHTMLConstants.ATTR_ALIGN))) {
					((Element) parentNode)
							.removeAttribute(IHTMLConstants.ATTR_ALIGN);
					IDOMPosition startPos = new DOMPosition(parentNode, 0);
					IDOMPosition endPos = new DOMRefPosition(endNode, true);
					return new DOMRange(startPos, endPos);
				}
				// else replace the align attribute
				/**
				 * this._applyingNode.appendChild(startNode);
				 * parentNode.getParentNode().replaceChild(this._applyingNode,
				 * parentNode);
				 */
				String align = this.getApplyingNode()
						.getAttribute(IHTMLConstants.ATTR_ALIGN);
				((Element) parentNode).setAttribute(IHTMLConstants.ATTR_ALIGN,
						align);

				IDOMPosition startPos = new DOMPosition(parentNode, 0);
				IDOMPosition endPos = new DOMRefPosition(endNode, true);
				return new DOMRange(startPos, endPos);
			}
		} else {
			if (parentNode != null
					&& parentNode.getNodeName().equalsIgnoreCase(
							IHTMLConstants.TAG_P)
					&& parentNode.getChildNodes().getLength() == len) {
				if (this.getApplyingNode()
						.getAttribute(IHTMLConstants.ATTR_ALIGN)
						.equals(
								((Element) parentNode)
										.getAttribute(IHTMLConstants.ATTR_ALIGN))) {
					((Element) parentNode)
							.removeAttribute(IHTMLConstants.ATTR_ALIGN);
					IDOMPosition startPos = new DOMPosition(parentNode, 0);
					IDOMPosition endPos = new DOMRefPosition(endNode, true);
					return new DOMRange(startPos, endPos);
				}

				/**
				 * Node sibling = startNode.getNextSibling();
				 * this._applyingNode.appendChild(startNode); Node
				 * endNodeSibling = endNode.getNextSibling(); while (sibling !=
				 * null && startNode != endNode && sibling != endNodeSibling) {
				 * Node tempNode = sibling.getNextSibling();
				 * this._applyingNode.appendChild(sibling); sibling = tempNode; }
				 * parentNode.getParentNode().replaceChild(this._applyingNode,
				 * parentNode);
				 */
				String align = this.getApplyingNode()
						.getAttribute(IHTMLConstants.ATTR_ALIGN);
				((Element) parentNode).setAttribute(IHTMLConstants.ATTR_ALIGN,
						align);

				IDOMPosition startPos = new DOMPosition(parentNode, 0);
				IDOMPosition endPos = new DOMRefPosition(endNode, true);
				return new DOMRange(startPos, endPos);
			}
		}
		return null;
	}

	private DOMRange InsertStyleTag(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 (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();
        }

        // now the startContainer and the endContainer should share the same
        // parent
        Element newNode = createStyleElement();
        startContainer.getParentNode()
        		.insertBefore(newNode, startContainer);

        Node sibling = startContainer.getNextSibling();
        newNode.appendChild(startContainer);
        Node endNodeSibling = endContainer.getNextSibling();
        while (sibling != null && startContainer != endContainer
        		&& sibling != endNodeSibling) {
        	Node tempNode = sibling.getNextSibling();
        	newNode.appendChild(sibling);
        	sibling = tempNode;
        }

        IDOMPosition startPos = new DOMPosition(newNode, 0);
        IDOMPosition endPos = new DOMRefPosition(endContainer, true);
        return new DOMRange(startPos, endPos);
	}

	private static String getAName(String name) {
		return name == null ? "" : name;
	}
}
