/*******************************************************************************
 * Copyright (c) 2004, 2007 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.css.core.internal.formatter;

import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.core.runtime.Preferences;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.wst.css.core.internal.CSSCorePlugin;
import org.eclipse.wst.css.core.internal.cleanup.CSSCleanupStrategy;
import org.eclipse.wst.css.core.internal.cleanup.CSSCleanupStrategyImpl;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
import org.eclipse.wst.css.core.internal.preferences.CSSCorePreferenceNames;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSAttr;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclItem;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleSheet;
import org.eclipse.wst.css.core.internal.util.CSSLinkConverter;
import org.eclipse.wst.css.core.internal.util.CSSUtil;
import org.eclipse.wst.css.core.internal.util.RegionIterator;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
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.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.util.Assert;

/**
 * 
 */
public abstract class AbstractCSSSourceFormatter implements CSSSourceGenerator {

	protected final static short GENERATE = 0;
	protected final static short FORMAT = 1;
	protected final static short CLEANUP = 2;
	protected static short strategy;

	/**
	 * 
	 */
	AbstractCSSSourceFormatter() {
		super();
	}

	/**
	 * 
	 */
	protected void appendDelimBefore(ICSSNode node, CompoundRegion toAppend, StringBuffer source) {
		if (node == null || source == null)
			return;
		if (isCleanup() && !getCleanupStrategy(node).isFormatSource())
			return; // for not formatting case on cleanup action
		String delim = getLineDelimiter(node);

		boolean needIndent = !(node instanceof ICSSStyleSheet);
		if (toAppend == null) {
			source.append(delim);
			source.append(getIndent(node));
			if (needIndent)
				source.append(getIndentString());
		}
		else {
			String type = toAppend.getType();
			if (type == CSSRegionContexts.CSS_COMMENT) {
				RegionIterator it = new RegionIterator(toAppend.getDocumentRegion(), toAppend.getTextRegion());
				it.prev();
				ITextRegion prev = it.prev();
				if (prev == null || (prev.getType() == CSSRegionContexts.CSS_S && TextUtilities.indexOf(DefaultLineTracker.DELIMITERS, it.getStructuredDocumentRegion().getText(prev), 0)[0] >= 0)) {
					source.append(delim);
					source.append(getIndent(node));
					if (needIndent)
						source.append(getIndentString());
				}
				else {
					appendSpaceBefore(node, toAppend.getText(), source);
				}
			}
			else if (type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
				RegionIterator it = new RegionIterator(toAppend.getDocumentRegion(), toAppend.getTextRegion());
				it.prev();
				ITextRegion prev = it.prev();

				Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();

				if (prev.getType() == CSSRegionContexts.CSS_S && TextUtilities.indexOf(DefaultLineTracker.DELIMITERS, it.getStructuredDocumentRegion().getText(prev), 0)[0] >= 0) {
					source.append(delim);
					source.append(getIndent(node));
					if (needIndent)
						source.append(getIndentString());
				}
				else if (preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH) > 0 && (!preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_PROHIBIT_WRAP_ON_ATTR) || node.getOwnerDocument().getNodeType() != ICSSNode.STYLEDECLARATION_NODE)) {
					int length = getLastLineLength(node, source);
					int append = 1;
					if (length + append > preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH)) {
						source.append(getLineDelimiter(node));
						source.append(getIndent(node));
						if (needIndent)
							source.append(getIndentString());
					}
				}
			}
			else if (type == CSSRegionContexts.CSS_RBRACE || type == CSSRegionContexts.CSS_LBRACE) {
				source.append(delim);
				source.append(getIndent(node));
			}
			else {
				source.append(delim);
				source.append(getIndent(node));
				if (needIndent)
					source.append(getIndentString());
			}
		}
	}

	/**
	 * 
	 */
	protected void appendSpaceBefore(ICSSNode node, CompoundRegion toAppend, StringBuffer source) {
		if (node == null || toAppend == null || source == null)
			return;
		if (isCleanup() && !getCleanupStrategy(node).isFormatSource())
			return; // for not formatting case on cleanup action
		String type = toAppend.getType();

		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();

		boolean needIndent = !(node instanceof ICSSStyleSheet);
		if (type == CSSRegionContexts.CSS_COMMENT) {
			// check whether previous region is 'S' and has CR-LF
			String delim = getLineDelimiter(node);
			RegionIterator it = new RegionIterator(toAppend.getDocumentRegion(), toAppend.getTextRegion());
			it.prev();
			ITextRegion prev = it.prev();
			if (prev.getType() == CSSRegionContexts.CSS_S && TextUtilities.indexOf(DefaultLineTracker.DELIMITERS, it.getStructuredDocumentRegion().getText(prev), 0)[0] >= 0) {
				source.append(delim);
				source.append(getIndent(node));
				if (needIndent)
					source.append(getIndentString());
			}
			else {
				appendSpaceBefore(node, toAppend.getText(), source);
			}
		}
		else if (type == CSSRegionContexts.CSS_LBRACE && preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_NEWLINE_ON_OPEN_BRACE)) {
			String delim = getLineDelimiter(node);
			source.append(delim);
			source.append(getIndent(node));
			// } else if (type == CSSRegionContexts.CSS_CURLY_BRACE_CLOSE) {
			// } else if (type == CSSRegionContexts.CSS_INCLUDES || type ==
			// CSSRegionContexts.CSS_DASHMATCH) {
		}
		else if (type == CSSRegionContexts.CSS_DECLARATION_SEPARATOR && node instanceof ICSSStyleDeclItem) {
			int n = preferences.getInt(CSSCorePreferenceNames.FORMAT_PROP_PRE_DELIM);
			if (preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH) > 0 && (!preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_PROHIBIT_WRAP_ON_ATTR) || node.getOwnerDocument().getNodeType() != ICSSNode.STYLEDECLARATION_NODE)) {
				int length = getLastLineLength(node, source);
				int append = 1;
				if (length + n + append > preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH)) {
					source.append(getLineDelimiter(node));
					source.append(getIndent(node));
					if (needIndent)
						source.append(getIndentString());
					n = 0; // no space is necessary
				}
			}
			// no delimiter case
			while (n-- > 0)
				source.append(" ");//$NON-NLS-1$
		}
		else if (type == CSSRegionContexts.CSS_DECLARATION_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR || type == CSSRegionContexts.CSS_DECLARATION_VALUE_PARENTHESIS_CLOSE) {
			if (preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH) > 0 && (!preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_PROHIBIT_WRAP_ON_ATTR) || node.getOwnerDocument().getNodeType() != ICSSNode.STYLEDECLARATION_NODE)) {
				int length = getLastLineLength(node, source);
				int append = 1;
				if (length + append > preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH)) {
					source.append(getLineDelimiter(node));
					source.append(getIndent(node));
					if (needIndent)
						source.append(getIndentString());
				}
			}
		}
		else if (CSSRegionContexts.CSS_FOREIGN_ELEMENT == type) {
			return;
		}
		else
			appendSpaceBefore(node, toAppend.getText(), source);
	}

	/**
	 * 
	 */
	protected void appendSpaceBefore(ICSSNode node, String toAppend, StringBuffer source) {
		if (node == null || source == null)
			return;
		if (isCleanup() && !getCleanupStrategy(node).isFormatSource())
			return; // for not formatting case on cleanup action

		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();
		if (toAppend != null && toAppend.startsWith("{") && preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_NEWLINE_ON_OPEN_BRACE)) {//$NON-NLS-1$
			source.append(getLineDelimiter(node));
			source.append(getIndent(node));
			return;
		}
		else if (/* ! mgr.isOnePropertyPerLine() && */preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH) > 0 && (!preferences.getBoolean(CSSCorePreferenceNames.WRAPPING_PROHIBIT_WRAP_ON_ATTR) || node.getOwnerDocument().getNodeType() != ICSSNode.STYLEDECLARATION_NODE)) {
			int n = getLastLineLength(node, source);
			int append = (toAppend != null) ? TextUtilities.indexOf(DefaultLineTracker.DELIMITERS, toAppend, 0)[0] : 0;
			if (toAppend != null)
				append = (append < 0) ? toAppend.length() : append;
			if (n + append + 1 > preferences.getInt(CSSCorePreferenceNames.LINE_WIDTH)) {
				source.append(getLineDelimiter(node));
				source.append(getIndent(node));
				source.append(getIndentString());
				return;
			}
		}
		source.append(" ");//$NON-NLS-1$
	}

	/**
	 * 
	 */
	public final StringBuffer cleanup(ICSSNode node) {
		short oldStrategy = strategy;
		strategy = CLEANUP;
		StringBuffer source = formatProc(node);
		strategy = oldStrategy;

		return source;
	}

	/**
	 * 
	 */
	public final StringBuffer cleanup(ICSSNode node, IRegion region) {
		short oldStrategy = strategy;
		strategy = CLEANUP;
		StringBuffer source = formatProc(node, region);
		strategy = oldStrategy;

		return source;
	}

	/**
	 * 
	 */
	protected String decoratedIdentRegion(CompoundRegion region, CSSCleanupStrategy stgy) {
		if (isFormat())
			return region.getText();

		String text = region.getText();
		if (region.getType() == CSSRegionContexts.CSS_STRING || region.getType() == CSSRegionContexts.CSS_URI)
			return decoratedRegion(region, 0, stgy);

		if (isCleanup()) {
			if (stgy.getIdentCase() == CSSCleanupStrategy.ASIS || region.getType() == CSSRegionContexts.CSS_COMMENT)
				return text;
			else if (stgy.getIdentCase() == CSSCleanupStrategy.UPPER)
				return text.toUpperCase();
			else
				return text.toLowerCase();
		}

		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();
		if (region.getType() == CSSRegionContexts.CSS_COMMENT)
			return text;
		else if (preferences.getInt(CSSCorePreferenceNames.CASE_IDENTIFIER) == CSSCorePreferenceNames.UPPER)
			return text.toUpperCase();
		else
			return text.toLowerCase();
	}

	/**
	 * 
	 */
	protected String decoratedPropNameRegion(CompoundRegion region, CSSCleanupStrategy stgy) {
		if (isFormat())
			return region.getText();

		String text = region.getText();
		if (region.getType() == CSSRegionContexts.CSS_STRING || region.getType() == CSSRegionContexts.CSS_URI)
			return decoratedRegion(region, 1, stgy);
		if (isCleanup()) {
			if (stgy.getPropNameCase() == CSSCleanupStrategy.ASIS || region.getType() != CSSRegionContexts.CSS_DECLARATION_PROPERTY)
				return text;
			else if (stgy.getPropNameCase() == CSSCleanupStrategy.UPPER)
				return text.toUpperCase();
			else
				return text.toLowerCase();
		}
		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();

		if (region.getType() != CSSRegionContexts.CSS_DECLARATION_PROPERTY)
			return text;
		else if (preferences.getInt(CSSCorePreferenceNames.CASE_PROPERTY_NAME) == CSSCorePreferenceNames.UPPER)
			return text.toUpperCase();
		else
			return text.toLowerCase();
	}

	/**
	 * 
	 */
	protected String decoratedPropValueRegion(CompoundRegion region, CSSCleanupStrategy stgy) {
		if (isFormat())
			return region.getText();

		String text = region.getText();
		String type = region.getType();
		if (type == CSSRegionContexts.CSS_STRING || type == CSSRegionContexts.CSS_URI || type == CSSRegionContexts.CSS_DECLARATION_VALUE_URI)
			return decoratedRegion(region, 2, stgy);
		if (isCleanup()) {
			if (stgy.getPropValueCase() != CSSCleanupStrategy.ASIS) {
				if (type == CSSRegionContexts.CSS_COMMENT) {
				}
				else {
					if (stgy.getPropValueCase() == CSSCleanupStrategy.UPPER)
						text = text.toUpperCase();
					else
						text = text.toLowerCase();
				}
			}
		}
		return text;
	}

	/**
	 * 
	 */
	protected String decoratedRegion(CompoundRegion region, int type, CSSCleanupStrategy stgy) {
		if (isFormat())
			return region.getText();

		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();
		String text = region.getText();
		String regionType = region.getType();
		if (regionType == CSSRegionContexts.CSS_URI || regionType == CSSRegionContexts.CSS_DECLARATION_VALUE_URI) {
			String uri = CSSLinkConverter.stripFunc(text);

			boolean prefIsUpper = preferences.getInt(CSSCorePreferenceNames.CASE_IDENTIFIER) == CSSCorePreferenceNames.UPPER;
			boolean upper = (type == 0) ? prefIsUpper : ((type == 1) ? preferences.getInt(CSSCorePreferenceNames.CASE_PROPERTY_NAME) == CSSCorePreferenceNames.UPPER : preferences.getInt(CSSCorePreferenceNames.CASE_PROPERTY_VALUE) == CSSCorePreferenceNames.UPPER);
			String func = text.substring(0, 4);
			if (isCleanup()) {
				upper = ((type == 0) ? stgy.getIdentCase() : ((type == 1) ? stgy.getPropNameCase() : stgy.getPropValueCase())) == CSSCleanupStrategy.UPPER;
				func = ((type == 0) ? stgy.getIdentCase() : ((type == 1) ? stgy.getPropNameCase() : stgy.getPropValueCase())) == CSSCleanupStrategy.ASIS ? text.substring(0, 4) : (upper ? "URL(" : "url(");//$NON-NLS-2$//$NON-NLS-1$
			}
			if ((!isCleanup() && preferences.getBoolean(CSSCorePreferenceNames.FORMAT_QUOTE_IN_URI)) || (isCleanup() && stgy.isQuoteValues())) {
				String quote = preferences.getString(CSSCorePreferenceNames.FORMAT_QUOTE);
				quote = CSSUtil.detectQuote(uri, quote);
				text = func + quote + uri + quote + ")";//$NON-NLS-1$
			}
			else if (isCleanup() && !stgy.isQuoteValues()) {
				text = func + CSSLinkConverter.removeFunc(text) + ")";//$NON-NLS-1$
			}
			else {
				text = func + uri + ")";//$NON-NLS-1$
			}
		}
		else if (region.getType() == CSSRegionContexts.CSS_STRING && (!isCleanup() || stgy.isQuoteValues())) {
			String quote = preferences.getString(CSSCorePreferenceNames.FORMAT_QUOTE);
			// begginning
			if (!text.startsWith(quote)) {
				if (text.startsWith("\"") || text.startsWith("\'")) //$NON-NLS-1$ //$NON-NLS-2$
					text = quote + text.substring(1);
				else
					text = quote + text;
			}
			// ending
			if (!text.endsWith(quote)) {
				if (text.endsWith("\"") || text.endsWith("\'")) //$NON-NLS-1$ //$NON-NLS-2$
					text = text.substring(0, text.length() - 1) + quote;
				else
					text = text + quote;
			}
		}
		return text;
	}

	/**
	 * 
	 */
	public final StringBuffer format(ICSSNode node) {
		short oldStrategy = strategy;
		strategy = FORMAT;
		StringBuffer source = formatProc(node);
		strategy = oldStrategy;

		return source;
	}

	/**
	 * 
	 */
	public final StringBuffer format(ICSSNode node, IRegion region) {
		short oldStrategy = strategy;
		strategy = FORMAT;
		StringBuffer source = formatProc(node, region);
		strategy = oldStrategy;

		return source;
	}

	/**
	 * 
	 */
	public StringBuffer formatAttrChanged(ICSSNode node, ICSSAttr attr, boolean insert, AttrChangeContext context) {
		return new StringBuffer(insert && (attr != null) ? attr.getValue() : "");//$NON-NLS-1$
	}

	/**
	 * Generate or format source between children('child' and its previous
	 * sibling) and append to string buffer
	 */
	abstract protected void formatBefore(ICSSNode node, ICSSNode child, String toAppend, StringBuffer source, IRegion exceptFor);

	/**
	 * Generate or format source between children('child' and its previous
	 * sibling) and append to string buffer
	 */
	public final StringBuffer formatBefore(ICSSNode node, ICSSNode child, IRegion exceptFor) {
		Assert.isTrue(child == null || child.getParentNode() == node);
		StringBuffer buf = new StringBuffer();
		formatBefore(node, child, /* (child != null) ? (child.getCssText()) : */"", buf, exceptFor);//$NON-NLS-1$
		return buf;
	}

	/**
	 * Generate or format source between children('child' and its previous
	 * sibling) and append to string buffer
	 */
	protected abstract void formatBefore(ICSSNode node, ICSSNode child, IRegion region, String toAppend, StringBuffer source);

	/**
	 * 
	 */
	protected final void formatChildren(ICSSNode node, StringBuffer source) {
		ICSSNode child = node.getFirstChild();
		boolean first = true;
		while (child != null) {
			// append child
			CSSSourceFormatter formatter = (CSSSourceFormatter) ((INodeNotifier) child).getAdapterFor(CSSSourceFormatter.class);
			if (formatter == null) {
				formatter = CSSSourceFormatterFactory.getInstance().getSourceFormatter((INodeNotifier) child);
			}
			StringBuffer childSource = ((AbstractCSSSourceFormatter) formatter).formatProc(child);
			if (!first) {
				formatBefore(node, child, new String(childSource), source, null);
			}
			source.append(childSource);
			// append between children
			child = child.getNextSibling();
			first = false;
		}
	}

	/**
	 * 
	 */
	protected final void formatChildren(ICSSNode node, IRegion region, StringBuffer source) {
		ICSSNode child = node.getFirstChild();
		int start = region.getOffset();
		int end = region.getOffset() + region.getLength();
		boolean first = true;
		while (child != null) {
			int curEnd = ((IndexedRegion) child).getEndOffset();
			StringBuffer childSource = null;
			boolean toFinish = false;
			if (start < curEnd) {
				int curStart = ((IndexedRegion) child).getStartOffset();
				if (curStart < end) {
					// append child
					CSSSourceFormatter formatter = (CSSSourceFormatter) ((INodeNotifier) child).getAdapterFor(CSSSourceFormatter.class);
					if (formatter == null) {
						formatter = CSSSourceFormatterFactory.getInstance().getSourceFormatter((INodeNotifier) child);
					}
					if (includes(region, curStart, curEnd))
						childSource = ((AbstractCSSSourceFormatter) formatter).formatProc(child);
					else
						childSource = ((AbstractCSSSourceFormatter) formatter).formatProc(child, overlappedRegion(region, curStart, curEnd));
				}
				else
					toFinish = true;
			}
			// append between children
			if (!first) {
				curEnd = ((IndexedRegion) child).getStartOffset(); // change
				// only
				// start
				if (start < curEnd) {
					int curStart = ((IndexedRegion) child.getPreviousSibling()).getEndOffset();
					if (curStart < end) {
						String toAppend = (childSource != null) ? new String(childSource) : "";//$NON-NLS-1$
						if (includes(region, curStart, curEnd))
							formatBefore(node, child, toAppend, source, null);
						else
							formatBefore(node, child, overlappedRegion(region, curStart, curEnd), toAppend, source);
					}
				}
			}
			if (childSource != null) {
				source.append(childSource);
			}
			first = false;
			if (toFinish)
				break;
			child = child.getNextSibling();
		}
	}

	/**
	 * Generate or format source after the last child and append to string
	 * buffer
	 */
	protected abstract void formatPost(ICSSNode node, StringBuffer source);

	/**
	 * Generate or format source after the last child and append to string
	 * buffer
	 */
	protected abstract void formatPost(ICSSNode node, IRegion region, StringBuffer source);

	/**
	 * Generate or format source before the first child and append to string
	 * buffer
	 */
	protected abstract void formatPre(ICSSNode node, StringBuffer source);

	/**
	 * Generate or format source before the first child and append to string
	 * buffer
	 */
	abstract protected void formatPre(ICSSNode node, IRegion region, StringBuffer source);

	/**
	 * 
	 * @return java.lang.StringBuffer
	 * @param node
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSNode
	 */
	protected final StringBuffer formatProc(ICSSNode node) {
		StringBuffer source = new StringBuffer();
		formatPre(node, source);
		formatChildren(node, source);
		formatPost(node, source);
		return source;
	}

	/**
	 * 
	 * @return java.lang.StringBuffer
	 * @param node
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSNode
	 * @param region
	 *            org.eclipse.jface.text.IRegion
	 */
	protected final StringBuffer formatProc(ICSSNode node, IRegion region) {
		StringBuffer source = new StringBuffer();
		int curStart = ((IndexedRegion) node).getStartOffset();
		int curEnd = ((IndexedRegion) node).getEndOffset();
		if (node.getChildNodes().getLength() > 0) {
			curEnd = ((IndexedRegion) node.getFirstChild()).getStartOffset();
			if (overlaps(region, curStart, curEnd)) {
				if (includes(region, curStart, curEnd))
					formatPre(node, source);
				else
					formatPre(node, overlappedRegion(region, curStart, curEnd), source);
			}
			curStart = curEnd;
			curEnd = ((IndexedRegion) node.getLastChild()).getEndOffset();
			if (overlaps(region, curStart, curEnd)) {
				if (includes(region, curStart, curEnd))
					formatChildren(node, source);
				else
					formatChildren(node, overlappedRegion(region, curStart, curEnd), source);
			}
			curStart = curEnd;
			curEnd = ((IndexedRegion) node).getEndOffset();
			if (overlaps(region, curStart, curEnd)) {
				if (includes(region, curStart, curEnd))
					formatPost(node, source);
				else
					formatPost(node, overlappedRegion(region, curStart, curEnd), source);
			}
		}
		else {
			curEnd = getChildInsertPos(node);
			if (overlaps(region, curStart, curEnd)) {
				if (includes(region, curStart, curEnd))
					formatPre(node, source);
				else
					formatPre(node, overlappedRegion(region, curStart, curEnd), source);
			}
			curStart = curEnd;
			curEnd = ((IndexedRegion) node).getEndOffset();
			if (overlaps(region, curStart, curEnd)) {
				if (includes(region, curStart, curEnd))
					formatPost(node, source);
				else
					formatPost(node, overlappedRegion(region, curStart, curEnd), source);
			}
		}
		return source;
	}

	/**
	 * 
	 */
	public int getAttrInsertPos(ICSSNode node, String attrName) {
		return -1;
	}

	/**
	 * Insert the method's description here.
	 * 
	 * @return org.eclipse.wst.css.core.internal.cleanup.CSSCleanupStrategy
	 * @param node
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSNode
	 */
	protected CSSCleanupStrategy getCleanupStrategy(ICSSNode node) {
		CSSCleanupStrategy currentStrategy = CSSCleanupStrategyImpl.getInstance();
		ICSSDocument doc = node.getOwnerDocument();
		if (doc == null)
			return currentStrategy;
		ICSSModel model = doc.getModel();
		if (model == null)
			return currentStrategy;
		if (model.getStyleSheetType() != ICSSModel.EXTERNAL) {
			// TODO - TRANSITION Nakamori-san, or Kit, how can we move to
			// "HTML" plugin?
			// can we subclass?
			// currentStrategy = CSSInHTMLCleanupStrategyImpl.getInstance();
		}
		return currentStrategy;
	}

	/**
	 * 
	 */
	protected String getIndent(ICSSNode node) {
		if (node == null)
			return "";//$NON-NLS-1$
		ICSSNode parent = node.getParentNode();
		if (node instanceof ICSSAttr)
			parent = ((ICSSAttr) node).getOwnerCSSNode();
		if (parent == null)
			return "";//$NON-NLS-1$
		if (node instanceof org.w3c.dom.css.CSSStyleDeclaration)
			parent = parent.getParentNode();
		if (parent == null)
			return "";//$NON-NLS-1$

		String parentIndent = getIndent(parent);
		if (parent instanceof org.w3c.dom.css.CSSRule)
			return parentIndent + getIndentString();
		if (node.getParentNode() instanceof ICSSStyleDeclaration)
			return parentIndent + getIndentString();
		return parentIndent;
	}

	/**
	 * 
	 */
	protected int getLastLineLength(ICSSNode node, StringBuffer source) {
		if (node == null || source == null)
			return 0;
		String delim = getLineDelimiter(node);
		String str = new String(source);
		int n = str.lastIndexOf(delim);
		if (n < 0)
			return str.length();

		return str.length() - n - delim.length();
	}

	/**
	 * 
	 * @return int
	 * @param node
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSNode
	 * @param insertPos
	 *            int
	 */
	public int getLengthToReformatAfter(ICSSNode node, int insertPos) {
		if (node == null)
			return 0;
		IndexedRegion nnode = (IndexedRegion) node;
		if (insertPos < 0 || !nnode.contains(insertPos))
			return 0;

		IStructuredDocumentRegion flatNode = node.getOwnerDocument().getModel().getStructuredDocument().getRegionAtCharacterOffset(insertPos);
		if (flatNode == null)
			return 0;
		ITextRegion region = flatNode.getRegionAtCharacterOffset(insertPos);
		if (region == null)
			return 0;
		RegionIterator it = new RegionIterator(flatNode, region);
		boolean found = false;
		while (it.hasNext()) {
			region = it.next();
			// if (region.getType() != CSSRegionContexts.CSS_S &&
			// region.getType() != CSSRegionContexts.CSS_DELIMITER &&
			// region.getType() !=
			// CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
			if (region.getType() != CSSRegionContexts.CSS_S) {
				found = true;
				break;
			}
		}
		int pos = (found ? it.getStructuredDocumentRegion().getStartOffset(region) : it.getStructuredDocumentRegion().getTextEndOffset(region)) - insertPos;
		return (pos >= 0) ? pos : 0;
	}

	/**
	 * 
	 * @return int
	 * @param node
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSNode
	 * @param insertPos
	 *            int
	 */
	public int getLengthToReformatBefore(ICSSNode node, int insertPos) {
		if (node == null)
			return 0;
		IndexedRegion nnode = (IndexedRegion) node;
		if (insertPos <= 0 || !nnode.contains(insertPos - 1))
			return 0;

		IStructuredDocumentRegion flatNode = node.getOwnerDocument().getModel().getStructuredDocument().getRegionAtCharacterOffset(insertPos - 1);
		if (flatNode == null)
			return 0;
		ITextRegion region = flatNode.getRegionAtCharacterOffset(insertPos - 1);
		if (region == null)
			return 0;
		RegionIterator it = new RegionIterator(flatNode, region);
		boolean found = false;
		while (it.hasPrev()) {
			region = it.prev();
			// if (region.getType() != CSSRegionContexts.CSS_S &&
			// region.getType() != CSSRegionContexts.CSS_DELIMITER &&
			// region.getType() !=
			// CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
			if (region.getType() != CSSRegionContexts.CSS_S) {
				found = true;
				break;
			}
		}
		int pos = insertPos - (found ? it.getStructuredDocumentRegion().getTextEndOffset(region) : it.getStructuredDocumentRegion().getStartOffset(region));
		// flatNode = it.getStructuredDocumentRegion();
		// if (found) {
		// if (region.getLength() != region.getTextLength()) {
		// pos = insertPos - flatNode.getTextEndOffset(region);
		// } else {
		// pos = insertPos - flatNode.getEndOffset(region);
		// }
		// } else {
		// pos = insertPos - flatNode.getStartOffset(region);
		// }
		return (pos >= 0) ? pos : 0;
	}

	/**
	 * 
	 */
	String getLineDelimiter(ICSSNode node) {
		ICSSModel model = (node != null) ? node.getOwnerDocument().getModel() : null;
		return (model != null) ? model.getStructuredDocument().getLineDelimiter() : "\n"; //$NON-NLS-1$

		// TODO : check whether to use model.getLineDelimiter() or
		// model.getStructuredDocument().getLineDelimiter()
	}

	/**
	 * 
	 */
	protected CompoundRegion[] getOutsideRegions(IStructuredDocument model, IRegion reg) {
		CompoundRegion[] ret = new CompoundRegion[2];
		RegionIterator it = new RegionIterator(model, reg.getOffset());
		it.prev();
		if (it.hasPrev()) {
			ITextRegion textRegion = it.prev();
			IStructuredDocumentRegion documentRegion = it.getStructuredDocumentRegion();
			ret[0] = new CompoundRegion(documentRegion, textRegion);
		}
		else {
			ret[0] = null;
		}
		it.reset(model, reg.getOffset() + reg.getLength());
		if (it.hasNext()) {
			ITextRegion textRegion = it.next();
			IStructuredDocumentRegion documentRegion = it.getStructuredDocumentRegion();
			ret[1] = new CompoundRegion(documentRegion, textRegion);
		}
		else {
			ret[1] = null;
		}
		return ret;
	}

	/**
	 */
	protected CSSSourceGenerator getParentFormatter(ICSSNode node) {
		ICSSNode parent = node.getParentNode();
		if (parent != null) {
			CSSSourceGenerator formatter = (CSSSourceGenerator) ((INodeNotifier) parent).getAdapterFor(CSSSourceFormatter.class);
			if (formatter == null) {
				formatter = CSSSourceFormatterFactory.getInstance().getSourceFormatter((INodeNotifier) parent);
			}
			return formatter;
		}
		return null;
	}

	/**
	 * 
	 */
	protected CompoundRegion[] getRegions(IStructuredDocument model, IRegion reg, IRegion exceptFor, String pickupType) {
		int start = reg.getOffset();
		int end = reg.getOffset() + reg.getLength();
		int startE = (exceptFor != null) ? exceptFor.getOffset() : -1;
		int endE = (exceptFor != null) ? exceptFor.getOffset() + exceptFor.getLength() : 0;

		ArrayList list = new ArrayList();
		IStructuredDocumentRegion flatNode = model.getRegionAtCharacterOffset(start);
		boolean pickuped = false;
		while (flatNode != null && flatNode.getStartOffset() < end) {
			ITextRegionList regionList = flatNode.getRegions();
			Iterator it = regionList.iterator();
			while (it.hasNext()) {
				ITextRegion region = (ITextRegion) it.next();
				if (flatNode.getStartOffset(region) < start)
					continue;
				if (end <= flatNode.getStartOffset(region))
					break;
				if (startE >= 0 && startE <= flatNode.getStartOffset(region) && flatNode.getEndOffset(region) <= endE)
					continue;
				if (region.getType() == CSSRegionContexts.CSS_COMMENT || region.getType() == CSSRegionContexts.CSS_CDC || region.getType() == CSSRegionContexts.CSS_CDO)
					list.add(new CompoundRegion(flatNode, region));
				else if (!pickuped && region.getType() == pickupType) {
					list.add(new CompoundRegion(flatNode, region));
					pickuped = true;
				}
			}
			flatNode = flatNode.getNext();
		}
		if (list.size() > 0) {
			CompoundRegion[] regions = new CompoundRegion[list.size()];
			list.toArray(regions);
			return regions;
		}
		return new CompoundRegion[0];
	}

	/**
	 * 
	 */
	protected CompoundRegion[] getRegionsWithoutWhiteSpaces(IStructuredDocument model, IRegion reg, CSSCleanupStrategy stgy) {
		int start = reg.getOffset();
		int end = reg.getOffset() + reg.getLength() - 1;
		ArrayList list = new ArrayList();
		IStructuredDocumentRegion flatNode = model.getRegionAtCharacterOffset(start);
		while (flatNode != null && flatNode.getStartOffset() <= end) {
			ITextRegionList regionList = flatNode.getRegions();
			Iterator it = regionList.iterator();
			while (it.hasNext()) {
				ITextRegion region = (ITextRegion) it.next();
				if (flatNode.getStartOffset(region) < start)
					continue;
				if (end < flatNode.getStartOffset(region))
					break;
				if (region.getType() != CSSRegionContexts.CSS_S || (isCleanup() && !stgy.isFormatSource())) // for
					// not
					// formatting
					// case
					// on
					// cleanup
					// action
					list.add(new CompoundRegion(flatNode, region));
			}
			flatNode = flatNode.getNext();
		}
		if (list.size() > 0) {
			CompoundRegion[] regions = new CompoundRegion[list.size()];
			list.toArray(regions);
			return regions;
		}
		return new CompoundRegion[0];
	}

	/**
	 * 
	 */
	public static boolean includes(IRegion region, int start, int end) {
		if (region == null)
			return false;

		return (region.getOffset() <= start) && (end <= region.getOffset() + region.getLength());
	}

	/**
	 * 
	 * @return boolean
	 */
	protected static boolean isCleanup() {
		return strategy == CLEANUP;
	}

	/**
	 * 
	 * @return boolean
	 */
	protected static boolean isFormat() {
		return strategy == FORMAT;
	}

	/**
	 * 
	 */
	protected boolean isIncludesPreEnd(ICSSNode node, IRegion region) {
		return (node.getFirstChild() != null && ((IndexedRegion) node.getFirstChild()).getStartOffset() == (region.getOffset() + region.getLength()));
	}

	/**
	 * 
	 */
	static protected boolean needS(CompoundRegion region) {
		return (region != null && region.getType() != CSSRegionContexts.CSS_S);
	}

	/**
	 * 
	 */
	public static IRegion overlappedRegion(IRegion region, int start, int end) {
		if (overlaps(region, start, end)) {
			int offset = (region.getOffset() <= start) ? start : region.getOffset();
			int length = ((end <= region.getOffset() + region.getLength()) ? end : region.getOffset() + region.getLength()) - offset;
			return new FormatRegion(offset, length);
		}
		return null;
	}

	/**
	 * 
	 */
	public static boolean overlaps(IRegion region, int start, int end) {
		if (region == null)
			return false;

		return (start < region.getOffset() + region.getLength()) && (region.getOffset() < end);
	}

	private String getIndentString() {
		StringBuffer indent = new StringBuffer();

		Preferences preferences = CSSCorePlugin.getDefault().getPluginPreferences();
		if (preferences != null) {
			char indentChar = ' ';
			String indentCharPref = preferences.getString(CSSCorePreferenceNames.INDENTATION_CHAR);
			if (CSSCorePreferenceNames.TAB.equals(indentCharPref)) {
				indentChar = '\t';
			}
			int indentationWidth = preferences.getInt(CSSCorePreferenceNames.INDENTATION_SIZE);

			for (int i = 0; i < indentationWidth; i++) {
				indent.append(indentChar);
			}
		}
		return indent.toString();
	}
}