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



import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
import org.eclipse.wst.html.core.HTMLCMProperties;
import org.eclipse.wst.html.core.HTMLFormatContraints;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.document.XMLText;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class HTMLTextFormatter extends HTMLFormatter {

	public static int FORMAT_ALL = 0;
	public static int FORMAT_HEAD = 1;
	public static int FORMAT_TAIL = 2;

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

	/**
	 */
	private boolean canFormatText(XMLText text) {
		if (text == null)
			return false;

		IStructuredDocumentRegion flatNode = text.getFirstStructuredDocumentRegion();
		if (flatNode != null) {
			String type = flatNode.getType();
			if (isUnparsedRegion(type))
				return false;
		}

		Node parent = text.getParentNode();
		if (parent != null && parent.getNodeType() == Node.ELEMENT_NODE) {
			XMLElement element = (XMLElement) parent;
			if (!element.isGlobalTag() && !text.isWhitespace())
				return false;
		}

		return canFormatChild(parent);
	}

	private boolean isUnparsedRegion(String type) {
		boolean result = isNestedScannedRegion(type) || isBlockScannedRegion(type);
		return result;
	}

	private boolean isBlockScannedRegion(String type) {
		return type == XMLRegionContext.BLOCK_TEXT;
	}

    /**
     * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
     * way for expedency. Should be evolved in future to depend on "nestedContext".
     */
	private boolean isNestedScannedRegion(String type) {
		final String JSP_CONTENT = "JSP_CONTENT"; //$NON-NLS-1$
		return type.equals(JSP_CONTENT);
	}

	/**
	 */
	private boolean canRemoveHeadingSpaces(XMLNode node) {
		if (node == null)
			return false;
		if (node.getPreviousSibling() != null)
			return false;
		Node parent = node.getParentNode();
		if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE)
			return false;

		CMElementDeclaration decl = getElementDeclaration((Element) parent);
		if (decl == null || (!decl.supports(HTMLCMProperties.LINE_BREAK_HINT)))
			return false;
		String hint = (String) decl.getProperty(HTMLCMProperties.LINE_BREAK_HINT);
		return hint.equals(HTMLCMProperties.Values.BREAK_BEFORE_START_AND_AFTER_END);
	}

	/**
	 */
	private boolean canRemoveTailingSpaces(XMLNode node) {
		if (node == null)
			return false;
		if (node.getNextSibling() != null)
			return false;
		Node parent = node.getParentNode();
		if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE)
			return false;

		CMElementDeclaration decl = getElementDeclaration((Element) parent);
		if (decl == null || (!decl.supports(HTMLCMProperties.LINE_BREAK_HINT)))
			return false;
		String hint = (String) decl.getProperty(HTMLCMProperties.LINE_BREAK_HINT);
		return hint.equals(HTMLCMProperties.Values.BREAK_BEFORE_START_AND_AFTER_END);
	}

	/**
	 */
	protected void formatNode(XMLNode node, HTMLFormatContraints contraints) {
		formatText(node, contraints, FORMAT_ALL); // full format
	}

	/**
	 */
	protected void formatText(XMLNode node, HTMLFormatContraints contraints, int mode) {
		if (node == null)
			return;
		Node parent = node.getParentNode();
		if (parent == null)
			return;

		XMLText text = (XMLText) node;
		String source = text.getSource();

		if (!canFormatText(text)) {
			setWidth(contraints, source);
			return;
		}

		int offset = text.getStartOffset();
		int length = text.getEndOffset() - offset;

		// format adjacent text at once
		if (mode == FORMAT_HEAD) {
			Node next = node.getNextSibling();
			while (next != null && next.getNodeType() == Node.TEXT_NODE) {
				XMLText nextText = (XMLText) next;
				length += (nextText.getEndOffset() - nextText.getStartOffset());
				String nextSource = nextText.getSource();
				if (nextSource != null && nextSource.length() > 0) {
					if (source == null)
						source = nextSource;
					else
						source += nextSource;
				}
				next = next.getNextSibling();
			}
		}
		else if (mode == FORMAT_TAIL) {
			Node prev = node.getPreviousSibling();
			while (prev != null && prev.getNodeType() == Node.TEXT_NODE) {
				XMLText prevText = (XMLText) prev;
				offset = prevText.getStartOffset();
				length += (prevText.getEndOffset() - offset);
				String prevSource = prevText.getSource();
				if (prevSource != null && prevSource.length() > 0) {
					if (source == null)
						source = prevSource;
					else
						source = prevSource + source;
				}
				prev = prev.getPreviousSibling();
			}
		}

		SpaceConverter converter = new SpaceConverter(source, keepBlankLines(contraints));

		int wordLength = converter.nextWord();
		if (wordLength == 0) { // only spaces
			if (!converter.hasSpaces())
				return; // empty
			boolean removeSpaces = false;
			if (parent.getNodeType() == Node.ELEMENT_NODE) {
				// check if tags are omitted
				XMLNode element = (XMLNode) parent;
				if (node.getPreviousSibling() == null && element.getStartStructuredDocumentRegion() == null) {
					removeSpaces = true;
				}
				else if (node.getNextSibling() == null && element.getEndStructuredDocumentRegion() == null) {
					removeSpaces = true;
				}
			}
			if (removeSpaces) {
				converter.replaceSpaces(null);
			}
			else if (!isWidthAvailable(contraints, 2) || canInsertBreakAfter(node) || canInsertBreakBefore(node)) {
				String spaces = null;
				if (node.getNextSibling() == null) { // last spaces
					// use parent indent for the end tag
					spaces = getBreakSpaces(parent);
				}
				else {
					spaces = getBreakSpaces(node);
				}
				converter.replaceSpaces(spaces);
				setWidth(contraints, spaces);
			}
			else if (canRemoveHeadingSpaces(node) || canRemoveTailingSpaces(node)) {
				converter.replaceSpaces(null);
			}
			else {
				converter.compressSpaces();
				addWidth(contraints, 1);
			}
		}
		else {
			String breakSpaces = null;

			// format heading spaces
			boolean hasSpaces = converter.hasSpaces();
			if (mode == FORMAT_TAIL) {
				// keep spaces as is
				addWidth(contraints, converter.getSpaceCount());
			}
			else if ((hasSpaces && !isWidthAvailable(contraints, wordLength + 1)) || canInsertBreakBefore(node)) {
				breakSpaces = getBreakSpaces(node);
				converter.replaceSpaces(breakSpaces);
				setWidth(contraints, breakSpaces);
			}
			else {
				if (hasSpaces) {
					if (canRemoveHeadingSpaces(node)) {
						converter.replaceSpaces(null);
					}
					else {
						converter.compressSpaces();
						addWidth(contraints, 1);
					}
				}
			}
			addWidth(contraints, wordLength);

			// format middle
			wordLength = converter.nextWord();
			while (wordLength > 0) {
				if (mode != FORMAT_ALL) {
					// keep spaces as is
					addWidth(contraints, converter.getSpaceCount());
				}
				else if (!isWidthAvailable(contraints, wordLength + 1)) {
					if (breakSpaces == null)
						breakSpaces = getBreakSpaces(node);
					converter.replaceSpaces(breakSpaces);
					setWidth(contraints, breakSpaces);
				}
				else {
					converter.compressSpaces();
					addWidth(contraints, 1);
				}
				addWidth(contraints, wordLength);
				wordLength = converter.nextWord();
			}

			// format tailing spaces
			hasSpaces = converter.hasSpaces();
			if (mode == FORMAT_HEAD) {
				// keep spaces as is
				addWidth(contraints, converter.getSpaceCount());
			}
			else if ((hasSpaces && !isWidthAvailable(contraints, 2)) || canInsertBreakAfter(node)) {
				if (node.getNextSibling() == null) { // last test
					// use parent indent for the end tag
					breakSpaces = getBreakSpaces(parent);
				}
				else {
					if (breakSpaces == null)
						breakSpaces = getBreakSpaces(node);
				}
				converter.replaceSpaces(breakSpaces);
				setWidth(contraints, breakSpaces);
			}
			else {
				if (hasSpaces) {
					if (canRemoveTailingSpaces(node)) {
						converter.replaceSpaces(null);
					}
					else {
						converter.compressSpaces();
						addWidth(contraints, 1);
					}
				}
			}
		}

		if (converter.isModified()) {
			source = converter.getSource();
			replaceSource(text.getModel(), offset, length, source);
		}
	}
}