public static List<double> CriticalTime(Trip trip, List<Fact> facts)
        {
            SortedDictionary<TimeInterval, double> criticalTimes = new SortedDictionary<TimeInterval, double>();

            //Populate dictionary with all policy-required time-intervals
            foreach (TimeInterval interval in DefaultPolicy.TimeIntervals) {
                criticalTimes.Add(interval, 0);
            }

            //Calculate meters driven in every interval
            for (int i = 1; i < facts.Count; i++) {
                foreach(TimeInterval interval in DefaultPolicy.TimeIntervals) {
                    if(interval.ActiveDays.Contains(facts[i].Temporal.Timestamp.DayOfWeek) && interval.StartTime <= facts[i].Temporal.Timestamp.TimeOfDay && interval.EndTime >= facts[i].Temporal.Timestamp.TimeOfDay) {
                        criticalTimes[interval] += facts[i].Spatial.DistanceToLag;
                    }
                }
            }

            //Calculate the distribution in percentages of whole trip
            for(int i = 0; i < DefaultPolicy.TimeIntervals.Count; i++) {
                criticalTimes[DefaultPolicy.TimeIntervals[i]] = (criticalTimes[DefaultPolicy.TimeIntervals[i]] / trip.MetersDriven) * 100;
            }

            return criticalTimes.Values.ToList();
        }
        //Mulige forbedrninger: Acceleration, brake og jerk er per gps point, men ignorerer tid - interpoler?
        public static List<double> Acceleration(Trip trip, List<Fact> facts)
        {
            SortedDictionary<Interval, double> accelerationIntervals = new SortedDictionary<Interval, double>();

            //Populate dictionary with all policy-required acceleration-intervals
            foreach (Interval interval in DefaultPolicy.AccelerationIntervals) {
                accelerationIntervals.Add(interval, 0);
            }

            //Add an acceleration in the fitting interval per point measured
            for (int i = 1; i < facts.Count; i++) {
                if (facts[i].Flag.Accelerating) {
                    foreach (Interval interval in DefaultPolicy.AccelerationIntervals) {
                        if (interval.Contains(facts[i].Measure.Acceleration)) {
                            accelerationIntervals[interval]++;
                        }
                    }
                }
            }

            //Calculate the distribution of points in percentages
            foreach (Interval interval in DefaultPolicy.AccelerationIntervals) {
                accelerationIntervals[interval] = (accelerationIntervals[interval] / trip.AccelerationCount) * 100;
            }

            return accelerationIntervals.Values.ToList();
        }
        public static List<double> Brake(Trip trip, List<Fact> facts)
        {
            SortedDictionary<Interval, double> brakeIntervals = new SortedDictionary<Interval, double>();
            double brakeValue;

            //Populate dictionary with all policy-required brake-intervals
            foreach (Interval interval in DefaultPolicy.BrakeIntervals) {
                brakeIntervals.Add(interval, 0);
            }

            //Add a brake in the fitting interval per point measured
            for (int i = 1; i < facts.Count; i++) {
                if (facts[i].Flag.Braking) {

                    //Convert all brakes to positive numbers, to make them comparable with policy variables
                    brakeValue = facts[i].Measure.Acceleration * -1;

                    foreach (Interval interval in DefaultPolicy.BrakeIntervals) {
                        if (interval.Contains(brakeValue)) {
                            brakeIntervals[interval]++;
                        }
                    }
                }
            }

            //Calculate the distribution of points in percentages
            foreach (Interval interval in DefaultPolicy.BrakeIntervals) {
                brakeIntervals[interval] = (brakeIntervals[interval] / trip.BrakeCount) * 100;
            }

            return brakeIntervals.Values.ToList();
        }
        //Updates trip without PreviousTripId, localtripId and Secondstolag
        public static void UpdateExistingTrip(Int16 carId, Int64 tripId)
        {
            DBController dbc = new DBController();

            Trip trip = new Trip(tripId, carId);
            List<Fact> facts = dbc.GetFactsByTripIdNoQuality(tripId);

            //Calc the trip updates
            trip = UpdateTrip(trip, facts, dbc);

            //Compute the scores
            trip.OptimalScore = FinalScore.CalculateOptimalScore(trip);
            List<double> fullscores = FinalScore.CalculateTripScores(trip);

            trip.RoadTypeScore = fullscores[0];
            trip.CriticalTimeScore = fullscores[1];
            trip.SpeedingScore = fullscores[2];
            trip.AccelerationScore = fullscores[3];
            trip.BrakeScore = fullscores[4];
            trip.JerkScore = fullscores[5];
            trip.TripScore = fullscores[6];

            //Update the trip in the database
            dbc.UpdateTripFactWithMeasures(trip);
            dbc.Close();
        }
        public static void UpdateTrip(Int16 carId, Int64 tripId)
        {
            DBController dbc = new DBController();

            Trip trip = new Trip(tripId, carId);
            List<Fact> facts = dbc.GetFactsByTripIdNoQuality(tripId);

            //Getting the previous tripid and seconds to previous trip
            List<Int64> tripIds = dbc.GetTripIdsByCarId(carId);
            //In case this is the first trip - ignore computing measures for previous trip
            if (tripIds.Count > 1) {
                Int64 latestTrip = tripIds[tripIds.Count() - 2];
                Trip previousTrip = dbc.GetTripByCarIdAndTripId(carId, latestTrip);
                trip.SecondsToLag = MeasureCalculator.SecondsToLag(facts[0].Temporal.Timestamp, previousTrip.EndTemporal.Timestamp);
            } else {
                trip.SecondsToLag = new TimeSpan(0, 0, -1);
            }
            //Calc the trip updates
            trip = UpdateTrip(trip, facts, dbc);

            //Compute the scores
            trip.OptimalScore = FinalScore.CalculateOptimalScore(trip);
            List<double> fullscores = FinalScore.CalculateTripScores(trip);

            trip.RoadTypeScore = fullscores[0];
            trip.CriticalTimeScore = fullscores[1];
            trip.SpeedingScore = fullscores[2];
            trip.AccelerationScore = fullscores[3];
            trip.BrakeScore = fullscores[4];
            trip.JerkScore = fullscores[5];
            trip.TripScore = fullscores[6];

            //Update the trip in the database
            dbc.UpdateTripFactWithMeasures(trip);
            dbc.Close();
        }
        private static Trip UpdateTripWithIntervals(Trip trip, List<Fact> facts, DBController dbc)
        {
            List<double> intervals;

            trip.IntervalInformation = new IntervalInformation(trip.CarId, trip.TripId);

            intervals = IntervalCalculator.RoadType(trip, facts, dbc);
            trip.IntervalInformation.RoadTypesInterval = IntervalHelper.Encode(intervals);

            intervals = IntervalCalculator.CriticalTime(trip, facts);
            trip.IntervalInformation.CriticalTimeInterval = IntervalHelper.Encode(intervals);

            intervals = IntervalCalculator.Speeding(trip, facts);
            trip.IntervalInformation.SpeedInterval = IntervalHelper.Encode(intervals);

            intervals = IntervalCalculator.Acceleration(trip, facts);
            trip.IntervalInformation.AccelerationInterval = IntervalHelper.Encode(intervals);

            intervals = IntervalCalculator.Brake(trip, facts);
            trip.IntervalInformation.BrakingInterval = IntervalHelper.Encode(intervals);

            intervals = IntervalCalculator.Jerk(trip, facts);
            trip.IntervalInformation.JerkInterval = IntervalHelper.Encode(intervals);

            return trip;
        }
        public static Trip UpdateTripWithCountsAndIntervals(Trip trip, List<Fact> facts, DBController dbc)
        {
            //Counts

            trip.JerkCount = 0;
            trip.BrakeCount = 0;
            trip.AccelerationCount = 0;

            for (int i = 1; i < facts.Count; i++) {

                //Acceleration count
                if (facts[i].Flag.Accelerating) {
                    trip.AccelerationCount++;
                }

                //Brake count
                if (facts[i].Flag.Braking) {
                    trip.BrakeCount++;
                }

                //Jerk count
                if (facts[i].Flag.Jerking) {
                    trip.JerkCount++;
                }
            }

            //Interval Information
            trip = UpdateTripWithIntervals(trip, facts, dbc);

            return trip;
        }
        public static Trip UpdateTrip(Trip trip, List<Fact> facts, DBController dbc)
        {
            //Temporal information
            trip.StartTemporal = facts.First().Temporal;
            trip.EndTemporal = facts.Last().Temporal;
            trip.SecondsDriven = MeasureCalculator.SecondsToLag(facts.Last().Temporal.Timestamp, facts.First().Temporal.Timestamp);

            //Counts
            trip.MetersDriven = 0;
            trip.JerkCount = 0;
            trip.BrakeCount = 0;
            trip.AccelerationCount = 0;
            trip.MetersSped = 0;
            trip.TimeSped = new TimeSpan();
            trip.SteadySpeedDistance = 0;
            trip.SteadySpeedTime = new TimeSpan();
            trip.DataQuality = 0;

            for (int i = 1; i < facts.Count; i++) {
                //Meters driven
                trip.MetersDriven += MeasureCalculator.DistanceToLag(facts[i].Spatial.MPoint, facts[i - 1].Spatial.MPoint);
                if(trip.MetersDriven == 0) {
                    trip.MetersDriven = 1;
                }

                //Meters sped
                if (facts[i].Flag.Speeding && facts[i].Segment.MaxSpeed != 0) {
                    trip.MetersSped += facts[i].Spatial.DistanceToLag;
                }

                //Time sped
                if (facts[i].Flag.Speeding && facts[i].Segment.MaxSpeed != 0) {
                    trip.TimeSped += facts[i].Temporal.SecondsToLag;
                }

                //Acceleration count
                if (facts[i].Flag.Accelerating) {
                    trip.AccelerationCount++;
                }

                //Brake count
                if (facts[i].Flag.Braking) {
                    trip.BrakeCount++;
                }

                //Jerk count
                if (facts[i].Flag.Jerking) {
                    trip.JerkCount++;
                }

                //Steady speed distance
                if (facts[i].Flag.SteadySpeed) {
                    trip.SteadySpeedDistance += facts[i].Spatial.DistanceToLag;
                }

                //Steady speed time
                if (facts[i].Flag.SteadySpeed) {
                    trip.SteadySpeedTime += facts[i].Temporal.SecondsToLag;
                }

                trip.DataQuality += facts[i].Quality.Hdop;
            }

            //Interval Information
            trip = UpdateTripWithIntervals(trip, facts, dbc);

            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // Needs to be calculated right
            ////////////////////////////////
            //Data Quality
            trip.DataQuality = trip.DataQuality / facts.Count;

            return trip;
        }
        public static List<double> Jerk(Trip trip, List<Fact> facts)
        {
            SortedDictionary<Interval, double> jerkIntervals = new SortedDictionary<Interval, double>();

            //Populate dictionary with all policy-required jerk-intervals
            foreach (Interval interval in DefaultPolicy.JerkIntervals) {
                jerkIntervals.Add(interval, 0);
            }

            //Add a jerk in the fitting interval per point measured
            for (int i = 1; i < facts.Count; i++) {
                if (facts[i].Flag.Jerking) {
                    foreach (Interval interval in DefaultPolicy.JerkIntervals) {
                        if (interval.Contains(Math.Abs(facts[i].Measure.Jerk))) {
                            jerkIntervals[interval]++;
                        }
                    }
                }
            }

            //Calculate the distribution of points in percentages
            foreach (Interval interval in DefaultPolicy.JerkIntervals) {
                jerkIntervals[interval] = (jerkIntervals[interval] / trip.JerkCount) * 100;
            }

            return jerkIntervals.Values.ToList();
        }
        public static Dictionary<string, double> MetricPercentage(Trip trip)
        {
            Dictionary<string, double> result = new Dictionary<string, double>();
            if (trip.RoadTypeScore != 0 || trip.MetersDriven != 0) {
                result.Add("Roadtypes", trip.RoadTypeScore / trip.MetersDriven * 100);
            } else {
                result.Add("Roadtypes", 0);
            }

            if (trip.CriticalTimeScore != 0 || trip.MetersDriven != 0) {
                result.Add("CriticalTimePeriod", trip.CriticalTimeScore / trip.MetersDriven * 100);
            } else {
                result.Add("CriticalTimePeriod", 0);
            }

            if (trip.SpeedingScore != 0 || trip.MetersDriven != 0) {
                result.Add("Speeding", trip.SpeedingScore / trip.MetersDriven * 100);
            } else {
                result.Add("Speeding", 0);
            }

            if (trip.AccelerationScore != 0 || trip.MetersDriven != 0) {
                result.Add("Accelerations", trip.AccelerationScore / trip.MetersDriven * 100);
            } else {
                result.Add("Accelerations", 0);
            }

            if (trip.BrakeScore != 0 || trip.MetersDriven != 0) {
                result.Add("Brakes", trip.BrakeScore / trip.MetersDriven * 100);
            } else {
                result.Add("Brakes", 0);
            }

            if (trip.JerkScore != 0 || trip.MetersDriven != 0) {
                result.Add("Jerks", trip.JerkScore / trip.MetersDriven * 100);
            } else {
                result.Add("Jerks", 0);
            }

            return result;
        }
        public static List<double> RoadType(Trip trip, List<Fact> facts, DBController dbc)
        {
            SortedDictionary<Global.Enums.RoadType, double> metersDistribution = new SortedDictionary<Global.Enums.RoadType, double>();
            List<Global.Enums.RoadType> roadTypes = dbc.GetRoadTypesByTripId(trip.TripId);

            //Populate dictionary with all policy-required roadtypes
            foreach (Global.Enums.RoadType roadType in DefaultPolicy.RoadTypes) {
                metersDistribution.Add(roadType, 0);
            }

            //Calculate meters driven on each roadtype
            for (int i = 1; i < facts.Count; i++) {
                if (DefaultPolicy.RoadTypes.Contains(roadTypes[i])) {
                    metersDistribution[roadTypes[i]] += facts[i].Spatial.DistanceToLag;
                }
            }

            List<double> resultList = metersDistribution.Values.ToList();

            //Calculate the distribution in percentages of whole trip
            for (int i = 0; i < resultList.Count; i++) {
                resultList[i] = (resultList[i] / trip.MetersDriven) * 100;
            }

            return resultList;
        }
        public int UpdateTripFactWithMeasures(Trip UpdatedTrip)
        {
            string sql = String.Format(@"UPDATE tripfact
                                         SET startdateid = @startdateid,
                                          starttimeid = @starttimeid,
                                          enddateid = @enddateid,
                                          endtimeid = @endtimeid,
                                          secondsdriven = @secondsdriven,
                                          metersdriven = @metersdriven,
                                          tripscore = @tripscore,
                                          optimalscore = @optimalscore,
                                          jerkcount = @jerkcount,
                                          brakecount = @brakecount,
                                          accelerationcount = @accelerationcount,
                                          meterssped = @meterssped,
                                          timesped = @timesped,
                                          steadyspeeddistance = @steadyspeeddistance,
                                          steadyspeedtime = @steadyspeedtime,
                                          secondstolag = @secondstolag,
                                          roadtypesinterval = @roadtypesinterval,
                                          criticaltimeinterval =  @criticaltimeinterval,
                                          speedinterval = @speedinterval,
                                          accelerationinterval = @accelerationinterval,
                                          jerkinterval = @jerkinterval,
                                          brakinginterval = @brakinginterval,
                                          dataquality = @dataquality,
                                          roadtypescore = @roadtypescore,
                                          criticaltimescore = @criticaltimescore,
                                          speedingscore = @speedingscore,
                                          accelerationscore = @accelerationscore,
                                          brakescore = @brakescore,
                                          jerkscore = @jerkscore
                                         WHERE tripid = @tripid");

            NpgsqlCommand command = new NpgsqlCommand(sql, Connection);

            command.Parameters.AddWithValue("@tripid", UpdatedTrip.TripId);

            if (UpdatedTrip.PreviousTripId != 0) {
                command.Parameters.AddWithValue("@previoustripid", UpdatedTrip.PreviousTripId);
            } else {
                command.Parameters.AddWithValue("@previoustripid", DBNull.Value);
            }

            command.Parameters.AddWithValue("@localtripid", UpdatedTrip.LocalTripId);

            command.Parameters.AddWithValue("@startdateid", Convert.ToInt32(UpdatedTrip.StartTemporal.Timestamp.ToString("yyyyMMdd")));
            command.Parameters.AddWithValue("@starttimeid", Convert.ToInt32(UpdatedTrip.StartTemporal.Timestamp.ToString("HHmmss")));
            command.Parameters.AddWithValue("@enddateid", Convert.ToInt32(UpdatedTrip.EndTemporal.Timestamp.ToString("yyyyMMdd")));
            command.Parameters.AddWithValue("@endtimeid", Convert.ToInt32(UpdatedTrip.EndTemporal.Timestamp.ToString("HHmmss")));
            command.Parameters.AddWithValue("@secondsdriven", UpdatedTrip.SecondsDriven.TotalSeconds);
            command.Parameters.AddWithValue("@metersdriven", UpdatedTrip.MetersDriven);
            //price?
            command.Parameters.AddWithValue("@tripscore", UpdatedTrip.TripScore);
            command.Parameters.AddWithValue("@optimalscore", UpdatedTrip.OptimalScore);
            command.Parameters.AddWithValue("@jerkcount", UpdatedTrip.JerkCount);
            command.Parameters.AddWithValue("@brakecount", UpdatedTrip.BrakeCount);
            command.Parameters.AddWithValue("@accelerationcount", UpdatedTrip.AccelerationCount);
            command.Parameters.AddWithValue("@meterssped", UpdatedTrip.MetersSped);
            command.Parameters.AddWithValue("@timesped", UpdatedTrip.TimeSped.TotalSeconds);
            command.Parameters.AddWithValue("@steadyspeeddistance", UpdatedTrip.SteadySpeedDistance);
            command.Parameters.AddWithValue("@steadyspeedtime", UpdatedTrip.SteadySpeedTime.TotalSeconds);
            command.Parameters.AddWithValue("@secondstolag", UpdatedTrip.SecondsToLag.TotalSeconds);

            //Interval Information
            command.Parameters.AddWithValue("@roadtypesinterval", UpdatedTrip.IntervalInformation.RoadTypesInterval);
            command.Parameters.AddWithValue("@criticaltimeinterval", UpdatedTrip.IntervalInformation.CriticalTimeInterval);
            command.Parameters.AddWithValue("@speedinterval", UpdatedTrip.IntervalInformation.SpeedInterval);
            command.Parameters.AddWithValue("@accelerationinterval", UpdatedTrip.IntervalInformation.AccelerationInterval);
            command.Parameters.AddWithValue("@jerkinterval", UpdatedTrip.IntervalInformation.JerkInterval);
            command.Parameters.AddWithValue("@brakinginterval", UpdatedTrip.IntervalInformation.BrakingInterval);

            command.Parameters.AddWithValue("@dataquality", UpdatedTrip.DataQuality);

            command.Parameters.AddWithValue("@roadtypescore", UpdatedTrip.RoadTypeScore);
            command.Parameters.AddWithValue("@criticaltimescore", UpdatedTrip.CriticalTimeScore);
            command.Parameters.AddWithValue("@speedingscore", UpdatedTrip.SpeedingScore);
            command.Parameters.AddWithValue("@accelerationscore", UpdatedTrip.AccelerationScore);
            command.Parameters.AddWithValue("@brakescore", UpdatedTrip.BrakeScore);
            command.Parameters.AddWithValue("@jerkscore", UpdatedTrip.JerkScore);

            try {
                NonQuery(command, "tripfact");
            } catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            return 0;
        }
        public int UpdateTripFactWithIntervals(Trip UpdatedTrip)
        {
            string sql = String.Format(@"UPDATE tripfact
                                         SET roadtypesinterval = @roadtypesinterval,
                                             criticaltimeinterval =  @criticaltimeinterval,
                                             speedinterval = @speedinterval,
                                             accelerationinterval = @accelerationinterval,
                                             jerkinterval = @jerkinterval,
                                             brakinginterval = @brakinginterval
                                         WHERE tripid = @tripid");

            NpgsqlCommand command = new NpgsqlCommand(sql, Connection);

            command.Parameters.AddWithValue("@tripid", UpdatedTrip.TripId);

            command.Parameters.AddWithValue("@roadtypesinterval", UpdatedTrip.IntervalInformation.RoadTypesInterval);
            command.Parameters.AddWithValue("@criticaltimeinterval", UpdatedTrip.IntervalInformation.CriticalTimeInterval);
            command.Parameters.AddWithValue("@speedinterval", UpdatedTrip.IntervalInformation.SpeedInterval);
            command.Parameters.AddWithValue("@accelerationinterval", UpdatedTrip.IntervalInformation.AccelerationInterval);
            command.Parameters.AddWithValue("@jerkinterval", UpdatedTrip.IntervalInformation.JerkInterval);
            command.Parameters.AddWithValue("@brakinginterval", UpdatedTrip.IntervalInformation.BrakingInterval);

            try {
                NonQuery(command, "tripfact");
            } catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            return 0;
        }
        public int UpdateTripFactWithCounts(Trip UpdatedTrip)
        {
            string sql = String.Format(@"UPDATE tripfact
                                         SET jerkcount = @jerkcount,
                                             accelerationcount =  @accelerationcount,
                                             brakecount = @brakecount
                                         WHERE tripid = @tripid");

            NpgsqlCommand command = new NpgsqlCommand(sql, Connection);

            command.Parameters.AddWithValue("@tripid", UpdatedTrip.TripId);

            command.Parameters.AddWithValue("@jerkcount", UpdatedTrip.JerkCount);
            command.Parameters.AddWithValue("@accelerationcount", UpdatedTrip.AccelerationCount);
            command.Parameters.AddWithValue("@brakecount", UpdatedTrip.BrakeCount);

            try {
                NonQuery(command, "tripfact");
            } catch (Exception e) {
                Console.WriteLine(e.ToString());
            }

            return 0;
        }
        public static List<double> CalculateTripScores(Trip trip)
        {
            List<double> roadTypeIntervals = IntervalHelper.Decode(trip.IntervalInformation.RoadTypesInterval);
            List<double> criticalTimeIntervals = IntervalHelper.Decode(trip.IntervalInformation.CriticalTimeInterval);
            List<double> speedingIntervals = IntervalHelper.Decode(trip.IntervalInformation.SpeedInterval);
            List<double> accelerationIntervals = IntervalHelper.Decode(trip.IntervalInformation.AccelerationInterval);
            List<double> brakingIntervals = IntervalHelper.Decode(trip.IntervalInformation.BrakingInterval);
            List<double> jerkIntervals = IntervalHelper.Decode(trip.IntervalInformation.JerkInterval);

            List<double> fullscores = new List<double>();
            double finalScore = trip.MetersDriven;

            double roadtypescore = Subscore.RoadTypes(trip.MetersDriven, roadTypeIntervals, DefaultPolicy.RoadTypeWeights);
            finalScore += roadtypescore;

            double criticaltimescore = Subscore.CriticalTimePeriod(trip.MetersDriven, criticalTimeIntervals, DefaultPolicy.CriticalTimeWeights);
            finalScore += criticaltimescore;

            double speedingscore = Subscore.Speeding(trip.MetersSped,
                                            speedingIntervals,
                                            DefaultPolicy.SpeedingWeights,
                                            DefaultPolicy.A,
                                            DefaultPolicy.B,
                                            DefaultPolicy.C,
                                            DefaultPolicy.Poly);
            finalScore += speedingscore;

            double accelerationscore = Subscore.Accelerations(trip.AccelerationCount,
                                                 accelerationIntervals,
                                                 DefaultPolicy.AccelerationPrice,
                                                 DefaultPolicy.AccelerationWeights,
                                                 DefaultPolicy.A,
                                                 DefaultPolicy.B,
                                                 DefaultPolicy.C,
                                                 DefaultPolicy.Poly);
            finalScore += accelerationscore;

            double brakescore = Subscore.Brakes(trip.BrakeCount,
                                          brakingIntervals,
                                          DefaultPolicy.BrakePrice,
                                          DefaultPolicy.BrakeWeights,
                                          DefaultPolicy.A,
                                          DefaultPolicy.B,
                                          DefaultPolicy.C,
                                          DefaultPolicy.Poly);
            finalScore += brakescore;

            double jerkscore = Subscore.Jerks(trip.JerkCount,
                                        jerkIntervals,
                                        DefaultPolicy.JerkPrice,
                                        DefaultPolicy.JerkWeights,
                                        DefaultPolicy.A,
                                        DefaultPolicy.B,
                                        DefaultPolicy.C,
                                        DefaultPolicy.Poly);
            finalScore += jerkscore;
            fullscores.Add(roadtypescore);
            fullscores.Add(criticaltimescore);
            fullscores.Add(speedingscore);
            fullscores.Add(accelerationscore);
            fullscores.Add(brakescore);
            fullscores.Add(jerkscore);
            fullscores.Add(finalScore);

            return fullscores;
        }
        public static double CalculateOptimalScore(Trip trip)
        {
            List<double> roadTypeIntervals = IntervalHelper.Decode(trip.IntervalInformation.RoadTypesInterval);
            List<double> criticalTimeIntervals = IntervalHelper.Decode(trip.IntervalInformation.CriticalTimeInterval);

            double optimalScore = trip.MetersDriven;
            optimalScore += Subscore.RoadTypes(trip.MetersDriven, roadTypeIntervals, DefaultPolicy.RoadTypeWeights);
            optimalScore += Subscore.CriticalTimePeriod(trip.MetersDriven, criticalTimeIntervals, DefaultPolicy.CriticalTimeWeights);

            return optimalScore;
        }
        public static List<double> Speeding(Trip trip, List<Fact> facts)
        {
            SortedDictionary<Interval, double> speedingIntervals = new SortedDictionary<Interval, double>();

            //Populate dictionary with all policy-required speeding-intervals
            foreach (Interval interval in DefaultPolicy.SpeedingIntervals) {
                speedingIntervals.Add(interval, 0);
            }

            //Calculate meters sped in every interval
            for (int i = 1; i < facts.Count; i++) {
                if (facts[i].Flag.Speeding && facts[i].Segment.MaxSpeed != 0) {
                    double percentage = facts[i].Measure.Speed / facts[i].Segment.MaxSpeed * 100 - 100;

                    foreach (Interval interval in DefaultPolicy.SpeedingIntervals) {
                        if (interval.Contains(percentage)) {
                            speedingIntervals[interval] += facts[i].Spatial.DistanceToLag;
                        }
                    }
                }
            }

            //Calculate the distribution in percentages of total meters sped
            foreach (Interval interval in DefaultPolicy.SpeedingIntervals) {
                speedingIntervals[interval] = (speedingIntervals[interval] / trip.MetersSped) * 100;
            }

            return speedingIntervals.Values.ToList();
        }
        public static Dictionary<string, double> MetricNormalized(Trip trip)
        {
            Dictionary<string, double> result = new Dictionary<string, double>();
            DBController dbc = new DBController();

            List<Fact> facts = dbc.GetFactsByTripIdNoQuality(trip.TripId);

            double tempint = trip.MetersDriven / 1000;

            result.Add("Speeding", 0);
            result.Add("Accelerations", 0);
            result.Add("Brakes", 0);
            result.Add("Jerks", 0);

            foreach (Fact fact in facts) {
                if (fact.Flag.Speeding) {
                    result["Speeding"]++;
                }
            }
            if (result["Speeding"] != 0) {
                result["Speeding"] = result["Speeding"] / tempint;
            }

            result["Accelerations"] = ((double)trip.AccelerationCount / tempint);
            result["Brakes"] = ((double)trip.BrakeCount / tempint);
            result["Jerks"] = ((double)trip.JerkCount / tempint);

            dbc.Close();

            return result;
        }