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

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Stack;

import org.eclipse.wst.css.core.internal.Logger;
import org.eclipse.wst.css.core.internal.metamodel.CSSMMNode;
import org.eclipse.wst.css.core.internal.metamodel.CSSMMSelector;
import org.eclipse.wst.css.core.internal.metamodel.CSSProfile;
import org.eclipse.wst.css.core.internal.metamodel.CSSProfileRegistry;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


class ProfileHandler extends DefaultHandler {

	public ProfileHandler(CSSMetaModelImpl metamodel, ResourceBundle resourceBundle, boolean logging) {
		super();
		fMetaModel = metamodel;
		fNodePool = metamodel.getNodePool();
		fResourceBundle = resourceBundle;
		fLogging = logging;
	}

	public ProfileHandler(CSSMetaModelImpl metamodel, ResourceBundle resourceBundle) {
		super();
		fMetaModel = metamodel;
		fNodePool = metamodel.getNodePool();
		fResourceBundle = resourceBundle;
		fLogging = false;
	}

	private String getResourceString(String key) {
		if (key.equals("%")) { //$NON-NLS-1$
			return key;
		}
		if (!key.startsWith("%")) { //$NON-NLS-1$
			return key;
		}
		if (key.startsWith("%%")) { //$NON-NLS-1$
			return key.substring(1);
		}

		if (fResourceBundle != null) {
			return fResourceBundle.getString(key.substring(1));
		}
		else {
			return key;
		}
	}

	public void startDocument() throws SAXException {
		// System.out.println("startDocument");
		// fNodeStack.push(metamodel);
		// fCurrentNode = null;
	}

	public void endDocument() throws SAXException {
		new ErrorCorrector().doCorrect(fMetaModel);
		if (fLogging) {
			Iterator i = fNodePool.getStrayNodes();
			while (i.hasNext()) {
				CSSMMNode node = (CSSMMNode) i.next();
				String str = "[CSSProfile Warning] " + node.getName(); //$NON-NLS-1$
				str += "(" + node.getType() + ") is not referred by any node."; //$NON-NLS-1$ //$NON-NLS-2$
				Logger.log(Logger.WARNING, str);
				// System.out.println(str);
			}
		}
	}

	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		TagNode tagNode = null;
		CSSMMNodeImpl parentNode = null;
		if (0 < fNodeStack.size()) {
			tagNode = (TagNode) fNodeStack.peek();
			parentNode = tagNode.node;
		}

		CSSMMNodeImpl node = null;
		if (qName.equals(ProfileKeywords.PROFILE_IMPORT)) { // import
			String profileName = attributes.getValue(ATTR_NAME_REFERENCE);
			importProfile(profileName);
		}
		else if (isDefinition(qName)) { // node creation
			String nodeName = attributes.getValue(ATTR_NAME_DEFINITION);
			node = fNodePool.getNode(qName, nodeName);
			if (node != null) {
				String overwrite = attributes.getValue(ATTR_OVERWRITE);
				if (overwrite == null || overwrite.equals(ATTR_VALUE_OVERWRITE_FALSE)) {
					node.removeAllChildNodes();
				}
				Map attrMap = new HashMap();
				for (int i = 0; i < attributes.getLength(); i++) {
					attrMap.put(attributes.getQName(i), attributes.getValue(i));
				}
				try {
					node.initializeAttribute(attrMap);
				}
				catch (IllegalArgumentException e) {
					Logger.logException(e);
				}
			}
		}
		else if (node == null) { // node reference
			String nodeName = attributes.getValue(ATTR_NAME_REFERENCE);
			node = fNodePool.getNode(qName, nodeName);
		}

