/*******************************************************************************
 * 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.css.core.internal.formatter;



import org.eclipse.jface.text.IRegion;
import org.eclipse.wst.css.core.internal.cleanup.CSSCleanupStrategy;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSAttr;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
import org.eclipse.wst.css.core.internal.provisional.document.ICounter;
import org.eclipse.wst.css.core.internal.util.CSSUtil;
import org.eclipse.wst.css.core.internal.util.RegionIterator;
import org.eclipse.wst.css.core.preferences.CSSPreferenceHelper;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;


/**
 * 
 */
public class CounterFormatter extends DefaultCSSSourceFormatter {

	private static CounterFormatter instance;

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

	/**
	 * 
	 */
	public StringBuffer formatAttrChanged(ICSSNode node, ICSSAttr attr, boolean insert, AttrChangeContext context) {
		StringBuffer source = new StringBuffer();
		if (node == null || attr == null)
			return source;

		if (!ICounter.IDENTIFIER.equalsIgnoreCase(attr.getName()) && !ICounter.LISTSTYLE.equalsIgnoreCase(attr.getName()) && !ICounter.SEPARATOR.equalsIgnoreCase(attr.getName()))
			return source;

		// get region to replace
		IndexedRegion iNode = (IndexedRegion) node;
		context.start = iNode.getStartOffset();
		context.end = iNode.getEndOffset();

		CSSPreferenceHelper mgr = CSSPreferenceHelper.getInstance();

		ICounter counter = (ICounter) node;
		String quote = mgr.getQuoteString(node.getOwnerDocument().getModel());
		String sep = counter.getSeparator();
		String ident = counter.getIdentifier();
		String style = counter.getListStyle();

		if (ICounter.IDENTIFIER.equalsIgnoreCase(attr.getName())) {
			if (insert)
				ident = attr.getValue();
			else
				ident = "";//$NON-NLS-1$
		}
		else if (ICounter.LISTSTYLE.equalsIgnoreCase(attr.getName())) {
			if (insert)
				style = attr.getValue();
			else
				style = null;
		}
		else if (ICounter.SEPARATOR.equalsIgnoreCase(attr.getName())) {
			if (insert)
				sep = attr.getValue();
			else
				sep = null;
		}

		quote = CSSUtil.detectQuote(sep, quote);
		sep = (sep == null || sep.length() == 0) ? null : (quote + sep + quote);

		String func = (sep == null || sep.length() == 0) ? "counter(" : "counters(";//$NON-NLS-2$//$NON-NLS-1$
		if (mgr.isPropValueUpperCase()) {
			ident = ident.toUpperCase();
			style = style.toUpperCase();
			func = func.toUpperCase();
		}
		else {
			ident = ident.toLowerCase();
			style = style.toLowerCase();
		}
		if (sep == null || sep.length() == 0) {
			source.append(func);
			appendSpaceBefore(node, ident, source);
			source.append(ident);
		}
		else {
			source.append(func);
			appendSpaceBefore(node, ident, source);
			source.append(ident);
			source.append(",");//$NON-NLS-1$
			appendSpaceBefore(node, sep, source);
			source.append(sep);
		}

		if (style != null && style.length() != 0) {
			source.append(",");//$NON-NLS-1$
			appendSpaceBefore(node, style, source);
		}
		source.append(")");//$NON-NLS-1$

		/*
		 * IStructuredDocument structuredDocument =
		 * node.getOwnerDocument().getModel().getStructuredDocument();
		 * ITextRegion[] regions =
		 * getRegionsWithoutWhiteSpaces(structuredDocument, new
		 * FormatRegion(context.start, context.end - context.start + 1)); int
		 * commas[2]; int numComma = 0; for(int j = 0; j <regions.length; j++) {
		 * if (regions[j].getType() == CSSRegionContexts.COMMA) {
		 * commas[numComma++] = j; if (numComma > 1) break; } }
		 * 
		 * if (ICounter.IDENTIFIER.equalsIgnoreCase(attr.getName())) { } else
		 * if (ICounter.LISTSTYLE.equalsIgnoreCase(attr.getName())) { } else
		 * if (ICounter.SEPARATOR.equalsIgnoreCase(attr.getName())) { boolean
		 * skipSpace = false; String func = insert ? "counters(" : "counter(";
		 * if (mgr.isPropValueUpperCase()) func = func.toUpperCase();
		 * 
		 * for(int i=0; i <regions.length; i++) { if (regions[i].getType() ==
		 * CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION)
		 * source.append(func); else { if (numComma == 2 && commas[1] < i) {
		 *  } else if (numComma == 1 && commas[0] < i && insert) {
		 *  } else if (numComma == 1 && commas[0] < i && ! insert) { } else if
		 * (numComma == 0 && insert && regions[i].getType ==
		 * CSSRegionContexts.PARENTHESIS_CLOSE) { source.append(",");
		 * appendSpaceBefore(node,attr.getValue(),source);
		 * source.append(attr.getValue()); }
		 * 
		 * if (i != 0 && !skipSpace)
		 * appendSpaceBefore(node,regions[i],source);
		 * source.append(decoratedPropValueRegion(regions[i])); } skipSpace =
		 * false;
		 * 
		 * if (regions[i].getType() ==
		 * CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION) skipSpace = true; } }
		 */
		return source;
	}

