public static void Update(Int16 carId)
        {
            DBController dbc = new DBController();
            List<Int64> tripIds = dbc.GetTripIdsByCarId(carId);
            List<Fact> facts;
            Trip trip;
            Int64 previousTripId = 0;
            DateTime previousEndTimestamp = new DateTime();

            for (int i = 0; i < tripIds.Count; i++) {
                trip = dbc.GetTripByTripId(tripIds[i]);
                facts = dbc.GetFactsByTripId(tripIds[i]);

                //If a previous trip exists, save ID and the time passed between them
                if (i > 0) {
                    trip.PreviousTripId = previousTripId;
                    trip.SecondsToLag = MeasureCalculator.SecondsToLag(facts[0].Temporal.Timestamp, previousEndTimestamp);
                }

                //Remember variables for next iteration
                previousTripId = trip.TripId;
                previousEndTimestamp = trip.EndTemporal.Timestamp;

                Console.WriteLine("Updating car {0}, trip {1} ({2} facts)", carId, trip.TripId, facts.Count);
                trip = UpdateTrip(trip, facts, dbc);
                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];
                dbc.UpdateTripFactWithMeasures(trip);
            }

            dbc.Close();
        }
        public static double tripPercentage(Int64 tripId)
        {
            double result = 0;

            DBController dbc = new DBController();
            Trip trip = dbc.GetTripByTripId(tripId);
            dbc.Close();

            if(trip.TripScore != 0 && trip.MetersDriven != 0) {
                result = trip.TripScore / trip.MetersDriven * 100 - 100;
            }

            return result;
        }
        public static double CalculateOptimal(Int64 tripId, List<double> optimalSpeedingProfile,
                                                     List<double> optimalAccelrationProfile,
                                                     List<double> optimalBrakesProfile,
                                                     List<double> optimalJerksProfile)
        {
            DBController dbc = new DBController();
            Trip trip = dbc.GetTripByTripId(tripId);
            dbc.Close();

            List<double> roadTypeIntervals = IntervalHelper.Decode(trip.IntervalInformation.RoadTypesInterval);
            List<double> criticalTimeIntervals = IntervalHelper.Decode(trip.IntervalInformation.CriticalTimeInterval);

            double metersSped = 0;
            double accelerations = 0;
            double brakes = 0;
            double jerks = 0;

            for (int i = 0; i < optimalSpeedingProfile.Count; i++) {
                //Optimal Profiles are per hundred kilometers - change the values to match the trip length instead
                optimalSpeedingProfile[i] *= (trip.MetersDriven / 100000);
                optimalAccelrationProfile[i] *= (trip.MetersDriven / 100000);
                optimalBrakesProfile[i] *= (trip.MetersDriven / 100000);
                optimalJerksProfile[i] *= (trip.MetersDriven / 100000);
                metersSped += optimalSpeedingProfile[i];
                accelerations += optimalAccelrationProfile[i];
                brakes += optimalBrakesProfile[i];
                jerks += optimalJerksProfile[i];
            }

            for (int i = 0; i < optimalSpeedingProfile.Count; i++) {
                optimalSpeedingProfile[i] /= metersSped * 100;
                optimalAccelrationProfile[i] /= accelerations * 100;
                optimalBrakesProfile[i] /= brakes * 100;
                optimalJerksProfile[i] /= jerks * 100;
            }

            double finalScore = trip.MetersDriven;
            finalScore += Subscore.RoadTypes(trip.MetersDriven, roadTypeIntervals, DefaultPolicy.RoadTypeWeights);
            finalScore += Subscore.CriticalTimePeriod(trip.MetersDriven, criticalTimeIntervals, DefaultPolicy.CriticalTimeWeights);
            finalScore += Subscore.Speeding(metersSped,
                                            optimalSpeedingProfile,
                                            DefaultPolicy.SpeedingWeights,
                                            DefaultPolicy.A,
                                            DefaultPolicy.B,
                                            DefaultPolicy.C,
                                            DefaultPolicy.Poly);
            finalScore += Subscore.Accelerations(accelerations,
                                                 optimalAccelrationProfile,
                                                 DefaultPolicy.AccelerationPrice,
                                                 DefaultPolicy.AccelerationWeights,
                                                 DefaultPolicy.A,
                                                 DefaultPolicy.B,
                                                 DefaultPolicy.C,
                                                 DefaultPolicy.Poly);
            finalScore += Subscore.Brakes(brakes,
                                          optimalBrakesProfile,
                                          DefaultPolicy.BrakePrice,
                                          DefaultPolicy.BrakeWeights,
                                          DefaultPolicy.A,
                                          DefaultPolicy.B,
                                          DefaultPolicy.C,
                                          DefaultPolicy.Poly);
            finalScore += Subscore.Jerks(jerks,
                                         optimalJerksProfile,
                                         DefaultPolicy.JerkPrice,
                                         DefaultPolicy.JerkWeights,
                                         DefaultPolicy.A,
                                         DefaultPolicy.B,
                                         DefaultPolicy.C,
                                         DefaultPolicy.Poly);
            return finalScore;
        }