		if (node != null) {
			if (parentNode != null && parentNode.canContain(node)) {
				String enabled = attributes.getValue(ATTR_ENABLED);
				if (enabled != null && enabled.equals(ATTR_VALUE_ENABLED_FALSE)) {
					parentNode.removeChild(node);
				}
				else {
					parentNode.appendChild(node);
				}
			}
			else if (node.getType() == CSSMMNode.TYPE_STYLE_SHEET || node.getType() == CSSMMNode.TYPE_CATEGORY) {
				fMetaModel.appendChild(node);
			}
			else {
				if (fLogging && parentNode != null) {
					Logger.log(Logger.ERROR, parentNode.getType() + " cannot contain " + //$NON-NLS-1$
								node.getType() + " (" + qName + ")"); //$NON-NLS-2$//$NON-NLS-1$
				}
			}
		}

		fNodeStack.push(new TagNode(qName, (node != null) ? node : parentNode));
	}

	public void endElement(String uri, String localName, String qName) throws SAXException {
		fNodeStack.pop();
	}

	public void characters(char[] ch, int start, int length) throws SAXException {
		TagNode tagNode = (TagNode) fNodeStack.peek();
		String tagName = tagNode.tag;
		if (tagName.equals(ProfileKeywords.KEYWORD_VALUE) || tagName.equals(ProfileKeywords.UNIT_VALUE) || tagName.equals(ProfileKeywords.FUNCTION_VALUE) || tagName.equals(ProfileKeywords.SELECTOR_VALUE) || tagName.equals(ProfileKeywords.DESCRIPTION) || tagName.equals(ProfileKeywords.CAPTION)) {
			StringBuffer buf = new StringBuffer(length);
			for (int i = 0; i < length; i++) {
				buf.append(ch[start + i]);
			}
			String value = getResourceString(buf.toString().trim());
			CSSMMNodeImpl node = tagNode.node;
			if (node != null) {
				if (node.getType() == CSSMMNode.TYPE_KEYWORD && tagName.equals(ProfileKeywords.KEYWORD_VALUE)) {
					((CSSMMKeywordImpl) node).setKeywordString(value);
				}
				else if (node.getType() == CSSMMNode.TYPE_UNIT && tagName.equals(ProfileKeywords.UNIT_VALUE)) {
					((CSSMMUnitImpl) node).setUnitString(value);
				}
				else if (node.getType() == CSSMMNode.TYPE_FUNCTION && tagName.equals(ProfileKeywords.FUNCTION_VALUE)) {
					((CSSMMFunctionImpl) node).setFunctionString(value);
				}
				else if (node.getType() == CSSMMNode.TYPE_SELECTOR && ((CSSMMSelector) node).getSelectorType() == CSSMMSelector.TYPE_PSEUDO_ELEMENT) {
					((CSSMMPseudoElementImpl) node).setSelectorString(value);
				}
				else if (node.getType() == CSSMMNode.TYPE_SELECTOR && ((CSSMMSelector) node).getSelectorType() == CSSMMSelector.TYPE_PSEUDO_CLASS) {
					((CSSMMPseudoClassImpl) node).setSelectorString(value);
				}
				else if (node.getType() == CSSMMNode.TYPE_CATEGORY && tagName.equals(ProfileKeywords.CAPTION)) {
					((CSSMMCategoryImpl) node).setCaption(value);
				}
				else if (tagName.equals(ProfileKeywords.DESCRIPTION)) {
					node.setDescription(value);
				}
			}
		}
	}

	private boolean isDefinition(String tagName) {
		return (tagName.equals(ProfileKeywords.STYLESHEET_DEF) || tagName.equals(ProfileKeywords.CHARSET_RULE_DEF) || tagName.equals(ProfileKeywords.IMPORT_RULE_DEF) || tagName.equals(ProfileKeywords.PAGE_RULE_DEF) || tagName.equals(ProfileKeywords.MEDIA_RULE_DEF) || tagName.equals(ProfileKeywords.FONTFACE_RULE_DEF) || tagName.equals(ProfileKeywords.STYLE_RULE_DEF) || tagName.equals(ProfileKeywords.KEYWORD_DEF) || tagName.equals(ProfileKeywords.NUMBER_DEF) || tagName.equals(ProfileKeywords.PROPERTY_DEF) || tagName.equals(ProfileKeywords.DESCRIPTOR_DEF) || tagName.equals(ProfileKeywords.CONTAINER_DEF) || tagName.equals(ProfileKeywords.UNIT_DEF) || tagName.equals(ProfileKeywords.FUNCTION_DEF) || tagName.equals(ProfileKeywords.STRING) || tagName.equals(ProfileKeywords.CATEGORY_DEF) || tagName.equals(ProfileKeywords.PSEUDO_CLASS_DEF) || tagName.equals(ProfileKeywords.PSEUDO_ELEMENT_DEF) || tagName.equals(ProfileKeywords.SELECTOR_EXPRESSION) || tagName.equals(ProfileKeywords.SEPARATOR));
	}

	private void importProfile(String profileName) {
		URL profileURL = null;
		CSSProfileRegistry reg = CSSProfileRegistry.getInstance();
		CSSProfile profile = reg.getProfile(profileName);
		if (profile != null) {
			// first: find URL by ID
			profileURL = profile.getProfileURL();
		}
		else {
			// second: find URL by filename of profile URL
			Iterator i = reg.getProfiles();
			while (i.hasNext()) {
				profile = (CSSProfile) i.next();
				URL url = profile.getProfileURL();
				if (url.getFile().endsWith(profileName)) {
					profileURL = url;
					break;
				}
			}
		}
		if (profileURL == null) {
			// final: it may be url itself
			try {
				profileURL = new URL(profileName);
			}
			catch (MalformedURLException e) {
				Logger.logException(e);
			}
		}
		if (profileURL != null) {
			try {
				ProfileLoader.loadProfile(fMetaModel, profileURL.openStream(), fResourceBundle, fLogging);
			}
			catch (IOException e) {
				Logger.logException("Cannot open stream for profile", //$NON-NLS-1$
							e);
			}
		}
	}

	class TagNode {

		String tag = null;
		CSSMMNodeImpl node = null;

		TagNode(String tag, CSSMMNodeImpl node) {
			this.tag = tag;
			this.node = node;
		}
	}

	class ErrorCorrector {

		void doCorrect(CSSMMNodeImpl node) {
			Iterator i = node.getChildNodes();
			while (i.hasNext()) {
				CSSMMNodeImpl child = (CSSMMNodeImpl) i.next();
				doCorrect(child);
				short error = child.getError();
				if (error != MetaModelErrors.NO_ERROR) {
					node.removeChild(child);

					String str = "[CSSProfile Error] " + node.getName(); //$NON-NLS-1$
					str += "(" + node.getType() + ") contains error node: "; //$NON-NLS-1$ //$NON-NLS-2$
					str += child.getName() + "(" + child.getType() + ")"; //$NON-NLS-1$ //$NON-NLS-2$
					str += " - error code = " + error; //$NON-NLS-1$
					if (fLogging) {
						Logger.log(Logger.ERROR, str);
						// System.out.println(str);
					}
				}
			}
		}
	}


	private CSSMetaModelImpl fMetaModel = null;
	private NodePool fNodePool = null;
	private Stack fNodeStack = new Stack();
	private boolean fLogging = false;
	private ResourceBundle fResourceBundle = null;

	private final static String ATTR_NAME_DEFINITION = "name"; //$NON-NLS-1$
	private final static String ATTR_NAME_REFERENCE = "name"; //$NON-NLS-1$
	private final static String ATTR_OVERWRITE = "overwrite"; //$NON-NLS-1$
	private final static String ATTR_ENABLED = "enabled"; //$NON-NLS-1$
	private final static String ATTR_VALUE_OVERWRITE_FALSE = "false"; //$NON-NLS-1$
	private final static String ATTR_VALUE_ENABLED_FALSE = "false"; //$NON-NLS-1$
}