/*****************************************************************************
 * 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 java.util.Vector;

import org.eclipse.wst.common.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.common.contentmodel.CMDocument;
import org.eclipse.wst.common.contentmodel.CMElementDeclaration;
import org.eclipse.wst.common.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.css.core.document.ICSSModel;
import org.eclipse.wst.css.core.document.ICSSStyleRule;
import org.eclipse.wst.css.ui.image.CSSImageType;
import org.eclipse.wst.html.core.contentmodel.HTMLCMDocumentFactory;
import org.eclipse.wst.sse.core.contentmodel.CMDocType;
import org.eclipse.wst.xml.core.document.DocumentTypeAdapter;
import org.eclipse.wst.xml.core.document.XMLDocument;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

class CSSProposalGeneratorForHTMLTag extends CSSProposalGenerator {

	/**
	 * CSSStyleRuleProposalGenerator constructor comment.
	 * 
	 * @param context
	 *            com.ibm.sed.contentassist.old.css.CSSContentAssistContext
	 */
	CSSProposalGeneratorForHTMLTag(CSSContentAssistContext context) {
		super(context);

		if (fHTMLTags == null) {
			fHTMLTags = setupHTMLTags();
		}
	}

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

		if (checkLeadingColon()) {
			return candidates.iterator();
		}

		// XHTML requires lower case
		boolean bLowerCase = false;
		if (fContext.getModel().getStyleSheetType() == ICSSModel.EMBEDDED) {
			Node domNode = fContext.getModel().getOwnerDOMNode();
			if (domNode != null && !(domNode instanceof Document)) {
				domNode = domNode.getOwnerDocument();
				if (domNode instanceof XMLDocument) {
					DocumentTypeAdapter adapter = (DocumentTypeAdapter) ((XMLDocument) domNode).getAdapterFor(DocumentTypeAdapter.class);
					if (adapter != null)
						bLowerCase = (adapter.getTagNameCase() == DocumentTypeAdapter.LOWER_CASE);
				}
			}
		}


		int length = fHTMLTags.length;
		for (int i = 0; i < length; i++) {
			String tagText = fHTMLTags[i];
			if (bLowerCase) {
				tagText = tagText.toLowerCase();
			}
			if (!isMatch(tagText)) {
				continue;
			}

			int cursorPos = 0;
			StringBuffer buf = new StringBuffer();
			buf.append(tagText);
			cursorPos += tagText.length();
			boolean inRule = (fContext.getTargetNode() instanceof ICSSStyleRule);
			if (!inRule || fContext.getTextToReplace().length() == 0) {
				buf.append(" ");//$NON-NLS-1$
				cursorPos += 1;
			}
			if (!inRule) {
				StringAndOffset sao = generateBraces();
				buf.append(sao.fString);
				cursorPos += sao.fOffset;
			}

			CSSCACandidate item = new CSSCACandidate();
			item.setReplacementString(buf.toString());
			item.setCursorPosition(cursorPos);
			item.setDisplayString(tagText);
			item.setImageType(CSSImageType.SELECTOR_TAG);
			candidates.add(item);
		}

		return candidates.iterator();
	}

	/**
	 *  
	 */
	private static String[] setupHTMLTags() {
		CMDocument cmdoc = HTMLCMDocumentFactory.getCMDocument(CMDocType.HTML_DOC_TYPE);
		CMNamedNodeMap elements = cmdoc.getElements();
		Vector names = new Vector();
		int nElements = elements.getLength();
		for (int i = 0; i < nElements; i++) {
			CMElementDeclaration edec = (CMElementDeclaration) elements.item(i);
			if (isAttrDefined(edec, HTML40Namespace.ATTR_NAME_STYLE)) {
				names.add(edec.getElementName());
			}
		}
		Collections.sort(names);
		String[] tags = new String[names.size()];
		Iterator iNames = names.iterator();
		for (int i = 0; iNames.hasNext(); i++) {
			tags[i] = (String) iNames.next();
		}
		return tags;
	}

	/**
	 *  
	 */
	private static boolean isAttrDefined(CMElementDeclaration edec, String attrName) {
		if (edec == null) {
			return false;
		}
		CMNamedNodeMap attrs = edec.getAttributes();
		if (attrs == null) {
			return false;
		}
		for (int i = 0; i < attrs.getLength(); i++) {
			CMAttributeDeclaration attr = (CMAttributeDeclaration) attrs.item(i);
			if (attr == null) {
				continue;
			}
			if (attr.getAttrName().equalsIgnoreCase(attrName)) {
				return true;
			}
		}
		return false;
	}

	private static String[] fHTMLTags = null;
}