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



import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.eclipse.wst.css.core.document.ICSSNode;
import org.eclipse.wst.css.core.document.ICSSPrimitiveValue;
import org.eclipse.wst.css.core.document.ICSSStyleDeclItem;
import org.eclipse.wst.css.core.metamodel.CSSMMDescriptor;
import org.eclipse.wst.css.core.metamodel.CSSMMFunction;
import org.eclipse.wst.css.core.metamodel.CSSMMNode;
import org.eclipse.wst.css.core.metamodel.CSSMMNumber;
import org.eclipse.wst.css.core.metamodel.CSSMMProperty;
import org.eclipse.wst.css.core.metamodel.CSSMMUnit;
import org.eclipse.wst.css.core.metamodel.util.CSSFunctionID;
import org.eclipse.wst.css.core.metamodel.util.CSSMetaModelUtil;
import org.eclipse.wst.css.core.parser.CSSRegionContexts;
import org.eclipse.wst.css.core.preferences.CSSPreferenceHelper;
import org.eclipse.wst.css.core.util.CSSUtil;
import org.eclipse.wst.css.core.util.RegionIterator;
import org.eclipse.wst.css.ui.image.CSSImageType;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.w3c.dom.css.CSSFontFaceRule;

class CSSProposalGeneratorForDeclarationValue extends CSSProposalGenerator {

	private static final String IMPORTANT = "!important"; //$NON-NLS-1$
	private boolean fUseUpperCase;
	private boolean fAppendSemiColon;

	/**
	 * CSSProposalGeneratorForDeclarationValue constructor comment.
	 * 
	 * @param context
	 *            com.ibm.sed.contentassist.old.css.CSSContentAssistContext
	 */
	CSSProposalGeneratorForDeclarationValue(CSSContentAssistContext context) {
		super(context);
		fUseUpperCase = CSSPreferenceHelper.getInstance().isPropValueUpperCase();
	}

	/**
	 *  
	 */
	private void addFunction(List candidates, CSSMMFunction prop) {
		String text = prop.toString();
		if (!isMatch(text)) {
			return;
		}

		int cursorPos = 0;
		StringBuffer buf = new StringBuffer();
		if (prop.getName().equals(CSSFunctionID.F_URI)) {
			StringAndOffset sao = generateURI();
			buf.append(sao.fString);
			cursorPos = sao.fOffset;
		} else {
			buf.append(prop.toString());
			cursorPos = buf.length();
			StringAndOffset sao = generateParenthesis();
			buf.append(sao.fString);
			cursorPos += sao.fOffset;
		}

		text = buf.toString();
		text = (fUseUpperCase) ? text.toUpperCase() : text.toLowerCase();

		CSSCACandidate item = new CSSCACandidate();
		item.setReplacementString(text);
		item.setCursorPosition(cursorPos);
		item.setDisplayString(text);
		item.setImageType(CSSImageType.VALUE_FUNCTION);
		appendSemiColon(item);
		candidates.add(item);
	}

	/**
	 *  
	 */
	private void addNumber(List candidates, CSSMMNumber prop) {
		String fullText = fContext.getTextToReplace();
		// skip number
		int unitIndex = -1;
		for (int i = 0; i < fullText.length(); i++) {
			if (Character.isDigit(fullText.charAt(i))) {
				unitIndex = i + 1;
			} else {
				break;
			}
		}

		String unitSubText = ""; //$NON-NLS-1$
		String numSubText = ""; //$NON-NLS-1$
		if (0 <= unitIndex) {
			numSubText = fullText.substring(0, unitIndex);
			if (unitIndex < fullText.length()) {
				unitSubText = fullText.substring(unitIndex);
			}
		} else {
			unitSubText = fullText;
		}

		Iterator i = prop.getDescendants();
		while (i.hasNext()) {
			CSSMMUnit unit = (CSSMMUnit) i.next();
			String unitString = unit.getUnitString();
			if ((0 < unitSubText.length() && unitString.indexOf(unitSubText) != 0) || (0 < numSubText.length() && unitString.equals("#"))) { //$NON-NLS-1$
				continue;
			}

			String text = numSubText + unitString;
			text = (fUseUpperCase) ? text.toUpperCase() : text.toLowerCase();
			CSSCACandidate item = new CSSCACandidate();
			item.setReplacementString(text);
			if (0 < numSubText.length() || text.equals("#")) { //$NON-NLS-1$
				item.setCursorPosition(text.length());
			} else {
				item.setCursorPosition(0);
			}
			item.setDisplayString(text);
			item.setImageType(CSSImageType.VALUE_NUMBER);
			appendSemiColon(item);
			candidates.add(item);
		}
	}

