/*******************************************************************************
 * 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.html.core.internal.contentmodel;

import java.util.Hashtable;

import org.eclipse.wst.html.core.HTMLCMProperties;
import org.eclipse.wst.xml.core.internal.contentmodel.annotation.AnnotationMap;

/**
 * The factory object of PropertyProvider.
 */
final class PropertyProviderFactory {


	/**
	 * DefaultProvider is intended to be used for unknown properties.
	 * It always returns null value for any properties.
	 */
	class DefaultProvider implements PropertyProvider {
		public DefaultProvider() {
			super();
		}

		public boolean supports(HTMLElementDeclaration edecl) {
			return false;
		}

		public Object get(HTMLElementDeclaration edecl) {
			return null;
		}
	}

	abstract class AbstractElementPropertyProvider implements PropertyProvider {
		protected AbstractElementPropertyProvider() {
			super();
		}

		public boolean supports(HTMLElementDeclaration edecl) {
			return (edecl != null);
		}

		public Object get(HTMLElementDeclaration edecl) {
			if (!(edecl instanceof HTMLPropertyDeclaration))
				return null;
			return getElementProperty((HTMLPropertyDeclaration)edecl);
		}

		abstract protected Object getElementProperty(HTMLPropertyDeclaration decl);
	}

	/*
	 * "tagInfo"
	 * gets documentation for the element
	 */
	class PPTagInfo extends AbstractElementPropertyProvider {
		private final static String htmlAnnotationLoc = "platform:/plugin/org.eclipse.wst.html.core/data/htmref.xml"; //$NON-NLS-1$
		protected AnnotationMap fAnnotationMap = null;

		public PPTagInfo() {
			super();
		}

		/**
		 * Gets the annotationMap.
		 * @return Returns a AnnotationMap
		 */
		protected AnnotationMap getAnnotationMap() {
			if (fAnnotationMap == null) {
				fAnnotationMap = new AnnotationMap();
				try {
					fAnnotationMap.load(htmlAnnotationLoc);
				}
				catch (Exception e) {
					// no annotation available
				}
			}
			return fAnnotationMap;
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			if (decl instanceof HTMLElementDeclaration) {
				return getAnnotationMap().getProperty(((HTMLElementDeclaration)decl).getElementName(), "tagInfo"); //$NON-NLS-1$
			} else {
				return null;
			}
		}
	}

