package com.jxml.quick.model.qdml;
import com.jxml.quick.ocm.*;
import com.jxml.quick.*;
import org.xml.sax.*;
import java.util.*;
import java.io.*;

/**
 * <p>
 * Models the element coin, which represents a family of elements in QDML
 * that are used to define XML elements and attributes.
 * Corrispondingly, QDMCoin serves as a base class 
 * for classes which model that family of QDML elements.
 * (The inheritance model used by QDML is the same model used by Java.)
 * </p>
 */
public abstract class QDMCoin extends QDMCloneable
{
	/**
	 * <p>
	 * Models the attribute label, a required attribute on the coin element.
	 * The label uniquely (within a document) names a coin.
	 * </p>
	 */
	public String label="";

	/**
	 * Models the generate attribute, an optional attribute which defaults to true.
	 * When set to false, the production of Java code for the class described by the
	 * coin is inhibited.
	 */
	public boolean generate=true;

	/**
	 * A container for QDMRem objects, which model rem elements.
	 * The rem elements are optional and repeating.
	 * When a class is generated from the coin, the rem elements are used
	 * to produce the JavaDoc comment which describes the class.
	 */
	public ArrayList remList=new ArrayList();

	/**
	 * <p>
	 * A list of all the coins which extend this one.
	 * This list is populated when the data model is initialized.
	 * </p>
	 */
	public transient ArrayList extensions=new ArrayList();

	/**
	 * <p>
	 * A list of all the coins which implement this one.
	 * This list is populated when the data model is initialized.
	 * </p>
	 */
	public transient ArrayList implementations=new ArrayList();

	/**
	 * Returns a deep copy of this object, but in an uninitialized form.
	 */
	public Object clone()
	{
		QDMCoin rv=(QDMCoin)super.clone();
		rv.remList=clone(remList);
		rv.extensions.clear();
		rv.implementations.clear();
		return rv;
	}

	/**
	 * Returns the unique (within the scope of the QDML document) name of the coin,
	 * as specified by the coin's label.
	 */
	public String getLabel()
	{
		return label;
	}

	/**
	 * Builds the maps.
	 * This method is called during initialization of the data model.
	 */
	public void buildMaps(Map coinMap, Map contentMap)
		throws SAXException
	{
	}

	/**
	 * Resolve references, inheritance.
	 * This method is called during initialization of the data model.
	 */
	public void init(Map coinMap, Map contentMap)
		throws SAXException
	{
	}

	public void addDecendants(ArrayList bl)
	{
		bl.add(this);
		int i,s;
		s=implementations.size();
		for(i=0;i<s;++i)
		{
			QDMCoin c=(QDMCoin)implementations.get(i);
			c.addDecendants(bl);
		}
		s=extensions.size();
		for(i=0;i<s;++i)
		{
			QDMCoin c=(QDMCoin)extensions.get(i);
			c.addDecendants(bl);
		}
	}

	public ArrayList getConcreteDecendants()
	{
		ArrayList bl=new ArrayList();
		addDecendants(bl);
		ArrayList rv=new ArrayList();
		int i,s;
		s=bl.size();
		for (i=0;i<s;++i)
		{
			QDMCoin coin=(QDMCoin)bl.get(i);
			if (coin instanceof QDMText 
			|| coin instanceof QDMBean 
			|| coin instanceof QDMLink)
				rv.add(coin);
		}
		return rv;
	}

	public boolean derivesFromOther(String label, TreeMap coinMap)
	{
		String l=getLabel();
		if (label.equals(l))
			return true;
		ArrayList bl=new ArrayList();
		addDecendants(bl);
		int i,s;
		s=bl.size();
		for (i=0;i<s;++i)
		{
			QDMCoin coin=(QDMCoin)bl.get(i);
			l=coin.getLabel();
			if (label.equals(l))
				return true;
		}
		return false;
	}
}
