package network.importnetwork;
/**
 * @author Ansleliu
 *
 */
import graph.Vertex;

import java.io.File;
import java.util.List;

import network.Junction;
import network.Link;
import network.Network;
import network.OD;
import network.ODMatrix;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class ImportLocalNetImplement
{
	//~Variables
	//--------------------------------------------------------------------------
	private Document document = null;
	private Network network = new Network(); //Network to Storage
	private ODMatrix odMatrix = new ODMatrix();

	//~Methods
	//--------------------------------------------------------------------------
	/**
	 * 构造函数
	 * @param filename
	 */
	public ImportLocalNetImplement(final String filename)
	{
		loadXML(filename);
	}
	
	/**
	 * Load XML File, Read it into Document
	 * @param filename
	 * 		The Name of the file which will be analysis
	 */
	public Document loadXML(final String filename)
	{
		//Document document = null;
		try 
		{
			final SAXReader saxReader = new SAXReader();
			document = saxReader.read(new File(filename));
		}
		catch (final Exception ex)
		{
			ex.printStackTrace();
		}
		return document;
	}
	
	/**
	 * 存储路网到Network
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Network networkStorage()
	{
		final Element root = document.getRootElement();
		final List<Element> junctionList = root.selectNodes(LocalXmlAttributeMatch.JUNCTION); 
		final List<Element> extLinkList = root.selectNodes(LocalXmlAttributeMatch.EXTLINK);
		final List<Element> originList = root.selectNodes(LocalXmlAttributeMatch.ORIGIN);
		addJunctionToNetwork(junctionList);
		addExtLinkToNetwork(extLinkList);
		addODToODMatrix(originList);
		return network;
	}
	
	/**
	 * 添加路口到路网
	 * @param junctionList
	 */
	@SuppressWarnings("unchecked")
	private void addJunctionToNetwork(List<Element> junctionList)
	{
		final int junctionListSize = junctionList.size();
		System.out.println("Junction's count: " + junctionListSize); 
		for(int i = 0; i<junctionListSize; i++)
		{
			Junction junction = null;
			//Get a Junction from the Junction List
			Element element = junctionList.get(i);
			
			List<Attribute> listJunctionAttribute = element.attributes();
			String id = listJunctionAttribute.get(0).getValue();
			String type = listJunctionAttribute.get(1).getValue();
			String x = listJunctionAttribute.get(2).getValue();
			String y = listJunctionAttribute.get(3).getValue();
			String intNode = listJunctionAttribute.get(4).getValue();
			
			junction = new Junction(id);		//设置路口名
			junction.setType(type);     			//设置路口类型
			junction.setX_Coordinate(Double.parseDouble(x));	//设置路口X坐标
			junction.setY_Coordinate(Double.parseDouble(y));	//设置路口Y坐标
			
			//添加内部节点到路口
			//---------------------------------------------------
			intNode = intNode.replace("[", "");
			intNode = intNode.replace("]", "");
			String[]intNodes = intNode.split(", ");
			for(int p=0; p<intNodes.length; p++)
			{
				String[] node = intNodes[p].split(" ");
				
				Vertex interNode = null;	//内部连接的点
				interNode = new Vertex(node[0],"Internal",
										Double.parseDouble(node[1]),
										Double.parseDouble(node[2]));
				junction.addInternalNode(interNode);
			}

			//添加内部连接到路口
			//-----------------------------------------------------
			List<Element> intLinkList = element.selectNodes(LocalXmlAttributeMatch.INTCONNECTION);
			int numIntLink = intLinkList.size();	
			for(int j = 0; j<numIntLink; j++)
			{
				List<Attribute> listIntLinkAttribute = intLinkList.get(j).attributes();
				String intLinkID = listIntLinkAttribute.get(0).getValue();					//内部连接名
				String intLinkNumLanes = listIntLinkAttribute.get(1).getValue();	//车道数
				String intLinkFrom = listIntLinkAttribute.get(2).getValue();			//起点
				String intLinkFromX = listIntLinkAttribute.get(3).getValue();			//起点X坐标
				String intLinkFromY = listIntLinkAttribute.get(4).getValue();			//起点Y坐标
				String intLinkTo = listIntLinkAttribute.get(5).getValue();				//终点
				String intLinkToX = listIntLinkAttribute.get(6).getValue();				//终点X坐标
				String intLinkToY = listIntLinkAttribute.get(7).getValue();				//终点Y坐标
				String dir = listIntLinkAttribute.get(8).getValue();							//转向信息
				
				Vertex interFromNode = null;	//内部连接的点
				interFromNode = new Vertex(intLinkFrom,"Internal",
											Double.parseDouble(intLinkFromX),
											Double.parseDouble(intLinkFromY));
				Vertex interToNode = null;	//内部连接的点
				interToNode = new Vertex(intLinkTo,"Internal",
										  Double.parseDouble(intLinkToX),
										  Double.parseDouble(intLinkToY));
				
				junction.addInternalEdge(interFromNode, interToNode);
				//添加内部连接到路口
				//---------------------------------------------------
				Link link = new Link(interFromNode,interToNode);
				link.setName(intLinkID);
				link.setLinkType("Internal");
				link.setLaneCount(Integer.parseInt(intLinkNumLanes));
				link.setDirection(dir);
				
				network.addLink(link);
			}	
			//添加路口到网络
			network.addJunction(junction);
		}
	}
	
	/**
	 * 添加外部连接到路网
	 * @param extLinkList
	 */
	@SuppressWarnings("unchecked")
	private void addExtLinkToNetwork(List<Element> extLinkList)
	{
		final int extLinkListSize = extLinkList.size();
		System.out.println("ExtLink's count: " + extLinkListSize); 
		for(int i = 0; i<extLinkListSize; i++)
		{
			//Get a node from the node list
			Element element = extLinkList.get(i);
			
			List<Attribute> listExtLinkAttribute = element.attributes();
			String id = listExtLinkAttribute.get(0).getValue();
			//String fromJunction = listExtLinkAttribute.get(1).getValue();
			//String toJunction = listExtLinkAttribute.get(2).getValue();
			String numLanes = listExtLinkAttribute.get(3).getValue();
			String speed = listExtLinkAttribute.get(4).getValue();
			String length = listExtLinkAttribute.get(5).getValue();

			Vertex linkStartNodeVertex = null;	//连接的起点
			Vertex linkEndNodeVertex = null;  	//连接的终点
			
			List<Element> extConnectionList = element.selectNodes(LocalXmlAttributeMatch.EXTCONNECTION);
			//int numExtConnection = extConnectionList.size();	
			
			List<Attribute> listExtConnectionAttribute = extConnectionList.get(0).attributes();
			String fromNode = listExtConnectionAttribute.get(0).getValue();		//外部连接内部起点
			String from_x = listExtConnectionAttribute.get(1).getValue();  			//起点X坐标
			String from_y = listExtConnectionAttribute.get(2).getValue();  			//起点Y坐标
			String toNode = listExtConnectionAttribute.get(3).getValue();  		//外部连接内部终点
			String to_x = listExtConnectionAttribute.get(4).getValue();	   			//终点X坐标
			String to_y = listExtConnectionAttribute.get(5).getValue();    			//终点Y坐标
			String dir = listExtConnectionAttribute.get(6).getValue();	   				//转向信息

			linkStartNodeVertex = new Vertex(fromNode,"Internal",
					Double.parseDouble(from_x),
					Double.parseDouble(from_y));
			linkEndNodeVertex = new Vertex(toNode,"Internal",
					Double.parseDouble(to_x),
					Double.parseDouble(to_y));
			
			//添加外部连接到路网
			//-----------------------------------------------------------
			Link link = new Link(linkStartNodeVertex, linkEndNodeVertex);
			link.setDirection(dir);
			link.setName(id);
			link.setLaneCount(Integer.parseInt(numLanes));
			link.setLinkType("External");
			link.setSpeed(Double.parseDouble(speed));
			link.setLength(Double.parseDouble(length));
			
			network.addLink(link);
		}
	}

	@SuppressWarnings("unchecked")
	private void addODToODMatrix(List<Element> originList)
	{
		final int originListSize = originList.size();
		System.out.println("Origin's count: " + originListSize); 
		for(int i = 0; i<originListSize; i++)
		{
			Vertex orgV = null;		//连接的起点
					
			Element element = originList.get(i);
			String orgid = element.attribute("id").getValue();
			String orgx = element.attribute("x").getValue();
			String orgy = element.attribute("y").getValue();
			
			orgV = new Vertex(orgid,"Internal",Double.parseDouble(orgx),Double.parseDouble(orgy));
			
			List<Element> destinationList = element.selectNodes(LocalXmlAttributeMatch.DESTINATION);
			int destinationCount = destinationList.size();	
			for(int j = 0; j<destinationCount; j++)
			{
				Vertex desV = null;  	//连接的终点
				String demand = null;
				
				Element destinaton = destinationList.get(j);
				String desid = destinaton.attribute("id").getValue();
				String desx = destinaton.attribute("x").getValue();
				String desy = destinaton.attribute("y").getValue();
				demand = destinaton.attribute("demand").getValue();
				
				desV = new Vertex(desid,"Internal",Double.parseDouble(desx),Double.parseDouble(desy));
				OD od = new OD(orgV,desV,Double.parseDouble(demand));
				odMatrix.addOD(od);
			}
		}
	}
	
	/**
	 * @return network
	 */
	public Network getNetwork()
	{
		return network;
	}

	/**
	 * @return odMatrix
	 */
	public ODMatrix getODMatrix()
	{
		return odMatrix;
	}
}