package com.westgroup.morpheus.xparser.inputrules;

import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xml.serialize.*;

import java.util.*;

public class RulesBuilder {
	 private Hashtable midStartTable;
	 private Hashtable layoutTable;
	 boolean isDefault;

	 public RulesBuilder () {System.err.println ("constructing RulesBuilder...");}

	 protected void buildRules (Node node) throws DOMException {
		  switch (node.getNodeType ()) {
		  case Node.DOCUMENT_NODE:
				buildRules (((Document) node).getDocumentElement ());
				break;
		  case Node.ELEMENT_NODE:
				for (Node child = node.getFirstChild (); child != null;
					  child = child.getNextSibling ()) {
					 buildRules (child);
				}

				Element current = (Element) node;
				if (current.getTagName().equals("m:default")) {
				    isDefault = true;
				}
				String mid = current.getAttribute ("m:id");
				String start = null;
				String end = null;
				Hashtable layout = (Hashtable) layoutTable.get (mid);

				if ( layout != null ) {
			        if (layout.containsKey("start"))
					    start = (String) layout.get("start");
					if (layout.containsKey("end"))
					    end = (String) layout.get("end");
					    
					if (start != null && !start.equals("") && 
					    end != null && !end.equals("")) {

                        Hashtable startend = new Hashtable();
                        startend.put("start",start);
                        startend.put("end",end);
                        
                        midStartTable.put (mid, startend);
					 }
			    }
				break;
		  default:
		  }
	 }

	 protected void buildLayout (Node node) {
		  switch (node.getNodeType ()) {
		  case Node.DOCUMENT_NODE:
			   buildLayout (((Document) node).getDocumentElement ());
				break;
		  case Node.ELEMENT_NODE:
				for (Node child = node.getFirstChild (); child != null;
					  child = child.getNextSibling ()) {
					 buildLayout (child);
				}

				Element current = (Element) node;
				String mid = current.getAttribute ("m:id");

				NamedNodeMap attributes = current.getAttributes ();
				Hashtable attPairTable = new Hashtable ();
				for (int i=0; i < attributes.getLength (); i++) {
					 Node att = attributes.item (i);
					 String key = att.getNodeName ();
					 String value = att.getNodeValue ();
					 attPairTable.put (key, value);
				}
				layoutTable.put (mid, attPairTable);

		  default:
				break;
		  }
	 }

	 public InputRules parseRulesFiles (String rules, String layout) {
		  midStartTable = new Hashtable ();
		  layoutTable = new Hashtable ();
		  isDefault = false;

          System.err.println ("called parseRulesFiles...");
		  try {
				System.err.println ("creating a new DOMParser for layout...");
				DOMParser lparser = new DOMParser ();
				System.err.println ("parsing layout...");
				lparser.parse (layout);

				System.err.println ("creating a new DOMParser for rules...");
				DOMParser rparser = new DOMParser ();
				System.err.println ("parsing rules...");
				rparser.parse (rules);

				buildLayout (lparser.getDocument ());
				buildRules (rparser.getDocument ());
				return new FieldedInputRules (rparser.getDocument (),
											  new Hashtable (midStartTable),
											  isDefault);
		  } catch (Exception e) {
				e.printStackTrace ();
				System.exit (1);
		  }
		  return new FieldedInputRules ();
	 }

	 private Hashtable cloneTable (Hashtable table) {
		  Hashtable newTable = new Hashtable ();

		  Enumeration keys = table.keys ();
		  for (Enumeration values = table.elements ();
				 keys.hasMoreElements () && values.hasMoreElements ();) {
				newTable.put (keys.nextElement (), values.nextElement ());
		  }

		  return newTable;
	 }

	 private void dump (Document doc) {
		  OutputFormat of = new OutputFormat ();
		  XMLSerializer serial = new XMLSerializer (System.out, of);

		  try {
				System.err.println ("");
				serial.serialize (doc);
		  } catch (Exception e) {
				e.printStackTrace ();
				System.exit (1);
		  }
	 }
}