	/**
	 * 
	 */
	protected void formatPre(ICSSNode node, StringBuffer source) {
		int start = ((IndexedRegion) node).getStartOffset();
		int end = ((IndexedRegion) node).getEndOffset();
		CSSPreferenceHelper mgr = CSSPreferenceHelper.getInstance();
		CSSCleanupStrategy stgy = getCleanupStrategy(node);

		if (end > 0) { // format source
			IStructuredDocument structuredDocument = node.getOwnerDocument().getModel().getStructuredDocument();
			CompoundRegion[] regions = getRegionsWithoutWhiteSpaces(structuredDocument, new FormatRegion(start, end - start), stgy);
			boolean skipSpace = false;
			for (int i = 0; i < regions.length; i++) {
				if (i != 0 && !skipSpace)
					appendSpaceBefore(node, regions[i], source);
				skipSpace = false;
				source.append(decoratedPropValueRegion(regions[i], stgy));
				if (regions[i].getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION)
					skipSpace = true;
			}
		}
		else { // generate source
			ICounter counter = (ICounter) node;
			String quote = mgr.getQuoteString(node.getOwnerDocument().getModel());
			String separator = counter.getSeparator();
			quote = CSSUtil.detectQuote(separator, quote);
			String sep = (separator == null || separator.length() == 0) ? null : (quote + separator + quote);
			String ident = counter.getIdentifier();
			String style = counter.getListStyle();
			String func = (sep == null || sep.length() == 0) ? "counter(" : "counters(";//$NON-NLS-2$//$NON-NLS-1$
			// normalize
			if (ident == null)
				ident = "";//$NON-NLS-1$
			if (style == null)
				style = "";//$NON-NLS-1$

			if (mgr.isPropValueUpperCase()) {
				ident = ident.toUpperCase();
				style = style.toUpperCase();
				func = func.toUpperCase();
			}
			else {
				ident = ident.toLowerCase();
				style = style.toLowerCase();
			}
			if (sep == null || sep.length() == 0) {
				source.append(func);
				appendSpaceBefore(node, ident, source);
				source.append(ident);
			}
			else {
				source.append(func);
				appendSpaceBefore(node, ident, source);
				source.append(ident);
				source.append(",");//$NON-NLS-1$
				appendSpaceBefore(node, sep, source);
				source.append(sep);
			}

			if (style != null && style.length() != 0) {
				source.append(",");//$NON-NLS-1$
				appendSpaceBefore(node, style, source);
			}
			source.append(")");//$NON-NLS-1$
		}
	}