	/**
	 *  
	 */
	private void checkSemiColon() {
		fAppendSemiColon = false;

		ITextRegion targetRegion = fContext.getTargetRegion();
		if (targetRegion != null && targetRegion.getType() != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
			// find trailing ":" or ";"
			// if ":" before ";" is found, add ";"
			RegionIterator iterator = fContext.getRegionIterator();
			IStructuredDocumentRegion container = iterator.getStructuredDocumentRegion();
			while (iterator.hasNext()) {
				ITextRegion region = iterator.next();
				if (iterator.getStructuredDocumentRegion() != container) {
					break;
				}
				if (region.getType() == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
					fAppendSemiColon = true;
					break;
				}
			}
			if (!fAppendSemiColon) {
				// second chance:
				// leading IStructuredDocumentRegion is not ";"
				IStructuredDocumentRegion nextStructuredDocumentRegion = CSSUtil.findNextSignificantNode(container);
				if (CSSUtil.getStructuredDocumentRegionType(nextStructuredDocumentRegion) != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
					fAppendSemiColon = true;
				}
			}
		}
	}

	/**
	 *  
	 */
	private void appendSemiColon(CSSCACandidate item) {
		if (fAppendSemiColon) {
			String replacementString = item.getReplacementString();
			item.setReplacementString(replacementString + ";"); //$NON-NLS-1$
			int cursorPosition = item.getCursorPosition();
			if (replacementString.length() <= cursorPosition) {
				// cursorpos is tail of string
				cursorPosition++;
				item.setCursorPosition(cursorPosition);
			}
		}
	}

	/**
	 *  
	 */
	private void addSemiColon(List candidates) {
		ICSSNode targetNode = fContext.getTargetNode();
		if (targetNode instanceof ICSSStyleDeclItem) {
			ICSSNode firstChild = targetNode.getFirstChild();
			if (firstChild == null) {
				return;
			}
			if (firstChild instanceof IndexedRegion) {
				int startOffset = ((IndexedRegion) firstChild).getStartOffset();
				if (fContext.getCursorPos() <= startOffset) {
					return;
				}
			}
		}

		boolean bAddCloser = false;

		ITextRegion targetRegion = fContext.getTargetRegion();
		if (targetRegion != null && targetRegion.getType() != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
			// find trailing ":" or ";"
			// if ":" before ";" is found, add ";"
			RegionIterator iterator = fContext.getRegionIterator();
			IStructuredDocumentRegion container = iterator.getStructuredDocumentRegion();
			while (iterator.hasNext()) {
				ITextRegion region = iterator.next();
				if (iterator.getStructuredDocumentRegion() != container) {
					break;
				}
				if (region.getType() == CSSRegionContexts.CSS_DECLARATION_SEPARATOR) {
					bAddCloser = true;
					break;
				}
			}
			if (!bAddCloser) {
				// second chance:
				// leading IStructuredDocumentRegion is not ";"
				IStructuredDocumentRegion nextStructuredDocumentRegion = CSSUtil.findNextSignificantNode(container);
				if (CSSUtil.getStructuredDocumentRegionType(nextStructuredDocumentRegion) != CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
					bAddCloser = true;
				}
			}
		}

		if (bAddCloser) {
			CSSCACandidate item = new CSSCACandidate();
			String text = fContext.getTextToReplace() + ";";//$NON-NLS-1$
			item.setReplacementString(text);
			item.setCursorPosition(text.length());
			item.setDisplayString(";");//$NON-NLS-1$
			item.setImageType(null);
			candidates.add(item);
		}
	}

