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



import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.Vector;

import org.eclipse.wst.common.contentmodel.CMNode;

/**
 * Factory for element declarations.
 */
final class ElementCollection extends DeclCollection implements org.eclipse.wst.html.core.HTML40Namespace.ElementName {


	// Element IDs
	private static class Ids {
		public static final int ID_A = 0;
		public static final int ID_ADDRESS = 1;
		public static final int ID_BASE = 2;
		public static final int ID_BLOCKQUOTE = 3;
		public static final int ID_BODY = 4;
		public static final int ID_BR = 5;
		public static final int ID_CENTER = 6;
		public static final int ID_DD = 7;
		public static final int ID_DIR = 8;
		public static final int ID_DIV = 9;
		public static final int ID_DL = 10;
		public static final int ID_DT = 11;
		public static final int ID_FORM = 12;
		public static final int ID_H1 = 13;
		public static final int ID_H2 = 14;
		public static final int ID_H3 = 15;
		public static final int ID_H4 = 16;
		public static final int ID_H5 = 17;
		public static final int ID_H6 = 18;
		public static final int ID_HEAD = 19;
		public static final int ID_HR = 20;
		public static final int ID_HTML = 21;
		public static final int ID_IMG = 22;
		public static final int ID_INPUT = 23;
		public static final int ID_LI = 24;
		public static final int ID_MENU = 25;
		public static final int ID_META = 26;
		public static final int ID_OL = 27;
		public static final int ID_OPTION = 28;
		public static final int ID_P = 29;
		public static final int ID_PRE = 30;
		public static final int ID_SELECT = 31;
		public static final int ID_TEXTAREA = 32;
		public static final int ID_TITLE = 33;
		public static final int ID_UL = 34;
		public static final int ID_SSI_CONFIG = 35;
		public static final int ID_SSI_ECHO = 36;
		public static final int ID_SSI_EXEC = 37;
		public static final int ID_SSI_FSIZE = 38;
		public static final int ID_SSI_FLASTMOD = 39;
		public static final int ID_SSI_INCLUDE = 40;
		public static final int ID_SSI_PRINTENV = 41;
		public static final int ID_SSI_SET = 42;

		public static int getNumOfIds() {
			if (numofids != -1)
				return numofids;

			// NOTE: If the reflection is too slow, this method should
			// just return the literal value, like 105.
			// -- 5/25/2001
			Class clazz = Ids.class;
			Field[] fields = clazz.getFields();
			numofids = 0;
			for (int i = 0; i < fields.length; i++) {
				String name = fields[i].getName();
				if (name.startsWith("ID_"))//$NON-NLS-1$
					numofids++;
			}
			return numofids;
		}

		// chache the result of the reflection.
		private static int numofids = -1;
	}

	/** %formctl;. INPUT | SELECT | TEXTAREA */
	private static final String[] FORMCTL = {INPUT, SELECT, TEXTAREA};
	/** %phrase;.
	 * DFN
	 */
	private static final String[] PHRASE = {DFN};
	/** %special;.
	 * A | IMG | BR
	 */
	private static final String[] SPECIAL = {A, IMG, BR};
	/** %heading;. H[1-6] */
	private static final String[] HEADING = {H1, H2, H3, H4, H5, H6};
	/** %list;. UL | OL | DIR | MENU */
	private static final String[] LIST = {UL, OL, DIR, MENU};
	/** %preformatted;. PRE */
	private static final String[] PREFORMATTED = {PRE};
	private AttributeCollection attributeCollection = null;
	private static String[] names = null;

	static {
		names = new String[Ids.getNumOfIds()];
		names[Ids.ID_A] = A;
		names[Ids.ID_ADDRESS] = ADDRESS;
		names[Ids.ID_BASE] = BASE;
		names[Ids.ID_BLOCKQUOTE] = BLOCKQUOTE;
		names[Ids.ID_BODY] = BODY;
		names[Ids.ID_BR] = BR;
		names[Ids.ID_CENTER] = CENTER;
		names[Ids.ID_DD] = DD;
		names[Ids.ID_DIR] = DIR;
		names[Ids.ID_DIV] = DIV;
		names[Ids.ID_DL] = DL;
		names[Ids.ID_DT] = DT;
		names[Ids.ID_FORM] = FORM;
		names[Ids.ID_H1] = H1;
		names[Ids.ID_H2] = H2;
		names[Ids.ID_H3] = H3;
		names[Ids.ID_H4] = H4;
		names[Ids.ID_H5] = H5;
		names[Ids.ID_H6] = H6;
		names[Ids.ID_HEAD] = HEAD;
		names[Ids.ID_HR] = HR;
		names[Ids.ID_HTML] = HTML;
		names[Ids.ID_IMG] = IMG;
		names[Ids.ID_INPUT] = INPUT;
		names[Ids.ID_LI] = LI;
		names[Ids.ID_MENU] = MENU;
		names[Ids.ID_META] = META;
		names[Ids.ID_OL] = OL;
		names[Ids.ID_OPTION] = OPTION;
		names[Ids.ID_P] = P;
		names[Ids.ID_PRE] = PRE;
		names[Ids.ID_SELECT] = SELECT;
		names[Ids.ID_TEXTAREA] = TEXTAREA;
		names[Ids.ID_TITLE] = TITLE;
		names[Ids.ID_UL] = UL;
		names[Ids.ID_SSI_CONFIG] = SSI_CONFIG;
		names[Ids.ID_SSI_ECHO] = SSI_ECHO;
		names[Ids.ID_SSI_EXEC] = SSI_EXEC;
		names[Ids.ID_SSI_FSIZE] = SSI_FSIZE;
		names[Ids.ID_SSI_FLASTMOD] = SSI_FLASTMOD;
		names[Ids.ID_SSI_INCLUDE] = SSI_INCLUDE;
		names[Ids.ID_SSI_PRINTENV] = SSI_PRINTENV;
		names[Ids.ID_SSI_SET] = SSI_SET;
	}