	/*
	 * "shouldKeepSpace"
	 */
	class PPShouldKeepSpace extends AbstractElementPropertyProvider {
		public PPShouldKeepSpace() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return new Boolean(decl.shouldKeepSpaces());
		}
	}

	/*
	 * "shouldIndentChildSource"
	 */
	class PPShouldIndentChildSource extends AbstractElementPropertyProvider {
		public PPShouldIndentChildSource() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return new Boolean(decl.shouldIndentChildSource());
		}
	}

	/*
	 * "terminators"
	 */
	class PPTerminators extends AbstractElementPropertyProvider {
		public PPTerminators() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			if (! (decl instanceof HTMLElemDeclImpl)) return null;
			return ((HTMLElemDeclImpl)decl).getTerminators();
		}
	}

	/*
	 * "prohibitedAncestors"
	 */
	class PPProhibitedAncestors extends AbstractElementPropertyProvider {
		public PPProhibitedAncestors() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return decl.getProhibitedAncestors();
		}
	}

	/*
	 * "isJSP"
	 */
	class PPIsJSP extends AbstractElementPropertyProvider {
		public PPIsJSP() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return new Boolean(decl.isJSP());
		}
	}

	/*
	 * "isXHTML"
	 * HTMLElementDeclaration itself never represent any XHTML element declaration.
	 * So, this property must be always false.
	 */
	class PPIsXHTML extends AbstractElementPropertyProvider {
		public PPIsXHTML() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return new Boolean(false);
		}
	}

	/*
	 * "isSSI"
	 * Each declaration class for SSI elements must provide this property itself,
	 * and then return true.  Other declaration must always return false.
	 */
	class PPIsSSI extends AbstractElementPropertyProvider {
		public PPIsSSI() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return new Boolean(false);
		}
	}

	/*
	 * "lineBreakHint"
	 */
	class PPLineBreakHint extends AbstractElementPropertyProvider {
		public PPLineBreakHint() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			String hint = HTMLCMProperties.Values.BREAK_NONE;
			switch (decl.getLineBreakHint()) {
				case HTMLElementDeclaration.BREAK_AFTER_START :
					hint = HTMLCMProperties.Values.BREAK_AFTER_START;
					break;
				case HTMLElementDeclaration.BREAK_BEFORE_START_AND_AFTER_END :
					hint = HTMLCMProperties.Values.BREAK_BEFORE_START_AND_AFTER_END;
					break;
				case HTMLElementDeclaration.BREAK_NONE :
				// nothing to do
				default :
					break;
			}
			return hint;
		}
	}

	/*
	 * "layoutType"
	 */
	class PPLayoutType extends AbstractElementPropertyProvider {
		public PPLayoutType() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			String type = HTMLCMProperties.Values.LAYOUT_NONE;
			switch (decl.getLayoutType()) {
				case HTMLElementDeclaration.LAYOUT_BLOCK :
					type = HTMLCMProperties.Values.LAYOUT_BLOCK;
					break;
				case HTMLElementDeclaration.LAYOUT_BREAK :
					type = HTMLCMProperties.Values.LAYOUT_BREAK;
					break;
				case HTMLElementDeclaration.LAYOUT_HIDDEN :
					type = HTMLCMProperties.Values.LAYOUT_HIDDEN;
					break;
				case HTMLElementDeclaration.LAYOUT_OBJECT :
					type = HTMLCMProperties.Values.LAYOUT_OBJECT;
					break;
				case HTMLElementDeclaration.LAYOUT_WRAP :
					type = HTMLCMProperties.Values.LAYOUT_WRAP;
					break;
				case HTMLElementDeclaration.LAYOUT_NONE :
				// nothing to do.
				default :
					break;
			}
			return type;
		}
	}

	/*
	 * "omitType"
	 */
	class PPOmitType extends AbstractElementPropertyProvider {
		public PPOmitType() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			String type = HTMLCMProperties.Values.OMIT_NONE;
			switch (decl.getOmitType()) {
				case HTMLElementDeclaration.OMIT_BOTH :
					type = HTMLCMProperties.Values.OMIT_BOTH;
					break;
				case HTMLElementDeclaration.OMIT_END :
					type = HTMLCMProperties.Values.OMIT_END;
					break;
				case HTMLElementDeclaration.OMIT_END_DEFAULT :
					type = HTMLCMProperties.Values.OMIT_END_DEFAULT;
					break;
				case HTMLElementDeclaration.OMIT_END_MUST :
					type = HTMLCMProperties.Values.OMIT_END_MUST;
					break;
				case HTMLElementDeclaration.OMIT_NONE :
				// nothing to do.
				default :
					break;
			}
			return type;
		}
	}

	/*
	 * "inclusion"
	 */
	class PPInclusion extends AbstractElementPropertyProvider {
		public PPInclusion() {
			super();
		}

		protected Object getElementProperty(HTMLPropertyDeclaration decl) {
			return decl.getInclusion();
		}
	}

	public static PropertyProvider getProvider(String propName) {
		PropertyProviderFactory factory = getInstance();
		PropertyProvider pp = (PropertyProvider) factory.registry.get(propName);
		if (pp != null)
			return pp;

		pp = factory.create(propName);
		if (pp == null)
			return factory.defaultProvider;

		factory.registry.put(propName, pp);
		return pp;
	}

	private static PropertyProviderFactory instance = null;

	private synchronized static PropertyProviderFactory getInstance() {
		if (instance != null)
			return instance;
		instance = new PropertyProviderFactory();
		return instance;
	}

	private Hashtable registry = new Hashtable();
	private PropertyProvider defaultProvider = new DefaultProvider();

	private PropertyProviderFactory() {
		super();
	}

	private PropertyProvider create(String propName) {
		PropertyProvider pp = null;
		if (propName.equals(HTMLCMProperties.IS_JSP))
			pp = new PPIsJSP();
		else if (propName.equals(HTMLCMProperties.IS_XHTML))
			pp = new PPIsXHTML();
		else if (propName.equals(HTMLCMProperties.IS_SSI))
			pp = new PPIsSSI();
		else if (propName.equals(HTMLCMProperties.LAYOUT_TYPE))
			pp = new PPLayoutType();
		else if (propName.equals(HTMLCMProperties.LINE_BREAK_HINT))
			pp = new PPLineBreakHint();
		else if (propName.equals(HTMLCMProperties.PROHIBITED_ANCESTORS))
			pp = new PPProhibitedAncestors();
		else if (propName.equals(HTMLCMProperties.SHOULD_KEEP_SPACE))
			pp = new PPShouldKeepSpace();
		else if (propName.equals(HTMLCMProperties.SHOULD_INDENT_CHILD_SOURCE))
			pp = new PPShouldIndentChildSource();
		else if (propName.equals(HTMLCMProperties.TERMINATORS))
			pp = new PPTerminators();
		else if (propName.equals(HTMLCMProperties.TAGINFO))
			pp = new PPTagInfo();
		else if (propName.equals(HTMLCMProperties.OMIT_TYPE))
			pp = new PPOmitType();
		else if (propName.equals(HTMLCMProperties.INCLUSION))
			pp = new PPInclusion();

		return pp;
	}
}