	/**
	 * 
	 */
	protected void formatPre(ICSSNode node, IRegion region, StringBuffer source) {
		IStructuredDocument structuredDocument = node.getOwnerDocument().getModel().getStructuredDocument();
		CSSCleanupStrategy stgy = getCleanupStrategy(node);

		CompoundRegion[] regions = getRegionsWithoutWhiteSpaces(structuredDocument, region, stgy);
		CompoundRegion[] outside = getOutsideRegions(structuredDocument, region);
		for (int i = 0; i < regions.length; i++) {
			if (i != 0 || needS(outside[0]))
				appendSpaceBefore(node, regions[i], source);
			source.append(decoratedPropValueRegion(regions[i], stgy));
		}
		if (needS(outside[1]) && !isIncludesPreEnd(node, region))
			appendSpaceBefore(node, outside[1], source);
	}

	/**
	 * 
	 */
	public int getAttrInsertPos(ICSSNode node, String attrName) {
		if (node == null || attrName == null || attrName.length() == 0)
			return -1;

		IndexedRegion iNode = (IndexedRegion) node;
		if (ICounter.IDENTIFIER.equalsIgnoreCase(attrName)) {
			ICSSAttr attr = (ICSSAttr) node.getAttributes().getNamedItem(ICounter.IDENTIFIER);
			if (attr != null && ((IndexedRegion) attr).getEndOffset() > 0)
				return ((IndexedRegion) attr).getStartOffset();
			if (iNode.getEndOffset() <= 0)
				return -1;

			IStructuredDocumentRegion flatNode = node.getOwnerDocument().getModel().getStructuredDocument().getRegionAtCharacterOffset(iNode.getEndOffset() - 1);
			RegionIterator it = new RegionIterator(flatNode, flatNode.getRegionAtCharacterOffset(iNode.getEndOffset() - 1));
			while (it.hasPrev()) {
				ITextRegion region = it.prev();
				if (region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION)
					return it.getStructuredDocumentRegion().getEndOffset(region);
			}
			return ((IndexedRegion) node).getEndOffset();
		}
		else if (ICounter.LISTSTYLE.equalsIgnoreCase(attrName)) {
			ICSSAttr attr = (ICSSAttr) node.getAttributes().getNamedItem(ICounter.LISTSTYLE);
			if (attr != null && ((IndexedRegion) attr).getEndOffset() > 0)
				return ((IndexedRegion) attr).getStartOffset();

			IStructuredDocumentRegion flatNode = node.getOwnerDocument().getModel().getStructuredDocument().getRegionAtCharacterOffset(iNode.getEndOffset() - 1);
			RegionIterator it = new RegionIterator(flatNode, flatNode.getRegionAtCharacterOffset(iNode.getEndOffset() - 1));
			while (it.hasPrev()) {
				ITextRegion region = it.prev();
				if (region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR)
					return it.getStructuredDocumentRegion().getEndOffset(region);
				else if (region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION)
					return it.getStructuredDocumentRegion().getEndOffset(region);
			}
			return ((IndexedRegion) node).getEndOffset();
		}
		else if (ICounter.SEPARATOR.equalsIgnoreCase(attrName)) {
			ICSSAttr attr = (ICSSAttr) node.getAttributes().getNamedItem(ICounter.SEPARATOR);
			if (attr != null && ((IndexedRegion) attr).getEndOffset() > 0)
				return ((IndexedRegion) attr).getStartOffset();

			IStructuredDocumentRegion flatNode = node.getOwnerDocument().getModel().getStructuredDocument().getRegionAtCharacterOffset(iNode.getEndOffset() - 1);
			RegionIterator it = new RegionIterator(flatNode, flatNode.getRegionAtCharacterOffset(iNode.getEndOffset() - 1));
			boolean hasComma = false;
			while (it.hasPrev()) {
				ITextRegion region = it.prev();
				if (region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR) {
					if (!hasComma)
						hasComma = true;
					else
						return it.getStructuredDocumentRegion().getEndOffset(region);
				}
				else if (region.getType() == CSSRegionContexts.CSS_DECLARATION_VALUE_FUNCTION)
					return it.getStructuredDocumentRegion().getEndOffset(region);
			}
			return ((IndexedRegion) node).getEndOffset();
		}
		else
			return -1;
	}

	/**
	 * 
	 */
	public synchronized static CounterFormatter getInstance() {
		if (instance == null)
			instance = new CounterFormatter();
		return instance;
	}
}