/**
 * This class holds all the data.
 * 
 * Ref.: Lozano, L. and Smith, J. C. (2014). 
 * A Backward Sampling Framework for Interdiction Problems with Fortification
 * 
 * @author L. Lozano & J. C. Smith
 * @affiliation Clemson University
 * @url www.leo-loza.com
 * 
 */
package backwardSampling;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Random;
import java.util.StringTokenizer;

import sampling.FinalNode;
import sampling.Node;
import sampling.PulseGraph;

public class DataHandler {
	// Name of the instance
	String CvsInput;
	// Number of arcs
	int numArcs;
	// Number of nodes
	public static int numNodes;
	// Destinantion node
	public int lastNode;
	// Source node
	public int source;
	// All the arcs in the network stored in a vector where Arcs[i][0]= Tail for arc i and Arcs[i][1]= Head for arc i 
	public static int[][] arcs;
	// The distance attribute for any arc i
	public static int[] cost;
	// The delay attribute for any arc i
	public static int[] delay;
	// Data structure for storing the graph
	private PulseGraph Gd;
	
	static int dBudget;
	static int aBudget;
	public static int[] arcCount;
	
	// Read data from an instance
	public DataHandler(Settings Instance) {
		CvsInput = Instance.DataFile;
		numArcs = Instance.NumArcs;
		numNodes = Instance.NumNodes;
		lastNode = Instance.LastNode;
		source = Instance.Source;
		arcs = new int[Instance.NumArcs][2];
		cost = new int[Instance.NumArcs];
		delay = new int[Instance.NumArcs];
		arcCount = new int[Instance.NumArcs];
		Gd = new PulseGraph(numNodes);
		dBudget = 0;
		aBudget = 0;
	}

		
// This procedure creates the nodes for the graph
	public void upLoadNodes(){
		// All nodes are VertexPulse except the final node
		for (int i = 0; i < numNodes; i++) {
			if(i!=(lastNode)){
				Gd.addVertex(new Node(i) );
			}
		}
		// The final node is a FinalVertexPulse 
		FinalNode vv = new FinalNode(lastNode);
		Gd.addFinalVertex(vv);
	}
	
	// This procedure returns a graph
	public PulseGraph getGd()
	{
		return Gd;
	}

	// This procedure reads data from a data file in DIMACS format
	public void ReadDimacs() throws NumberFormatException, IOException {
		File file = new File(CvsInput);

		BufferedReader bufRdr = new BufferedReader(new FileReader(file));
		String line = null;

		String[] readed = new String[5];

		int row = 0;
		int col = 0;
		
		upLoadNodes();
		
		while ((line = bufRdr.readLine()) != null && row < numArcs + 3) {
			StringTokenizer st = new StringTokenizer(line, " ");
			while (st.hasMoreTokens()) {
				// get next token and store it in the array
				readed[col] = st.nextToken();
				col++;
			}

			if (row >= 3) {
				arcs[row - 3][0] = (Integer.parseInt(readed[1]) );
				arcs[row - 3][1] = (Integer.parseInt(readed[2]) );
				cost[row - 3] = Integer.parseInt(readed[3]);
				delay[row - 3] = Integer.parseInt(readed[4]);
				// Add edges to the network
				Gd.addWeightedEdge( Gd.getVertexByID(arcs[row - 3][0]), Gd.getVertexByID(arcs[row - 3][1]),cost[row - 3], delay[row - 3] , row-3);
			}

			col = 0;
			row++;

		}
		
	}
	
}

