package units;


import java.util.Collections;
import java.util.HashMap;
import java.util.Vector;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import dataTypeInterface.XMlXSLTClass;

/**
 * this class builds the available units from the xml configuration file
 * @author MC
 *
 */
public class UnitsBuilder {
	static protected Vector<Unit> vectUnits= null;
	static protected HashMap<Integer, String> vectMagnetude= null;
	static final String xmlFileUnit = "../xml/11073UCUM.xml";
	static final String xmlFileMagnetude = "../xml/11073magnetude.xml";
	public static void init(){
		if(vectUnits == null){
			//parse xml file of units
			XMlXSLTClass xmlClass = new XMlXSLTClass();
			Document doc1 =  xmlClass.readXMLFile(xmlFileUnit);
			Document doc2 =  xmlClass.readXMLFile(xmlFileMagnetude);
			vectUnits = new Vector<Unit>();
			vectMagnetude = new HashMap<Integer, String>();
			
			Node root = doc1.getDocumentElement();
			Node root2 = doc2.getDocumentElement();
			
			parseNodeMagnetude(root2);
			parseNodeUnits(root);
			
		}
	}
	
	private static void parseNodeMagnetude(Node root) {
		if (root.hasChildNodes()){
	         NodeList children;
	         int numChildren;
	         Node node;
	         children = root.getChildNodes();
	         numChildren = children.getLength();
	         for (int i=0; i < numChildren; i++) {
	        	 node = children.item(i);                 
		         if (node != null) {                     
		 	          if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName() == "Magnetude-info") {
		 	        	  String name ="";
		 	        	  int offset = -1;
		 	        	  NodeList listUnitproperties = node.getChildNodes();
		 	        	  for( int j = 0; j < listUnitproperties.getLength(); j++){
		 	        		 Node nodeUnit = listUnitproperties.item(j);
		 	        		 
		 	        		 if (nodeUnit.getNodeType() == Node.ELEMENT_NODE)
		 	        			 if(nodeUnit.getNodeName() == "Name") {	 	        				 
		 	        				 name = nodeUnit.getTextContent();	 	        				 	        				 
		 	        			 } 
		 	        			 else if (nodeUnit.getNodeName() == "Code-Offset") {
		 	        				 offset = Integer.parseInt(nodeUnit.getTextContent());
		 	        			 }
		 	    
			 	        	  }
		 	        	  		if(offset != -1)
		 	        	  			vectMagnetude.put(offset, name); 	        		 
	 	        	  	
	 	        	  }
	 	          }
	         }
	     }
		
	}

	static private void parseNodeUnits(Node root){
		if (root.hasChildNodes()){
	         NodeList children;
	         int numChildren;
	         Node node;
	         children = root.getChildNodes();
	         numChildren = children.getLength();
	         for (int i=0; i < numChildren; i++) {
	        	 node = children.item(i);                 
		         if (node != null) {                     
		 	          if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName() == "Nomenclature_Info") {
		 	        	 Unit unitObj = new Unit();
		 	        	  NodeList listUnitproperties = node.getChildNodes();
		 	        	  for( int j = 0; j < listUnitproperties.getLength(); j++){
		 	        		 Node nodeUnit = listUnitproperties.item(j);
		 	        		 
	 	        		 if (nodeUnit.getNodeType() == Node.ELEMENT_NODE)
	 	        			 if(nodeUnit.getNodeName() == "Reference_Id") {
	 	        				 String termCode = nodeUnit.getAttributes().getNamedItem("Term_Code").getNodeValue();
	 	        				 String referenceId = nodeUnit.getTextContent();
	 	        				 unitObj.setTermCode(Integer.parseInt(termCode.trim()));
	 	        				 unitObj.setReferenceId(referenceId);
	 	        				 
	 	        			 } 
	 	        			 else if (nodeUnit.getNodeName() == "UnitofMeasurement") {
	 	        				 unitObj.setUnitofMeasurement(nodeUnit.getTextContent());
	 	        			 }
	 	        			 else if (nodeUnit.getNodeName() == "Symbol") {
	 	        				 unitObj.setSymbol(nodeUnit.getTextContent());
	 	        			 }
	 	        			 else if (nodeUnit.getNodeName() == "UCUM") {
	 	        				 unitObj.setUcum(nodeUnit.getTextContent());
		        			 }
		 	        	  }
		 	        	  addUnit(unitObj);
	 	        		 
	 	        	  	
	 	        	  }
	 	          }
	         }
	         // we sort our unit vector from low to high code
	         Collections.sort(vectUnits);
	     }
	}
	
	private static void addUnit(Unit unitObj) {
		vectUnits.add(unitObj);		 		
	}

	static public Unit getUnit(int termCode){
		init();
		Unit unitObj = null;
		Unit unitRes = null;
		boolean found = false;
		boolean notRecognized = false; 
		int i = 0;
		while(!found && i < vectUnits.size()){
			unitObj = vectUnits.get(i);
			if(unitObj.getTermCode() > termCode){
				found = true;
				unitObj = vectUnits.get(i - 1);
			}
			i++;
		}
		if(found){
			unitRes = new Unit(unitObj);
			Integer offset = new Integer(- unitObj.termCode + termCode);
			String magnetude;
			if(vectMagnetude.containsKey(offset)){
				magnetude = vectMagnetude.get(offset);
				unitRes.setTermCode(termCode);
				String reference = unitRes.getReferenceId();
				if(reference.contains("_X_")){
					if(magnetude != "")
						reference = reference.replace("_X_", "_"+magnetude.toUpperCase()+"_");
					else if (reference != "")
						reference = reference.replace("_X_", "");
					unitRes.setReferenceId(reference);
				}
				else if(offset != 0){
					// not recognized
					notRecognized = true;
				}
			}
			else{
				//not recognized
				notRecognized = true;
			}
		}
		else{
			//not recognized
			notRecognized = true;
		}
		
		if(unitObj == null || notRecognized){
			unitRes = new Unit();
			unitRes.termCode = termCode;
		}
		return unitRes;
	}
	
	
}

