package com.jxml.quick.util.dtd2qdml;
import com.wutka.dtd.*;
import com.jxml.quick.*;
import org.xml.sax.*;
import java.util.*;
import com.jxml.quick.ocm.*;
import java.io.*;

/**
 * Extracts DTD data.
 */
public class QCDTD extends OCMrootPeerSupport
{
	/**
	 * User-provided code to perform the conversion.
	 */
	public void cvt(Object param)
		throws SAXException, IOException
	{
		DTD dm=(DTD)dataModel;
		List items=dm.items;
		HashMap elementPeers=new HashMap();
		int s=items.size();
		int i;
		boolean hasAny=false;

		// Build table of elements
		for (i=0;i<s;++i)
		{
			Object o=items.get(i);
			if (o instanceof DTDElement)
			{
				DTDElement el=(DTDElement)o;
				if (el.content instanceof DTDAny)
					hasAny=true;
				Object p=peer(el);
				if (p!=null)
					elementPeers.put(el.name,p);
			}
		}

		// Add attributes to elements
		for (i=0;i<s;++i)
		{
			Object o=items.get(i);
			if (o instanceof DTDAttlist)
			{
				DTDAttlist atl=(DTDAttlist)o;
				String name=atl.name;
				QCDTDElement pe=(QCDTDElement)elementPeers.get(name);
				if (pe!=null)
				{
					int j;
					int t=atl.attributes.size();
					for (j=0;j<t;++j)
					{
						DTDAttribute at=(DTDAttribute)atl.attributes.get(j);
						pe.cvt(at);
					}
				}
			}
		}

		// Add comments to elements and attributes
		ArrayList comments=new ArrayList();
		for (i=0;i<s;++i)
		{
			Object o=items.get(i);
			if (o instanceof DTDComment)
			{
				try
				{
					DTDComment c=(DTDComment)o;
					String text=c.text;
					byte[] bytes=text.getBytes();
					ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
					InputStreamReader isr=new InputStreamReader(bais);
					BufferedReader br=new BufferedReader(isr);
					String line;
					for (line=br.readLine();line!=null;line=br.readLine())
						if (line.trim().length()>0)
							comments.add(line);			
				}
				catch (Exception e)
				{
				}
			}
			else if (o instanceof DTDElement)
			{
				doCvt(o,comments);
				comments=new ArrayList();
			}
			else if (o instanceof DTDAttlist)
			{
				DTDAttlist atl=(DTDAttlist)o;
				if (atl.attributes.size()>0)
				{
					Object a=atl.attributes.get(0);
					doCvt(a,comments);
				}
				comments=new ArrayList();
			}
		}

		startElement("qdml");

		if (hasAny)
		{
			addStringAttribute("label","#any");
			addStringAttribute("type","BIMODAL");
			addBooleanAttribute("wild",true);
			startElement("bean");
			startElement("attributes");
			addStringAttribute("coin","#any.attribute");
			addBooleanAttribute("optional",true);
			addBooleanAttribute("repeating",true);
			startElement("item");
			endElement("item");
			endElement("attributes");
			startElement("elements");
			addStringAttribute("coin","#any");
			addBooleanAttribute("optional",true);
			addBooleanAttribute("repeating",true);
			startElement("item");
			endElement("item");
			endElement("elements");
			endElement("bean");
			addStringAttribute("label","#any.attribute");
			addBooleanAttribute("wild",true);
			startElement("text");
			endElement("text");
		}

		// convert elements
		for (i=0;i<s;++i)
		{
			Object o=items.get(i);
			if (o instanceof DTDElement)
			{
				DTDElement el=(DTDElement)o;
				doCvt(el,this);
			}
		}
		endElement("qdml");
	}
}
