//package seng302.Model;
//
//import org.geotools.referencing.GeodeticCalculator;
//import seng302.Constants;
//import seng302.Controllers.RaceController;
//import seng302.GPSCoordinate;
//import seng302.RaceDataSource;
//
//import java.awt.geom.Point2D;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.List;
//import java.util.Random;
//
///**
// * Created by cbt24 on 6/03/17.
// *
// * @deprecated
// */
//public class ConstantVelocityRace extends Race {
//
//    private int dnfChance = 0; //%percentage chance a boat fails at each checkpoint
//
//    /**
//     * Initializer for a constant velocity race without standard data source
//     *
//     * @param startingBoats in race
//     * @param legs in race
//     * @param controller for graphics
//     * @param scaleFactor of timer
//     */
//    public ConstantVelocityRace(List<BoatInRace> startingBoats, List<Leg> legs, RaceController controller, int scaleFactor) {
//        super(startingBoats, legs, controller, scaleFactor);
//    }
//
//    /**
//     * Initializer for legacy tests
//     *
//     * @param startingBoats in race
//     * @param legs in race
//     * @param controller for graphics
//     * @param scaleFactor of timer
//     *
//     * @deprecated Please use {@link #ConstantVelocityRace(List, List, RaceController, int) } for future tests.
//     */
//    public ConstantVelocityRace(BoatInRace[] startingBoats, List<Leg> legs, RaceController controller, int scaleFactor) {
//        super(Arrays.asList(startingBoats), legs, controller, scaleFactor);
//    }
//
//    /**
//     * Initializer for constant velocity race with standard data source
//     * @param raceData for race
//     * @param controller for graphics
//     * @param scaleFactor of timer
//     */
//    public ConstantVelocityRace(RaceDataSource raceData, RaceController controller, int scaleFactor) {
//        super(raceData, controller, scaleFactor);
//    }
//
//    public void initialiseBoats() {
//        Leg officialStart = legs.get(0);
//        String name = officialStart.getName();
//        CompoundMark endMarker = officialStart.getEndCompoundMark();
//
//        BoatInRace.setTrackPointTimeInterval(BoatInRace.getBaseTrackPointTimeInterval() / scaleFactor);
//
//        ArrayList<CompoundMark> startMarkers = getSpreadStartingPositions();
//        for (int i = 0; i < startingBoats.size(); i++) {
//            BoatInRace boat = startingBoats.get(i);
//            if (boat != null) {
//                boat.setScaledVelocity(boat.getVelocity() * scaleFactor);
//                Leg startLeg = new Leg(name, 0);
//                boat.setCurrentPosition(startMarkers.get(i).getAverageGPSCoordinate());
//                startLeg.setStartCompoundMark(startMarkers.get(i));
//                startLeg.setEndCompoundMark(endMarker);
//                startLeg.calculateDistance();
//                boat.setCurrentLeg(startLeg);
//                boat.setHeading(boat.calculateHeading());
//            }
//        }
//    }
//
//    /**
//     * Creates a list of starting positions for the different boats, so they do not appear cramped at the start line
//     *
//     * @return list of starting positions
//     */
//    public ArrayList<CompoundMark> getSpreadStartingPositions() {
//
//        int nBoats = startingBoats.size();
//        CompoundMark marker = legs.get(0).getStartCompoundMark();
//
//        GeodeticCalculator initialCalc = new GeodeticCalculator();
//        initialCalc.setStartingGeographicPoint(marker.getMark1().getLongitude(), marker.getMark1().getLatitude());
//        initialCalc.setDestinationGeographicPoint(marker.getMark2().getLongitude(), marker.getMark2().getLatitude());
//
//        double azimuth = initialCalc.getAzimuth();
//        double distanceBetweenMarkers = initialCalc.getOrthodromicDistance();
//        double distanceBetweenBoats = distanceBetweenMarkers / (nBoats + 1);
//
//        GeodeticCalculator positionCalc = new GeodeticCalculator();
//        positionCalc.setStartingGeographicPoint(marker.getMark1().getLongitude(), marker.getMark1().getLatitude());
//        ArrayList<CompoundMark> positions = new ArrayList<>();
//
//        for (int i = 0; i < nBoats; i++) {
//            positionCalc.setDirection(azimuth, distanceBetweenBoats);
//            Point2D position = positionCalc.getDestinationGeographicPoint();
//            positions.add(new CompoundMark(new GPSCoordinate(position.getY(), position.getX())));
//
//            positionCalc = new GeodeticCalculator();
//            positionCalc.setStartingGeographicPoint(position);
//        }
//        return positions;
//    }
//
//    /**
//     * Sets the chance each boat has of failing at a gate or marker
//     * @param chance percentage chance a boat has of failing per checkpoint.
//     */
//    protected void setDnfChance(int chance) {
//        if (chance >= 0 && chance <= 100) {
//            dnfChance = chance;
//        }
//    }
//
//    protected boolean doNotFinish() {
//        Random rand = new Random();
//        return rand.nextInt(100) < dnfChance;
//    }
//
//    /**
//     * Calculates the distance a boat has travelled and updates its current position according to this value.
//     *
//     * @param boat to be updated
//     * @param millisecondsElapsed since last update
//     */
//    protected void updatePosition(BoatInRace boat, int millisecondsElapsed) {
//
//        //distanceTravelled = velocity (nm p hr) * time taken to update loop
//        double distanceTravelled = (boat.getScaledVelocity() * millisecondsElapsed) / 3600000;
//
//        double totalDistanceTravelled = distanceTravelled + boat.getDistanceTravelledInLeg();
//
//        boolean finish = boat.getCurrentLeg().getName().equals("Finish");
//        if (!finish) {
//            boat.setHeading(boat.calculateHeading());
//            //update boat's distance travelled
//            boat.setDistanceTravelledInLeg(totalDistanceTravelled);
//            //Calculate boat's new position by adding the distance travelled onto the start point of the leg
//            boat.setCurrentPosition(calculatePosition(boat.getCurrentLeg().getStartCompoundMark().getAverageGPSCoordinate(),
//                    totalDistanceTravelled, boat.calculateAzimuth()));
//        }
//    }
//
//    protected void checkPosition(BoatInRace boat, long timeElapsed) {
//        if (boat.getDistanceTravelledInLeg() > boat.getCurrentLeg().getDistance()) {
//            //boat has passed onto new leg
//            if (boat.getCurrentLeg().getName().equals("Finish")) {
//                //boat has finished
//                boatsFinished++;
//                boat.setFinished(true);
//                boat.setTimeFinished(timeElapsed);
//            } else if (doNotFinish()) {
//                boatsFinished++;
//                boat.setFinished(true);
//                boat.setCurrentLeg(new Leg("DNF", -1));
//                boat.setVelocity(0);
//                boat.setScaledVelocity(0);
//            } else {
//                //Calculate how much the boat overshot the marker by
//                boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg() - boat.getCurrentLeg().getDistance());
//                //Move boat on to next leg
//                Leg nextLeg = legs.get(boat.getCurrentLeg().getLegNumber() + 1);
//
//                boat.setCurrentLeg(nextLeg);
//                //Add overshoot distance into the distance travelled for the next leg
//                boat.setDistanceTravelledInLeg(boat.getDistanceTravelledInLeg());
//            }
//            //Update the boat display table in the GUI to reflect the leg change
//            updatePositions();
//        }
//    }
//
//    /**
//     * Calculates the boats next GPS position based on its distance travelled and heading
//     *
//     * @param oldCoordinates    GPS coordinates of the boat's starting position
//     * @param distanceTravelled distance in nautical miles
//     * @param azimuth           boat's current direction. Value between -180 and 180
//     * @return The boat's new coordinate
//     */
//    public static GPSCoordinate calculatePosition(GPSCoordinate oldCoordinates, double distanceTravelled, double azimuth) {
//
//        //Find new coordinate using current heading and distance
//
//        GeodeticCalculator geodeticCalculator = new GeodeticCalculator();
//        //Load start point into calculator
//        Point2D startPoint = new Point2D.Double(oldCoordinates.getLongitude(), oldCoordinates.getLatitude());
//        geodeticCalculator.setStartingGeographicPoint(startPoint);
//        //load direction and distance tranvelled into calculator
//        geodeticCalculator.setDirection(azimuth, distanceTravelled * Constants.NMToMetersConversion);
//        //get new point
//        Point2D endPoint = geodeticCalculator.getDestinationGeographicPoint();
//
//        return new GPSCoordinate(endPoint.getY(), endPoint.getX());
//    }
//
//}