package drawing;

import java.util.Vector;

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

/**
 * this class build the classUnits and links for the UML diagram from an xml file or a dom document 
 * @author  MC
 */
public class BuilderDiagram {
	public Diagram dia;
	private String xmlFileName;
	
	/**
	 * constructor
	 * @param name
	 */
	public BuilderDiagram(String name){
		xmlFileName = name;
		dia = new Diagram();
	}
	/**
	 * constructor
	 * @param doc
	 */
	public BuilderDiagram(Document doc){
		dia = new Diagram();
		Node root = doc.getDocumentElement();
		UnitClass u = new UnitClass("DIM");
		dia.add(u);
		parseNode(root, u);
		dia.initNbInstancetemp(null);
	}
	/**
	 * parses the XML file
	 *
	 */
	public void parseXml(){
		XMlXSLTClass xmlClass = new XMlXSLTClass();
		Document doc = xmlClass.readXMLFile(xmlFileName);
		Node root = doc.getDocumentElement();
		UnitClass u = new UnitClass("DIM");
		dia.add(u);
		parseNode(root, u);
		dia.initNbInstancetemp(null);
	}
	/**
	 * add the link between an class and its parent
	 * @param u the child class
	 * @param parent the parent class
	 */
	private void add(UnitClass u, UnitClass parent){
		Link l;
		if(!dia.contains(u))
		{
			dia.add(u);
			l = new Link(dia.getUnitClass(parent), u);
		}
		else
			l = new Link(parent, dia.getUnitClass(u));
		
		dia.add(l);
			
	}
	/**
	 * parses the node 
	 * @param root
	 * @param parent
	 */
	private void parseNode(Node root, UnitClass parent)
	{
		String moc;
		UnitClass u = null;
		UnitClass p = parent;
		Vector vectSaveNbInstances = new Vector();
		boolean autoRefer = false;
		vectSaveNbInstances = dia.getNbInstanceTemp(p);
		if (root.hasChildNodes()){
	         NodeList children;                
	         int numChildren;
	         Node node;
	         children = root.getChildNodes();
	         numChildren = children.getLength();
	         
	        
	         for (int j=0; j < numChildren; j++) {
	        	 node = children.item(j);                 
		         if (node != null) {                     
		 	          if (node.getNodeType() == Node.ELEMENT_NODE) {
		 	        	  // MOC object name
		 	        	  if (node.getNodeName().equals("OBJECT_NAME")) {
		 	        		  moc = node.getFirstChild().getNodeValue();
		 	        		  String label = null;
		 	        		  if(node.getAttributes().getNamedItem("Label").getFirstChild() != null)
		 	        			  label = node.getAttributes().getNamedItem("Label").getFirstChild().getNodeValue();
		 	        		  if(label != null && !label.equals("")){
			 	        		  moc += ":";
			 	        		  moc += node.getAttributes().getNamedItem("Label").getFirstChild().getNodeValue();
		 	        		  }
		 	        		  u = new UnitClass(moc);
		 	        		  
		 	        		  add(u, p);
		 	        		 
		 	        		 if(dia.contains(u))
		 	        			 dia.initNbInstancetemp(u);
		 	        		  
		 	                if(p.isEqual(u)){
		 	                	autoRefer = true;
		 	                }
		 	        		 
		 	        		  p = u;
		 	        		 
		 	        	  }		 	        	  
		 	        	  else
		 	        	  {       		  
		 	        		  // recursivity
		 	        		  parseNode(node, p);
			            	  		            			 
		 	        	  }
		 	          }
		         }
	         }
	         // when there is autorefernce to an object we must restore the cardinality of the parent 
	         if(autoRefer){
		         dia.initNbInstancetemp(p);
		         dia.setNbInstancesTemp(vectSaveNbInstances);
	         }
	      }
	}
}

