/*******************************************************************************
 * 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 = null;
		if (!stgy.isFormatSource())
			text = region.getFullText();
		else
			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 = null;
		if (!stgy.isFormatSource())
			text = region.getFullText();
		else
			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 = null;
		if (!stgy.isFormatSource())
			text = region.getFullText();
		else
			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 = null;
		if (!stgy.isFormatSource())
			text = region.getFullText();
		else
			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();
	}
}