/*******************************************************************************
 * Copyright (c) 2004, 2011 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.internal.contentassist;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.wst.css.core.internal.metamodel.CSSMetaModel;
import org.eclipse.wst.css.core.internal.metamodel.util.CSSMetaModelFinder;
import org.eclipse.wst.css.core.internal.parserz.CSSRegionContexts;
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.util.CSSUtil;
import org.eclipse.wst.css.core.internal.util.RegionIterator;
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;

class CSSContentAssistContext {

	private int fReplaceBegin = -1;
	private String fTextToReplace = null;
	private String fTextToCompare = null;
	private int fTargetPos = -1;
	private ICSSNode fTargetNode = null;
	private int fCursorPos = -1;
	private int fLength = -1;
	private IStructuredDocument fStructuredDocument = null;
	private int fDocumentOffset = 0;
	private char fQuote = 0;
	private ICSSModel fModel = null;
	private boolean fSelected = false;

	/**
	 *  
	 */
	private CSSContentAssistContext() {
		super();
	}

	/**
	 *  
	 */
	CSSContentAssistContext(int documentPosition, ICSSNode node, int documentOffset, char quote) {
		this();
		fCursorPos = documentPosition;
		fDocumentOffset = documentOffset;
		fQuote = quote;
		initialize(node.getOwnerDocument());
	}

	CSSContentAssistContext(int documentPosition, ICSSNode node, int documentOffset, int length, char quote) {
		this();
		fCursorPos = documentPosition;
		fDocumentOffset = documentOffset;
		fQuote = quote;
		fLength = length;
		initialize(node.getOwnerDocument());
	}

	CSSContentAssistContext(int documentPosition, ICSSNode node, int documentOffset, char quote, boolean selected) {
		this();
		fCursorPos = documentPosition;
		fDocumentOffset = documentOffset;
		fQuote = quote;
		fSelected = selected;
		initialize(node.getOwnerDocument());
	}

	/**
	 * @return int
	 */
	int getCursorPos() {
		return fCursorPos;
	}

	/**
	 * @return int
	 */
	int getDocumentOffset() {
		return fDocumentOffset;
	}

	IStructuredDocument getStructuredDocument() {
		return fStructuredDocument;
	}

	ICSSModel getModel() {
		return fModel;
	}

	private ICSSNode getNodeAt(int offset) {
		return (ICSSNode) ((fModel != null) ? fModel.getIndexedRegion(offset) : null);
	}

	/**
	 * 
	 * @return char
	 */
	char getQuoteOfStyleAttribute() {
		return fQuote;
	}

	ITextRegion getRegionByOffset(int offset) {
		ITextRegion region = null;
		if (fStructuredDocument != null) {
			IStructuredDocumentRegion flatNode = fStructuredDocument.getRegionAtCharacterOffset(offset);
			if (flatNode != null) {
				//if its a quoted region and at the beginning of a node then get the node before it
				if(offset == flatNode.getStartOffset() && fQuote != 0) {
					flatNode = fStructuredDocument.getRegionAtCharacterOffset(offset-1);
				}
				
				//if its the end offset of the node then to get the region need to step back one
				if(offset == flatNode.getEndOffset()) {
					region = flatNode.getRegionAtCharacterOffset(offset-1);
				} else {
					region = flatNode.getRegionAtCharacterOffset(offset);
				}
			}
		}
		return region;
	}

	/**
	 *  
	 */
	//	String getRegionText() {
	//		ITextRegion targetRegion = getTargetRegion();
	//		if (targetRegion != null) {
	//			return targetRegion.getText();
	//		} else {
	//			return ""; //$NON-NLS-1$
	//		}
	//	}
	/**
	 *  
	 */
	int getReplaceBegin() {
		return fReplaceBegin;
	}

	ICSSNode getTargetNode() {
		return fTargetNode;
	}

	private int getTargetPos() {
		return fTargetPos;
	}

	ITextRegion getTargetRegion() {
		return getRegionByOffset(getTargetPos());
	}

	private IStructuredDocumentRegion getTargetDocumentRegion() {
		return getDocumentRegionByOffset(getTargetPos());
	}

	private IStructuredDocumentRegion getDocumentRegionByOffset(int offset) {
		return (fStructuredDocument != null) ? fStructuredDocument.getRegionAtCharacterOffset(offset) : null;
	}

	ITextRegion getTargetRegionPrevious() {
		ITextRegion previousRegion = null;
		ITextRegion targetRegion = getTargetRegion();
		RegionIterator iterator = null;
		if (targetRegion == null) {
			if (0 < fCursorPos) {
				iterator = new RegionIterator(fStructuredDocument, fCursorPos - 1);
			}
		} else {
			iterator = getRegionIterator();
			if (iterator.hasPrev()) {
				iterator.prev();
			} else {
				iterator = null;
			}
		}
		if (iterator != null) {
			while (iterator.hasPrev()) {
				ITextRegion region = iterator.prev();
				String type = region.getType();
				if (type != CSSRegionContexts.CSS_S && type != CSSRegionContexts.CSS_COMMENT && type != CSSRegionContexts.CSS_CDO && type != CSSRegionContexts.CSS_CDC) {
					previousRegion = region;
					break;
				}
			}
		}

		return previousRegion;
	}

	/**
	 * @return java.lang.String
	 */
	String getTextToCompare() {
		return fTextToCompare;
	}

	/**
	 *  
	 */
	String getTextToReplace() {
		return fTextToReplace;
	}

	/**
	 *  
	 */
	private void initialize(ICSSDocument doc) {
		if (doc == null) {
			return;
		}
		ICSSModel model = doc.getModel();
		fModel = model;
		fStructuredDocument = model.getStructuredDocument();

		initializeTargetPos();
		initializeTargetText();
		initializeTargetNode();
	}

	/**
	 *  
	 */
	private void initializeTargetNode() {
		if (fCursorPos == 0) {
			fTargetNode = fModel.getDocument();
			return;
		}

		// find edge of tree node
		ICSSNode cursorNode = getNodeAt(fCursorPos);
		if (cursorNode == null) { // end of document
			cursorNode = fModel.getDocument();
		}
		ICSSNode node = null;
		IStructuredDocumentRegion flatNode = fStructuredDocument.getRegionAtCharacterOffset(fCursorPos - 1);
		while (flatNode != null && (node = getNodeAt(flatNode.getStartOffset())) == cursorNode && ((IndexedRegion) node).getStartOffset() != flatNode.getStartOffset()) {
			flatNode = flatNode.getPrevious();
		}
		if (flatNode == null) { // top of document
			fTargetNode = (node == null) ? fModel.getDocument() : node;
			return;
		}
		//   v<--|
		//   AAAAAA
		// BBBBBBBBBB cursorNode:A , node:B -> target is A
		if (cursorNode != null) {
			for (ICSSNode parent = cursorNode.getParentNode(); parent != null; parent = parent.getParentNode()) {
				if (parent == cursorNode) {
					fTargetNode = cursorNode;
					return;
				}
			}
		}
		//     v<--|
		//   AAA
		// BBBBBBBBBB cursorNode:B , node:A -> depend on A's node type
		short nodeType = node.getNodeType();
		if (nodeType == ICSSNode.STYLEDECLITEM_NODE || nodeType == ICSSNode.CHARSETRULE_NODE || nodeType == ICSSNode.IMPORTRULE_NODE) {
			String type = CSSUtil.getStructuredDocumentRegionType(flatNode);
			if (type == CSSRegionContexts.CSS_DELIMITER || type == CSSRegionContexts.CSS_DECLARATION_DELIMITER) {
				fTargetNode = node.getParentNode();
			} else {
				fTargetNode = node;
			}
			//			fTargetNode = (bOverSemiColon) ? node.getParentNode() : node;
		} else if (CSSUtil.getStructuredDocumentRegionType(flatNode) == CSSRegionContexts.CSS_RBRACE) {
			fTargetNode = node.getParentNode();
		} else {
			fTargetNode = node;
		}

		return;
	}

	/**
	 *  
	 */
	private void initializeTargetPos() {
		if (fCursorPos == 0 || isSpecialDelimiterRegion(fCursorPos - 1)) {
			fTargetPos = fCursorPos;
		} else {
			fTargetPos = fCursorPos - 1;
		}
		
		//deal with the leading quote
		if(fQuote != 0) {
			fTargetPos--;
		}
	}

	/**
	 *  
	 */
	private void initializeTargetText() {
		ITextRegion targetRegion = getTargetRegion();
		IStructuredDocumentRegion documentRegion = getTargetDocumentRegion();
		if (targetRegion == null) {
			fReplaceBegin = fCursorPos;
			fTextToReplace = ""; //$NON-NLS-1$
			fTextToCompare = ""; //$NON-NLS-1$
		} else {
			String regionText = documentRegion.getText(targetRegion);
			int regionStart = documentRegion.getStartOffset(targetRegion);
			if (!fSelected && (regionStart == fCursorPos || regionText.trim().length() == 0 || regionStart + regionText.length() - 1 < this.fTargetPos)) {
				// to insertion
				fReplaceBegin = fCursorPos;
				fTextToReplace = ""; //$NON-NLS-1$
				fTextToCompare = ""; //$NON-NLS-1$
				try {
					if (fLength > 0)
						fTextToReplace = fStructuredDocument.get(fReplaceBegin, fLength);
				}
				catch (BadLocationException e) {
				}
			} else {
				// to replace
				fReplaceBegin = regionStart;
				fTextToReplace = regionText;

				//math to deal with leading quote
				int matchLength = fCursorPos - fReplaceBegin;
				if(fQuote != 0) {
					matchLength--;
					fReplaceBegin++;
				}
				
				if(fCursorPos >= fReplaceBegin && regionText.trim().length() >= (matchLength))
					fTextToCompare = regionText.substring(0, matchLength);
				else
					fTextToCompare = ""; //$NON-NLS-1$
			}
		}
	}

	/**
	 *  
	 */
	private boolean isSpecialDelimiterRegion(int pos) {
		ITextRegion region = getRegionByOffset(pos);
		String type = null;
		if(region != null) {
			type = region.getType();
		}
		return (type != null) &&((type == CSSRegionContexts.CSS_LBRACE ||
				type == CSSRegionContexts.CSS_RBRACE ||
				type == CSSRegionContexts.CSS_DELIMITER ||
				type == CSSRegionContexts.CSS_DECLARATION_SEPARATOR ||
				type == CSSRegionContexts.CSS_DECLARATION_DELIMITER ||
				type == CSSRegionContexts.CSS_DECLARATION_VALUE_OPERATOR ||
				type == CSSRegionContexts.CSS_S));
	}
	/**
	 *  
	 */
	boolean isTargetPosAfterOf(String regionType) {
		int start = ((IndexedRegion) fTargetNode).getStartOffset();
		if (start < 0 || ((IndexedRegion) fTargetNode).getEndOffset() <= 0) {
			return false;
		}

		RegionIterator iRegion = new RegionIterator(fStructuredDocument, start);
		while (iRegion.hasNext()) {
			ITextRegion region = iRegion.next();
			if (fTargetPos < iRegion.getStructuredDocumentRegion().getTextEndOffset(region)) {
				break;
			}
			if (region.getType() == regionType) {
				return true;
			}
		}

		return false;
	}

	/**
	 *  
	 */
	boolean isTargetPosBeforeOf(String regionType) {
		return !isTargetPosAfterOf(regionType);
	}

	/**
	 * @return boolean
	 * @param regionType
	 *            java.lang.String
	 */
	boolean targetFollows(String regionType) {
		RegionIterator iRegion;
		ITextRegion region = null;
		if (fStructuredDocument.getLength() <= fTargetPos) {
			iRegion = new RegionIterator(fStructuredDocument, fStructuredDocument.getLength() - 1);
		} else {
			iRegion = new RegionIterator(fStructuredDocument, fTargetPos);
			try {
				if (!Character.isWhitespace(fStructuredDocument.getChar(fTargetPos)) && iRegion.hasPrev()) {
					region = iRegion.prev();
				}
			} catch (BadLocationException e) {
				iRegion = new RegionIterator(fStructuredDocument, fStructuredDocument.getLength() - 1);
			}
		}
		while (iRegion.hasPrev()) {
			region = iRegion.prev();
			String type = region.getType();
			if (type == CSSRegionContexts.CSS_S || type == CSSRegionContexts.CSS_COMMENT) {
				continue;
			} else {
				break;
			}
		}
		if (region != null && region.getType() == regionType) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 *  
	 */
	boolean targetHas(String regionType) {
		int end = ((IndexedRegion) fTargetNode).getEndOffset();
		if (getTargetPos() < 0 || end <= 0) {
			return false;
		}
		RegionIterator iRegion = new RegionIterator(fStructuredDocument, getTargetPos());
		while (iRegion.hasNext()) {
			ITextRegion region = iRegion.next();
			if (end <= iRegion.getStructuredDocumentRegion().getStartOffset(region)) {
				break;
			}
			if (region.getType() == regionType) {
				return true;
			}
		}
		return false;
	}

	RegionIterator getRegionIterator() {
		return new RegionIterator(getStructuredDocument(), getTargetPos());
	}

	/**
	 *  
	 */
	CSSMetaModel getMetaModel() {
		CSSMetaModelFinder finder = CSSMetaModelFinder.getInstance();
		ICSSModel model = getModel();
		if (model.getOwnerDOMNode() != null) {
			return finder.findMetaModelFor(model.getOwnerDOMNode());
		}
		return finder.findMetaModelFor(getModel());
	}
}
