/**
 * This class represents a graph. It is used for the SP and the pulse!!!
 * 
 * Ref.: Lozano, L. and Medaglia, A. L. (2013). 
 * On an exact method for the constrained shortest path problem. Computers & Operations Research. 40 (1):378-384.
 * DOI: http://dx.doi.org/10.1016/j.cor.2012.07.008 
 * 
 * 
 * @author L. Lozano & D. Duque
 * @affiliation Universidad de los Andes - Centro para la Optimización y Probabilidad Aplicada (COPA)
 * @url http://copa.uniandes.edu.co/
 * 
 */
package sampling;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;

import org.jgrapht.EdgeFactory;
import org.jgrapht.Graph;

import backwardSampling.DataHandler;

public class PulseGraph  implements Graph<Node, EdgePulse> {
	
	// The nodes
	static Node[] vertexes;
	// Number of nodes
	private int numNodes;
	//SP stuff
	private int Cd;
	private int Ct;
	// Time constraint
	static double TimeC;
	// Primal bound
	public static double PrimalBound;
	// The best solution found is globally stored here 
	static ArrayList<Integer> Path;
	// The time for the best solution found (the distance is stored in the primal bound)
	public static double realDist;
	// Binary indicator to know if visiting a node creates a cycle
	static int[] Visited;
	public static double obj;
	public static double width;
	
	public PulseGraph( int numNodes) {
		super();
		this.numNodes = numNodes;
		Cd=0;
		Ct=0;
		vertexes = new Node[numNodes];
		Path= new ArrayList<Integer>();
		Visited = new int[numNodes];
		this.TimeC=Double.POSITIVE_INFINITY;
	}
	@Override
	public EdgePulse addEdge(Node sourceVertex, Node targetVertex) {
		// TODO Auto-generated method stub
		return null;
	}
	
	public  int getNumNodes()
	{
		return numNodes;
	}
	public Node getVertexByID(int id){
		return vertexes[id];
	}
	
	public EdgePulse addWeightedEdge(Node sourceVertex, Node targetVertex, int d, int t, int id) {
		if(d>Cd){
			Cd=d;
		}
		if(t>Ct){
			Ct=t;
		}
		vertexes[targetVertex.getID()].addReversedEdge(new EdgePulse(d, t, targetVertex , sourceVertex, id));
		vertexes[sourceVertex.getID()].magicIndex.add(id);
		return null;
	}
	
	
	@Override
	public boolean addEdge(Node sourceVertex, Node targetVertex, EdgePulse e) {
		return false;
	}

	@Override
	public boolean addVertex(Node v) {
		vertexes[v.getID()] = v;
		return true;
	}
	public boolean addFinalVertex(FinalNode v) {
		vertexes[v.getID()] = v;
		return true;
	}

	@Override
	public boolean containsEdge(Node sourceVertex,
			Node targetVertex) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsEdge(EdgePulse e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean containsVertex(Node v) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Set<EdgePulse> edgeSet() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<EdgePulse> edgesOf(Node vertex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Set<EdgePulse> getAllEdges(Node sourceVertex,
			Node targetVertex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public EdgePulse getEdge(Node sourceVertex, Node targetVertex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public EdgeFactory<Node, EdgePulse> getEdgeFactory() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Node getEdgeSource(EdgePulse e) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Node getEdgeTarget(EdgePulse e) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public double getEdgeWeight(EdgePulse e) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public boolean removeAllEdges(Collection<? extends EdgePulse> edges) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Set<EdgePulse> removeAllEdges(Node sourceVertex,
			Node targetVertex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean removeAllVertices(Collection<? extends Node> vertices) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public EdgePulse removeEdge(Node sourceVertex,
			Node targetVertex) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean removeEdge(EdgePulse e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean removeVertex(Node v) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Set<Node> vertexSet() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	public int getCd()
	{
		return Cd;
	}
	public int getCt()
	{
		return Ct;
	}
	
	public void resetNetwork(){
		PrimalBound=Double.POSITIVE_INFINITY;
		realDist=Double.POSITIVE_INFINITY;
		for (int i = 0; i < numNodes ; i++) {
			vertexes[i].reset();
		}
	}
	
	public void SetConstraint(double timeC) {
		
		this.TimeC=timeC;
		
	}
	public void setPrimalBound(int bound) {
		
		this.PrimalBound=bound;
		
	}
	public void setObj(double obj) {
		this.obj = obj;
		
	}
	public void setWidth(double d) {
		this.width = d;
		
	}
	
	


}
