package data.trainnetwork;

import org.jgrapht.graph.DefaultWeightedEdge;
import org.joda.time.LocalTime;
import org.json.simple.JSONObject;

import util.JSONTools;

import data.MissingParameterException;

/**
 * An {@link Edge} representing a path between two train {@link Stations} being part of a train line 
 * @author Balazs Pete
 *
 */
public class Section extends DefaultWeightedEdge {

	public enum ScoreMode {
		TravelTime, Cost, NumberOfHops 
	}
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 116967749447316838L;
	
	public static ScoreMode scoreMode = ScoreMode.TravelTime; 
	
	private String routeID;
	private LocalTime startTime;
	private long journeyLength;
	private int cost;
	private int maxPassengers;

	/**
	 * Create a new instance of {@link Section}
	 * @param routeID The ID of the train route the 
	 * @param startTime The time at which the train leaves the station
	 * @param journeyLength The length of the journey on the {@link Section}
	 */
	public Section(String routeID, LocalTime startTime, long journeyLength) {
		this.routeID = routeID;
		this.startTime = startTime;
		this.journeyLength = journeyLength;
	}
	
	/**
	 * Create a new instance of {@link Section}
	 * @param routeID The ID of the train route the
	 * @param startTime The time at which the train leaves the station
	 * @param journeyLength The length of the journey on the {@link Section}
	 */
	public Section(String routeID, LocalTime startTime, long journeyLength, int cost) {
		this.routeID = routeID;
		this.startTime = startTime;
		this.journeyLength = journeyLength;
		this.cost = cost;
	}
	
	/**
	 * Set the maximum number of passengers the train can take on this section
	 * @param max The maximum number of passengers
	 */
	public void setMaxPassengers(int max) {
		this.maxPassengers =max;
	}
	
	/**
	 * Get the identifier of the route the {@link Section belongs to}
	 * @return The ID of the route
	 */
	public String getRouteID() {
		return routeID;
	}
	
	/**
	 * Get the time at which the train leaves the station
	 * @return The {@link LocalTime} of departure
	 */
	public LocalTime getStartTime() {
		return startTime;
	}
	
	/**
	 * Get the length of journey (in seconds) for the section
	 * @return The length of time in seconds
	 */
	public long getJourneyLength() {
		return journeyLength;
	}
	
	/**
	 * Get the maximum number of passengers for the section
	 * @return The maximum number of passengers
	 */
	public int getMaxPassengers() {
		return maxPassengers;
	}
	
	/**
	 * Create a {@link Section} from a corresponding {@link JSONObject}
	 * @param rawSection The JSON data for the section
	 * @param routeID The ID of the associated route
	 * @return The newly created {@link Section}
	 * @throws IllegalArgumentException Thrown if an argument within the JSON is of incorrect type
	 * @throws MissingParameterException Thrown if a required argument is not defined in the JSON
	 */
	public static Section getSectionFromJSON(JSONObject rawSection, String routeID) throws IllegalArgumentException, MissingParameterException {
		Object time = JSONTools.getParameter(rawSection, "time");
		Object length = JSONTools.getParameter(rawSection, "length");
		Object cost = JSONTools.getParameter(rawSection, "cost");
		
		return new Section(
			routeID,
			new LocalTime(time), 
			(Long) length,
			(int)(long)(Long) cost);
	}
	
	@Override
	public boolean equals(Object o) {
		if (!(o instanceof Section)) return false;
		
		Section s = (Section) o;
		return routeID.equalsIgnoreCase(s.getRouteID()) &&
				startTime.equals(s.getStartTime()) &&
				journeyLength == s.getJourneyLength();
	}
	
	@Override
	protected double getWeight() {
		switch(scoreMode) {
			case Cost: return journeyLength * cost;
			default: return journeyLength;
		}
	}
	
	@Override
	public String toString() {
		return "<" + routeID + " >";
	}
}

@@ -386,16 +386,17 @@
 dEdge %7B%0A
+%09
 %0A%09public
@@ -596,16 +596,70 @@
 lTime; %0A
+%09public static int DIFFERENT_ROUTE_MULTIPLICATOR = 2;%0A
 %09%0A%09priva
@@ -3754,31 +3754,15 @@
 turn
- journeyLength *
  cost;%0A
+
 %09%09%09d
@@ -3796,24 +3796,239 @@
 h;%0A%09%09%7D%0A%09%7D%0A%09%0A
+%09public double getWeight(Section other) %7B%0A%09%09if (other != null &&%0A%09%09%09%09other.getRouteID().equalsIgnoreCase(routeID)) %7B%0A%09%09%09return getWeight();%0A%09%09%7D else %7B%0A%09%09%09return getWeight() * DIFFERENT_ROUTE_MULTIPLICATOR;%0A%09%09%7D%0A%09%7D%0A%09%0A
 %09@Override%0A%09
@@ -4050,24 +4050,24 @@
 oString() %7B%0A
+
 %09%09return %22%3C%22
@@ -4080,17 +4080,16 @@
 teID + %22
- 
 %3E%22;%0A%09%7D%0A%7D

Add comparing getWeight method used by AppliedDijkstraShortestPath