using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Collections;

namespace EQTrack
{
    class Report
    {
        private DataTable GetReport(int DeviceID, string From, string To, int MinStopSpeed,int MinStopDistance)
        {
            System.Data.DataTable dtReport = Globals.ReportService.FullTrackingReport(DeviceID.ToString() , From, To);
            System.Data.DataTable dtCheckedReport = DecideStoppedOrTravelling(dtReport, MinStopSpeed, MinStopDistance);
            return (CompileReport(dtCheckedReport));

        }

        private double GetDistanceBetween(double lat1, double lon1, double lat2, double lon2)
        {
            int R = 6371000; // km
            double dLat = DegreesToRadians(lat2 - lat1);
            double dLon = DegreesToRadians(lon2 - lon1);
            double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + DegreesToRadians(Math.Cos(lat1)) * DegreesToRadians(Math.Cos(lat2)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
            double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
            double d = R * c;
            return (d);
        }

        private DataTable DecideStoppedOrTravelling(DataTable DT, int MinSpeedofStopped, int MinDistanceofStopped)
        {
            System.Data.DataTable reporttable = new System.Data.DataTable();
            reporttable.Columns.Add("Status");
            reporttable.Columns.Add("Event Number");
            reporttable.Columns.Add("Device ID");
            reporttable.Columns.Add("Address");
            reporttable.Columns.Add("Speed");
            reporttable.Columns.Add("Latitude");
            reporttable.Columns.Add("Longitude");
            reporttable.Columns.Add("Date & Time");
            reporttable.Columns.Add("Distance Till Next");
            reporttable.Columns.Add("Time Till Next");
            DateTime FromTime;
            int ilines = DT.Rows.Count;
            for (int iRow = 0; iRow <= ilines - 2; iRow++)
            {
                FromTime = DateTime.Parse(DT.Rows[iRow][6].ToString());
                string sAddress = DT.Rows[iRow][2].ToString();
                int iSpd = int.Parse(DT.Rows[iRow][3].ToString());
                System.TimeSpan TimeBetween = new TimeSpan();
                TimeBetween = DateTime.Parse(DT.Rows[iRow + 1][6].ToString()).Subtract(FromTime);

                double Lat_now = double.Parse(DT.Rows[iRow][4].ToString());
                double Lon_now = double.Parse(DT.Rows[iRow][5].ToString());

                double Lat_next = double.Parse(DT.Rows[iRow + 1][4].ToString());
                double Lon_next = double.Parse(DT.Rows[iRow + 1][5].ToString());

                int DistanceBetween = (int)GetDistanceBetween(Lat_now, Lon_now, Lat_next, Lon_next);

                if ((iSpd <= MinSpeedofStopped) & (DistanceBetween <= MinDistanceofStopped))
                {
                    reporttable.Rows.Add(new string[] { "Stopped", DT.Rows[iRow][0].ToString(), DT.Rows[iRow][1].ToString(), sAddress.ToString(), iSpd.ToString(), Lat_now.ToString(), Lon_now.ToString(), FromTime.ToString(), DistanceBetween.ToString() + "m", TimeBetween.ToString() });
                }
                else if ((iSpd <= MinSpeedofStopped) & (DistanceBetween > MinDistanceofStopped))
                {
                    reporttable.Rows.Add(new string[] { "Travelling", DT.Rows[iRow][0].ToString(), DT.Rows[iRow][1].ToString(), sAddress.ToString(), iSpd.ToString(), Lat_now.ToString(), Lon_now.ToString(), FromTime.ToString(), DistanceBetween.ToString() + "m", TimeBetween.ToString() });
                }
                else if ((iSpd > MinSpeedofStopped) & (DistanceBetween <= MinDistanceofStopped))
                {
                    reporttable.Rows.Add(new string[] { "Travelling", DT.Rows[iRow][0].ToString(), DT.Rows[iRow][1].ToString(), sAddress.ToString(), iSpd.ToString(), Lat_now.ToString(), Lon_now.ToString(), FromTime.ToString(), DistanceBetween.ToString() + "m", TimeBetween.ToString() });
                }
                else if ((iSpd > MinSpeedofStopped) & (DistanceBetween > MinDistanceofStopped))
                {
                    reporttable.Rows.Add(new string[] { "Travelling", DT.Rows[iRow][0].ToString(), DT.Rows[iRow][1].ToString(), sAddress.ToString(), iSpd.ToString(), Lat_now.ToString(), Lon_now.ToString(), FromTime.ToString(), DistanceBetween.ToString() + "m", TimeBetween.ToString() });
                }
            }
            return (reporttable);
        }

        private DataTable CompileReport(DataTable DT)
        {
            System.Data.DataTable FinalReport = new System.Data.DataTable();
            FinalReport.Columns.Add("Status");
            FinalReport.Columns.Add("Address");
            FinalReport.Columns.Add("Start");
            FinalReport.Columns.Add("Finish");
            FinalReport.Columns.Add("Max Speed");
            FinalReport.Columns.Add("Ave Speed");
            FinalReport.Columns.Add("Time");

            string FromDateTime = "";
            string ToDateTime = "";
            int line = 0;
            int ilines = DT.Rows.Count;
            while (line < ilines - 1)
            {
                string Status = DT.Rows[line][0].ToString();
                ArrayList ArrayAddress = new ArrayList();
                System.TimeSpan TimeBetween = new TimeSpan();
                ArrayList ArraySpeed = new ArrayList();
                string sTime = "";
                if (Status == "Stopped")
                {
                    FromDateTime = DT.Rows[line][7].ToString();
                    while ((Status == "Stopped") & (line < ilines - 1))
                    {
                        line = line + 1;
                        Status = DT.Rows[line][0].ToString();

                        ArrayAddress.Add(DT.Rows[line][3].ToString());

                    }
                    string sAddress = ArrayAddress[ArrayAddress.Count / 2].ToString();
                    ToDateTime = DT.Rows[line][7].ToString();
                    TimeBetween = DateTime.Parse(ToDateTime).Subtract(DateTime.Parse(FromDateTime));

                    FinalReport.Rows.Add(new string[] { "Stopped at", sAddress, FromDateTime, ToDateTime, "", "", TimeBetween.ToString() });
                }
                else
                {

                    FromDateTime = DT.Rows[line][7].ToString();
                    while ((Status == "Travelling") & (line < ilines - 1))
                    {
                        line = line + 1;
                        Status = DT.Rows[line][0].ToString();
                        ArraySpeed.Add(int.Parse(DT.Rows[line][4].ToString()));
                    }

                    ArraySpeed.Sort();
                    int iMaxSpeed = int.Parse(ArraySpeed[ArraySpeed.Count - 1].ToString());



                    int iAveSpeed = 0;
                    for (int i = 0; i < ArraySpeed.Count; i++)
                    {
                        iAveSpeed = iAveSpeed + int.Parse(ArraySpeed[i].ToString());
                    }
                    iAveSpeed = iAveSpeed / ArraySpeed.Count;

                    ToDateTime = DT.Rows[line][7].ToString();
                    TimeBetween = DateTime.Parse(ToDateTime).Subtract(DateTime.Parse(FromDateTime));
                    FinalReport.Rows.Add(new string[] { "Travelling", "", FromDateTime, ToDateTime, iMaxSpeed.ToString(), iAveSpeed.ToString(), TimeBetween.ToString() });
                }
            }
            return (FinalReport);
        }

        public static double DegreesToRadians(double degrees)
        {
            double radians = (Math.PI / 180) * degrees;
            return (radians);
        }




    }
}