	/**
	 *  
	 */
	private void addString(List candidates, String text) {
		if (!isMatch(text)) {
			return;
		}

		text = (fUseUpperCase) ? text.toUpperCase() : text.toLowerCase();

		CSSCACandidate item = new CSSCACandidate();
		item.setReplacementString(text);
		item.setCursorPosition(text.length());
		item.setDisplayString(text);
		item.setImageType(CSSImageType.VALUE_STRING);
		appendSemiColon(item);
		candidates.add(item);
	}

	private void addImportant(List candidates) {
		ICSSNode targetNode = fContext.getTargetNode();
		while (targetNode instanceof ICSSPrimitiveValue) {
			targetNode = targetNode.getParentNode();
		}
		if (!(targetNode instanceof ICSSStyleDeclItem)) {
			return;
		}
		// 1. has no priority region
		// 2. cursor position is after of last child
		// 3. normal isMatch method
		String priority = ((ICSSStyleDeclItem) targetNode).getPriority();
		if (priority == null || priority.length() == 0) {
			ICSSNode lastChild = targetNode.getLastChild();
			if (lastChild instanceof IndexedRegion) {
				int startOffset = ((IndexedRegion) lastChild).getStartOffset();
				//	int endOffset = ((IndexedRegion)lastChild).getEndOffset();
				if (startOffset < fContext.getCursorPos() && isMatch(IMPORTANT)) {
					CSSCACandidate item = new CSSCACandidate();
					item.setReplacementString(IMPORTANT);
					item.setCursorPosition(IMPORTANT.length());
					item.setDisplayString(IMPORTANT);
					item.setImageType(CSSImageType.VALUE_STRING);
					appendSemiColon(item);
					candidates.add(item);
				}
			}
		}
	}

	/**
	 * getCandidates method comment.
	 */
	protected Iterator getCandidates() {
		List candidates = new ArrayList();

		checkSemiColon(); // check should add semi-colon or not

		String name = getPropertyName();
		if (name != null) {
			CSSMetaModelUtil util = new CSSMetaModelUtil(fContext.getMetaModel());
			Iterator i = Collections.EMPTY_LIST.iterator();
			if (isFontFaceRule()) {
				CSSMMDescriptor desc = util.getDescriptor(name);
				if (desc != null) {
					i = desc.getValues();
				}
			} else {
				CSSMMProperty prop = util.getProperty(name);
				if (prop != null) {
					i = prop.getValues();
				}
			}
			while (i.hasNext()) {
				CSSMMNode val = (CSSMMNode) i.next();
				String valueType = val.getType();
				if (valueType == CSSMMNode.TYPE_KEYWORD) {
					addString(candidates, val.toString());
				} else if (valueType == CSSMMNode.TYPE_NUMBER) {
					addNumber(candidates, (CSSMMNumber) val);
				} else if (valueType == CSSMMNode.TYPE_FUNCTION) {
					addFunction(candidates, (CSSMMFunction) val);
				}
			}
		}

		addImportant(candidates);
		addSemiColon(candidates);

		return candidates.iterator();
	}

	/**
	 * @return java.lang.String
	 */
	private String getPropertyName() {
		ICSSNode targetNode = fContext.getTargetNode();
		while (targetNode instanceof ICSSPrimitiveValue) {
			targetNode = targetNode.getParentNode();
		}
		if (targetNode instanceof ICSSStyleDeclItem) {
			return ((ICSSStyleDeclItem) targetNode).getPropertyName();
		} else {
			return null;
		}
	}

	/**
	 *  
	 */
	private boolean isFontFaceRule() {
		ICSSNode targetNode = fContext.getTargetNode();
		while (targetNode instanceof ICSSPrimitiveValue) {
			targetNode = targetNode.getParentNode();
		}
		if (targetNode instanceof ICSSStyleDeclItem) {
			targetNode = targetNode.getParentNode(); // get Declaration
			if (targetNode != null) {
				// inline style has no rule node
				targetNode = targetNode.getParentNode(); // get rule
			}
		}
		return (targetNode instanceof CSSFontFaceRule);
	}
}