	/**
	 */
	public ElementCollection(AttributeCollection collection) {
		super(names, TOLERANT_CASE);
		attributeCollection = collection;
	}

	/**
	 * Actually creates HTMLElementDeclaration instance.
	 * @return HTMLElementDeclaration
	 */
	protected CMNode create(String elementName) {
		HTMLElemDeclImpl edec = null;

		if (elementName.equalsIgnoreCase(A)) {
			edec = new HedA(this);

		}
		else if (elementName.equalsIgnoreCase(ADDRESS)) {
			edec = new HedADDRESS(this);

		}
		else if (elementName.equalsIgnoreCase(BASE)) {
			edec = new HedBASE(this);

		}
		else if (elementName.equalsIgnoreCase(BLOCKQUOTE)) {
			edec = new HedBLOCKQUOTE(this);

		}
		else if (elementName.equalsIgnoreCase(BODY)) {
			edec = new HedBODY(this);

		}
		else if (elementName.equalsIgnoreCase(BR)) {
			edec = new HedBR(this);

		}
		else if (elementName.equalsIgnoreCase(CENTER)) {
			edec = new HedCENTER(this);

		}
		else if (elementName.equalsIgnoreCase(DD)) {
			edec = new HedDD(this);

		}
		else if (elementName.equalsIgnoreCase(DIR)) {
			edec = new HedMENU(DIR, this);

		}
		else if (elementName.equalsIgnoreCase(DIV)) {
			edec = new HedDIV(this);

		}
		else if (elementName.equalsIgnoreCase(DL)) {
			edec = new HedDL(this);

		}
		else if (elementName.equalsIgnoreCase(DT)) {
			edec = new HedDT(this);

		}
		else if (elementName.equalsIgnoreCase(FORM)) {
			edec = new HedFORM(this);

		}
		else if (elementName.equalsIgnoreCase(H1)) {
			edec = new HedHeading(H1, this);

		}
		else if (elementName.equalsIgnoreCase(H2)) {
			edec = new HedHeading(H2, this);

		}
		else if (elementName.equalsIgnoreCase(H3)) {
			edec = new HedHeading(H3, this);

		}
		else if (elementName.equalsIgnoreCase(H4)) {
			edec = new HedHeading(H4, this);

		}
		else if (elementName.equalsIgnoreCase(H5)) {
			edec = new HedHeading(H5, this);

		}
		else if (elementName.equalsIgnoreCase(H6)) {
			edec = new HedHeading(H6, this);

		}
		else if (elementName.equalsIgnoreCase(HEAD)) {
			edec = new HedHEAD(this);

		}
		else if (elementName.equalsIgnoreCase(HR)) {
			edec = new HedHR(this);

		}
		else if (elementName.equalsIgnoreCase(HTML)) {
			edec = new HedHTML(this);

		}
		else if (elementName.equalsIgnoreCase(IMG)) {
			edec = new HedIMG(this);

		}
		else if (elementName.equalsIgnoreCase(INPUT)) {
			edec = new HedINPUT(this);

		}
		else if (elementName.equalsIgnoreCase(LI)) {
			edec = new HedLI(this);

		}
		else if (elementName.equalsIgnoreCase(MENU)) {
			edec = new HedMENU(MENU, this);

		}
		else if (elementName.equalsIgnoreCase(META)) {
			edec = new HedMETA(this);

		}
		else if (elementName.equalsIgnoreCase(OL)) {
			edec = new HedOL(this);

		}
		else if (elementName.equalsIgnoreCase(OPTION)) {
			edec = new HedOPTION(this);

		}
		else if (elementName.equalsIgnoreCase(P)) {
			edec = new HedP(this);

		}
		else if (elementName.equalsIgnoreCase(PRE)) {
			edec = new HedPRE(this);

		}
		else if (elementName.equalsIgnoreCase(SELECT)) {
			edec = new HedSELECT(this);

		}
		else if (elementName.equalsIgnoreCase(TEXTAREA)) {
			edec = new HedTEXTAREA(this);

		}
		else if (elementName.equalsIgnoreCase(TITLE)) {
			edec = new HedTITLE(this);

		}
		else if (elementName.equalsIgnoreCase(UL)) {
			edec = new HedUL(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_CONFIG)) {
			edec = new HedSSIConfig(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_ECHO)) {
			edec = new HedSSIEcho(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_EXEC)) {
			edec = new HedSSIExec(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_FSIZE)) {
			edec = new HedSSIFsize(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_FLASTMOD)) {
			edec = new HedSSIFlastmod(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_INCLUDE)) {
			edec = new HedSSIInclude(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_PRINTENV)) {
			edec = new HedSSIPrintenv(this);

		}
		else if (elementName.equalsIgnoreCase(SSI_SET)) {
			edec = new HedSSISet(this);

		} // unknown
		else {
			// NOTE: We don't define the UNKNOWN element declaration.
			// <code>null</code> for a declaration is a sign of
			// the target element is unknown.
			// -- 3/9/2001
			edec = null;
		}
		return edec;
	}

