// This file is part of TagSoup and is Copyright 2002-2008 by John Cowan.
//
// TagSoup is licensed under the Apache License,
// Version 2.0.  You may obtain a copy of this license at
// http://www.apache.org/licenses/LICENSE-2.0 .  You may also have
// additional legal rights not granted by this license.
//
// TagSoup is distributed in the hope that it will be useful, but
// unless required by applicable law or agreed to in writing, TagSoup
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, either express or implied; not even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// 
// 
// Model of document

package org.ccil.cowan.tagsoup;
import java.util.HashMap;

/**
Abstract class representing a TSSL schema.
Actual TSSL schemas are compiled into concrete subclasses of this class.
**/

public abstract class Schema {

	public static final int M_ANY = 0xFFFFFFFF;
	public static final int M_EMPTY = 0;
	public static final int M_PCDATA = 1 << 30;
	public static final int M_ROOT = 1 << 31;


	public static final int F_RESTART = 1;
	public static final int F_CDATA = 2;
	public static final int F_NOFORCE = 4;

	private HashMap theEntities = 
		new HashMap();		// String -> Character
	private HashMap theElementTypes = 
		new HashMap();		// String -> ElementType

	private String theURI = "";
	private String thePrefix = "";
	private ElementType theRoot = null;

	/**
	Add or replace an element type for this schema.
	@param name Name (Qname) of the element
	@param model Models of the element's content as a vector of bits
	@param memberOf Models the element is a member of as a vector of bits
	@param flags Flags for the element
	**/

	public void elementType(String name, int model, int memberOf, int flags) {
		ElementType e = new ElementType(name, model, memberOf, flags, this);
		theElementTypes.put(name.toLowerCase(), e);
		if (memberOf == M_ROOT) theRoot = e;
		}

	/**
	Get the root element of this schema
	**/

	public ElementType rootElementType() {
		return theRoot;
		}

	/**
	Add or replace a default attribute for an element type in this schema.
	@param elemName Name (Qname) of the element type
	@param attrName Name (Qname) of the attribute
	@param type Type of the attribute
	@param value Default value of the attribute; null if no default
	**/

	public void attribute(String elemName, String attrName,
				String type, String value) {
		ElementType e = getElementType(elemName);
		if (e == null) {
			throw new Error("Attribute " + attrName +
				" specified for unknown element type " +
				elemName);
			}
		e.setAttribute(attrName, type, value);
		}

	/**
	Specify natural parent of an element in this schema.
	@param name Name of the child element
	@param parentName Name of the parent element
	**/

	public void parent(String name, String parentName) {
		ElementType child = getElementType(name);
		ElementType parent = getElementType(parentName);
		if (child == null) {
			throw new Error("No child " + name + " for parent " + parentName);
			}
		if (parent == null) {
			throw new Error("No parent " + parentName + " for child " + name);
			}
		child.setParent(parent);
		}

	/**
	Add to or replace a character entity in this schema.
	@param name Name of the entity
	@param value Value of the entity
	**/

	public void entity(String name, int value) {
		theEntities.put(name, new Integer(value));
		}

	/**
	Get an ElementType by name.
	@param name Name (Qname) of the element type
	@return The corresponding ElementType
	**/

	public ElementType getElementType(String name) {
		return (ElementType)(theElementTypes.get(name.toLowerCase()));
		}

	/**
	Get an entity value by name.
	@param name Name of the entity
	@return The corresponding character, or 0 if none
	**/

	public int getEntity(String name) {
//		System.err.println("%% Looking up entity " + name);
		Integer ch = (Integer)theEntities.get(name);
		if (ch == null) return 0;
		return ch.intValue();
		}

	/**
	Return the URI (namespace name) of this schema.
	**/

	public String getURI() {
		return theURI;
		}

	/**
	Return the prefix of this schema.
	**/

	public String getPrefix() {
		return thePrefix;
		}

	/**
	Change the URI (namespace name) of this schema.
	**/

	public void setURI(String uri) {
		theURI = uri;
		}

	/**
	Change the prefix of this schema.
	**/

	public void setPrefix(String prefix) {
		thePrefix = prefix;
		}

	}
