/*******************************************************************************
 * 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.HashMap;
import java.util.Iterator;
import java.util.Locale;

import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;

/**
 */
abstract class DeclCollection implements CMNamedNodeMap {


	protected class DualMap {
		public DualMap() {
			super();
		}

		public DualMap(Object[] objects) {
			super();
			initialize(objects);
		}

		public int size() {
			return table.length;
		}

		public Object getValue(int key) {
			if (!isValidIndex(key))
				return null;
			return table[key];
		}

		public int getKey(Object value) {
			Integer keyObj = (Integer) map.get(value);
			if (keyObj == null)
				return ID_UNKNOWN;
			return keyObj.intValue();
		}

		protected void initialize(Object[] objects) {
			if (objects == null)
				return;
			table = objects;
			map = new HashMap();
			for (int key = 0; key < objects.length; key++) {
				Object value = table[key];
				map.put(value, new Integer(key));
			}
		}

		private Object[] table = null;
		private HashMap map = null;

		private boolean isValidIndex(int index) {
			return index >= 0 && index < table.length;
		}
	}

	protected class TolerantStringDualMap extends DualMap {
		public TolerantStringDualMap(String[] names) {
			super();
			Object[] objects = new Object[names.length];
			for (int i = 0; i < names.length; i++) {
				objects[i] = makeCanonicalForm(names[i]);
			}
			initialize(objects);
		}

		public int getKey(Object value) {
			try {
				String name = (String) value;
				return super.getKey(makeCanonicalForm(name));
			}
			catch (ClassCastException e) {
				return ID_UNKNOWN;
			}
		}

		private String makeCanonicalForm(String raw) {
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=100152
			// we are able to "cheat" here a little and use US Locale 
			// to get a good cononical form, since we are using this only 
			// for HTML and JSP standard tags. 
			// Long term, for similar needs with XML 1.1 (for example)
			// we should use a class such as com.ibm.icu.text.Normalizer
			return raw.toUpperCase(Locale.US);
		}
	}

	private class DeclIterator implements Iterator {
		public DeclIterator() {
			maxid = fDecls.length - 1;
		}

		public boolean hasNext() {
			return id < maxid;
		}

		public Object next() {
			if (!hasNext())
				return null;
			return item(++id);
		}

		public void remove() { /* nothing should be done. */
		}

		private int id = -1;
		private int maxid = -1;
	}

	CMNode[] fDecls = null;
	protected final static boolean STRICT_CASE = false;
	protected final static boolean TOLERANT_CASE = true;
	protected final static int ID_UNKNOWN = -1;
	private DualMap fMap = null;

	/**
	 */
	public DeclCollection(String[] names, boolean tolerant) {
		super();
		fDecls = new CMNode[names.length];
		if (tolerant) {
			fMap = new TolerantStringDualMap(names);
		}
		else {
			fMap = new DualMap(names);
		}
	}

	/**
	 * @return org.eclipse.wst.xml.core.internal.contentmodel.CMNode
	 * @param id int
	 */
	protected abstract CMNode create(String name);

	/**
	 */
	public CMNamedNodeMap getDeclarations(String[] names) {
		CMNamedNodeMapImpl map = new CMNamedNodeMapImpl();
		for (int i = 0; i < names.length; i++) {
			String name = names[i];
			CMNode node = getNamedItem(name);
			if (node == null)
				continue;
			map.putNamedItem(name, node);
		}
		return map;
	}

	/**
	 * @param names java.util.Iterator
	 */
	public void getDeclarations(CMGroupImpl group, Iterator names) {
		while (names.hasNext()) {
			String entityName = (String) names.next();
			CMNode dec = getNamedItem(entityName);
			if (dec != null)
				group.appendChild(dec);
		}
	}

	/**
	 * Map name to id.
	 * @return int
	 * @param name java.lang.String
	 */
	protected int getID(String name) {
		return fMap.getKey(name);
	}

	/**
	 * getLength method
	 * @return int
	 */
	public int getLength() {
		return fDecls.length;
	}

	/**
	 * @return java.lang.String
	 * @param id int
	 */
	protected String getName(int id) {
		return (String) fMap.getValue(id);
	}

	/**
	 * getNamedItem method
	 * @return CMNode
	 * @param name java.lang.String
	 */
	public CMNode getNamedItem(String name) {
		int id = getID(name);
		if (!isValidID(id))
			return null;
		return item(id);
	}

	/**
	 * @return boolean
	 * @param id int
	 */
	private boolean isValidID(int id) {
		return id >= 0 && id < fDecls.length;
	}

	/**
	 * item method
	 * @return CMNode
	 * @param index int
	 */
	public CMNode item(int index) {
		if (!isValidID(index))
			return null;
		CMNode decl = fDecls[index];
		if (decl != null)
			return decl; // already exist.

		decl = create(getName(index));
		fDecls[index] = decl;
		return decl;
	}

	/**
	 */
	public Iterator iterator() {
		return new DeclIterator();
	}
}