	/**
	 * @return com.ibm.sed.contentmodel.html.AttributeCollection
	 */
	public AttributeCollection getAttributeCollection() {
		return attributeCollection;
	}

	/**
	 */
	public final Collection getNamesOfBlock() {
		// P | %list | %preformatted | DL | DIV | CENTER | BLOCKQUOTE | FORM | HR
		String[] blockMisc = {P, DL, DIV, CENTER, BLOCKQUOTE, FORM, HR,};
		Vector blockNames = new Vector(Arrays.asList(blockMisc));
		// %heading;
		blockNames.addAll(Arrays.asList(HEADING));
		// %list;
		blockNames.addAll(Arrays.asList(LIST));
		// %preformatted;
		blockNames.addAll(Arrays.asList(PREFORMATTED));

		return blockNames;
	}

	/**
	 * %block;.
	 * %block; is:
	 * P | %heading; | %list; | %preformatted; | DL | DIV | CENTER |
	 * NOSCRIPT | NOFRAMES | BLOCKQUOTE | FORM | ISINDEX | HR |
	 * TABLE | FIELDSET | ADDRESS.<br>
	 * @param group CMGroupImpl Return values.
	 */
	public final void getBlock(CMGroupImpl group) {
		if (group == null)
			return;
		getDeclarations(group, getNamesOfBlock().iterator());
	}

	/**
	 * Create element declarations and store them
	 * into a <code>CMGroupImpl</code> instance.
	 * @param group CMGroupImpl Return values.
	 */
	public final void getFlow(CMGroupImpl group) {
		if (group == null)
			return;
		getBlock(group);
		getInline(group);
	}

	/**
	 * Create element declarations and store them into a <code>CMGroupImpl</code>
	 * instance.<br>
	 * @param group CMGroupImpl Return values.
	 */
	public final void getFontstyle(CMGroupImpl group) {
		return;
	}

	/**
	 * Create element declarations and store them into a <code>CMGroupImpl</code>
	 * instance.<br>
	 * @param group CMGroupImpl Return values.
	 */
	public final void getFormctrl(CMGroupImpl group) {
		if (group == null)
			return;
		getDeclarations(group, Arrays.asList(FORMCTL).iterator());
	}

	/**
	 * %heading;.
	 * @param group CMGroupImpl Return values.
	 */
	public final void getHeading(CMGroupImpl group) {
		if (group == null)
			return;

		getDeclarations(group, Arrays.asList(HEADING).iterator());
	}

	/**
	 * Create element declarations and store them
	 * into a <code>CMGroupImpl</code> instance.
	 * @param group CMGroupImpl Return values.
	 */
	public final void getInline(CMGroupImpl group) {
		if (group == null)
			return;
		getFontstyle(group);
		getPhrase(group);
		getSpecial(group);
		getFormctrl(group);
	}

	/**
	 * %list;.
	 * @param group CMGroupImpl Return values.
	 */
	public final void getList(CMGroupImpl group) {
		if (group == null)
			return;

		getDeclarations(group, Arrays.asList(LIST).iterator());
	}

	/**
	 * Create element declarations and store them into a <code>CMGroupImpl</code>
	 * instance.<br>
	 * @param group CMGroupImpl Return values.
	 */
	public final void getPhrase(CMGroupImpl group) {
		if (group == null)
			return;
		getDeclarations(group, Arrays.asList(PHRASE).iterator());
	}

	/**
	 * %preformatted;
	 * @param group CMGroupImpl Return values.
	 */
	public final void getPreformatted(CMGroupImpl group) {
		if (group == null)
			return;

		getDeclarations(group, Arrays.asList(PREFORMATTED).iterator());
	}

	/**
	 * Create element declarations and store them into a <code>CMGroupImpl</code>
	 * instance.<br>
	 * @param group CMGroupImpl Return values.
	 */
	public final void getSpecial(CMGroupImpl group) {
		if (group == null)
			return;
		getDeclarations(group, Arrays.asList(SPECIAL).iterator());
	}
}