using pavesys_iRAP.DTO;
using System.Collections.Generic;
using CommunityToolkit.Mvvm.ComponentModel;
using CrudHelper = pavesys_iRAP.Helper.CrudHelper;
using System.Diagnostics;
using System.Linq;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Reflection;
using pavesys_iRAP.Business;
using Avalonia.Media.Imaging;
using Serilog;
using System.IO;
using Avalonia.Media;
using pavesys_iRAP.Helper;
using System.Collections.ObjectModel;
using Avalonia.Controls;

namespace pavesys_iRAP.ViewModels
{

    public class SegmentGridData
    {
        public int SegmentIndex { get; set; }
        public string FlyOutErrorTip { get; set; }
        public string SegmentComment { get; set; }
        //Warning Error Done ou None
        public IBrush EllipseCodeState { get; set; }
        public decimal InitialKm { get; set; }
        public SegmentGridData() { }
    }
    public partial class CodingPageViewModel : ViewModelBase
    {


        //Codificações do projeto selecionado
        public List<Coding?>? codingCtx { get; set; }
        public List<CodingImage> codingImagesCtx { get; set; }
        public int projectId { get; set; }
        //Cópia do projeto selecionado

        public Project currentProject;
        //Variaveis para navegar nos segmentos e distâncias
        public int segment { get; set; } = 0;
        //Tipo de stretch da imagem.
        [ObservableProperty]
        private Stretch imageStretch = Stretch.Uniform;
        //Informações para o grid de segmentos
        public ObservableCollection<SegmentGridData> SegmentGridData { get; set; }
        //Informações Gerais
        public int? codingId { get; set; }
        [ObservableProperty]
        private string coderName;
        [ObservableProperty]
        private DateTime codingDate;
        [ObservableProperty]
        private string codingDateString;
        [ObservableProperty]
        private decimal? initialKM;
        [ObservableProperty]
        private decimal? finalKM;
        //Selected Segment in SEG datagrid
        [ObservableProperty]
        private SegmentGridData selectedSegment;
        //Tab index to use on hotkeys 
        [ObservableProperty]
        private int selectedTab = 0;
        //Progressbar
        [ObservableProperty]
        private int segmentCurrent;
        [ObservableProperty]
        private int selectedStation;
        //Fotos
        [ObservableProperty]
        private List<string> leftImagesList;
        [ObservableProperty]
        private List<string> rightImagesList;
        [ObservableProperty]
        private Bitmap? leftImage;
        [ObservableProperty]
        private Bitmap? rightImage;
        [ObservableProperty]
        private string leftImageString;
        [ObservableProperty]
        private string rightImageString;

        public string projPath { get; set; }
        //Codificações Aba A1
        [ObservableProperty]
        private int? carriageWay;
        [ObservableProperty]
        private int? upgradeCost;
        [ObservableProperty]
        private int? areaType;
        [ObservableProperty]
        private int? motorcycleFlow;
        [ObservableProperty]
        private int? bicycleFlow;
        [ObservableProperty]
        private int? pedestrianRoadFlow;
        [ObservableProperty]
        private int? pedestrianDriverFlow;
        [ObservableProperty]
        private int? pedestrianPassengerFlow;
        [ObservableProperty]
        private int? landUseWidthDriver;
        [ObservableProperty]
        private int? landUseWidthPassenger;
        //Codificação Aba A2
        [ObservableProperty]
        private int? carSpeedLimit;
        [ObservableProperty]
        private int? motorcycleSpeedLimit;
        [ObservableProperty]
        private int? truckSpeedLimit;
        [ObservableProperty]
        private bool? delineation;
        [ObservableProperty]
        private bool? differentialSpeed;
        [ObservableProperty]
        private bool? soundLandUse;
        [ObservableProperty]
        private bool? soundMiddle;
        [ObservableProperty]
        private int? soilDriver;
        [ObservableProperty]
        private int? soilPassenger;
        [ObservableProperty]
        private int? medianType;
        [ObservableProperty]
        private List<string> speedLimitSource;

        //codificações aba a3
        [ObservableProperty]
        private int? roadQuality;
        [ObservableProperty]
        private int? curvature;
        [ObservableProperty]
        private int? curvatureQuality;
        [ObservableProperty]
        private int? propertyAccess;
        [ObservableProperty]
        private int? incline;
        [ObservableProperty]
        private int? roadWork;
        [ObservableProperty]
        private bool? marginRoad;
        [ObservableProperty]
        private int? visibilityDistance;

        //Codificações aba a4
        [ObservableProperty]
        private int? severityObjectDriver;
        [ObservableProperty]
        private int? severityDistanceDriver;
        [ObservableProperty]
        private int? severityObjectPassenger;
        [ObservableProperty]
        private int? severityDistancePassenger;
        //Codificações aba a5
        [ObservableProperty]
        private int? pedCrossInspected;
        [ObservableProperty]
        private int? pedCrossTransversal;
        [ObservableProperty]
        private int? crossingQuality;
        [ObservableProperty]
        private int? vehicleParking;
        [ObservableProperty]
        private bool? pedChanneling;
        [ObservableProperty]
        private bool? speedControl;
        //Codificações aba a6
        [ObservableProperty]
        private int? intersectionType;
        [ObservableProperty]
        private int? intersectionQuality;
        [ObservableProperty]
        private bool? intersectionChanneling;
        [ObservableProperty]
        private bool? publicLighthing;
        [ObservableProperty]
        private int? trafficVolumeTransversal;
        [ObservableProperty]
        private int? skidResistance;
        [ObservableProperty]
        private int? laneNumber;
        [ObservableProperty]
        private int? laneWidth;
        //Codificações aba a7
        [ObservableProperty]
        private int? infraMotorcycle;
        [ObservableProperty]
        private int? infraBicycle;
        [ObservableProperty]
        private int? sideWalkDriver;
        [ObservableProperty]
        private int? sideWalkPassenger;
        [ObservableProperty]
        private int? schoolWarn;
        [ObservableProperty]
        private int? schoolSupervisor;
        //Informações geográficas
        [ObservableProperty]
        private decimal? latitude;
        [ObservableProperty]
        private decimal? longitude;
        //Informações na aba SEG
        [ObservableProperty]
        private string? comments;
        [ObservableProperty]
        private string? landmark;

        //Commmands usados na view
        public RelayCommand nextSeg { get; }
        public RelayCommand prevSeg { get; }

        public RelayCommand stationHandler { get; }
        public RelayCommand<string> stationHotkey { get; }
        public RelayCommand saveCoding { get; }
        public RelayCommand exportProj { get; }
        public CodingPageViewModel()
        {
            codingCtx = new List<Coding?>();
            nextSeg = new RelayCommand(nextSegment);
            prevSeg = new RelayCommand(previousSegment);
            saveCoding = new RelayCommand(SaveCodingCtx);
            exportProj = new RelayCommand(Export);
            stationHandler = new(StationHandle);
            stationHotkey = new(StationHotkey);

            leftImagesList = new List<string>();
            rightImagesList = new List<string>();
            SegmentCurrent = 1;
        }
        public static object GetPropValue(object src, string propName)
        {
            return src.GetType().GetProperty(propName).GetValue(src, null);
        }
        private List<string[]> ReadErrorCsv()
        {


            var lines = File.ReadAllLines(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "errors.csv"));
            List<string[]> result = new List<string[]>();
            foreach (var line in lines)
            {
                var fields = line.Split(';');
                result.Add(fields);
            }
            result.RemoveAt(0);
            return result;
        }

        private SegmentGridData ProcessSingleSegment(Coding coding, List<string[]> errorTests, int index)
        {
            var SelectedLanguage = ConfigManager.GetLanguage();
            var x = new SegmentGridData
            {
                InitialKm = (decimal)coding.InitialKm,
                SegmentComment = coding.Landmark,
                SegmentIndex = index,
                EllipseCodeState = Brush.Parse("Green")

            };
            string NonCodified = string.Empty;
            //Checa se não está codificado
            if (!IsAllPropertiesCoded(coding, out NonCodified))
            {
                x.EllipseCodeState = Brush.Parse("Gray");
                x.FlyOutErrorTip = NonCodified;
                return x;
            }
            //Usa a lista de erros csv
            foreach (var error in errorTests)
            {
                string errorPhrase = SelectedLanguage switch
                {
                    "pt-BR" => error[0],
                    "en-US" => error[12],
                    "es" => error[13]
                };

                if (error[7] == "N/A")
                {
                    if ((int)GetPropValue(coding, error[1]) == int.Parse(error[2]) &&
                        (int)GetPropValue(coding, error[4]) == int.Parse(error[5]))
                    {
                        if (error[10] == "No")
                        {
                            x.EllipseCodeState = Brush.Parse("Yellow");
                            x.FlyOutErrorTip = errorPhrase;
                            break;
                        }
                        else if (error[11] == "No")
                        {
                            x.EllipseCodeState = Brush.Parse("Red");
                            x.FlyOutErrorTip = errorPhrase;
                            break;
                        }
                    }
                }
                else
                {
                    if ((int)GetPropValue(coding, error[1]) == int.Parse(error[2]) &&
                        (int)GetPropValue(coding, error[4]) == int.Parse(error[5]) &&
                        (int)GetPropValue(coding, error[7]) == int.Parse(error[8]))
                    {
                        if (error[10] == "No")
                        {
                            x.EllipseCodeState = Brush.Parse("Yellow");
                            x.FlyOutErrorTip = errorPhrase;
                            break;
                        }
                        else if (error[11] == "No")
                        {
                            x.EllipseCodeState = Brush.Parse("Red");
                            x.FlyOutErrorTip = errorPhrase;
                            break;

                        }
                    }
                }
            }

            return x;
        }

        public void PopulateGridSegData()
        {
            var resultData = new List<SegmentGridData>();
            var errorTests = ReadErrorCsv();
            errorTests.RemoveAt(0); // Remove the headers

            int counter = 1;
            foreach (var coding in codingCtx)
            {
                var segmentData = ProcessSingleSegment(coding, errorTests, counter);
                resultData.Add(segmentData);
                counter++;
            }
            SegmentGridData = new(resultData);
        }

        public void LoadSegfromGrid()
        {
            CrudHelper.RefreshContext();
            SaveCodingCtx();
            SegmentGridData[segment] = ProcessSingleSegment(codingCtx[segment], ReadErrorCsv(), segment + 1);

            SegmentCurrent = SelectedSegment.SegmentIndex;
            segment = SelectedSegment.SegmentIndex - 1;
            try
            {
                SetContext();
            }
            catch (Exception ex)
            {
                Log.Debug(ex, "Error Setting Context");
            }
        }

        public void SaveCodingCtx()
        {
            Log.Debug("Saving segment encoding");
            this.codingCtx[segment] = CrudHelper.SaveRemappedCoding(this, true);
            Log.Debug("Save completed");
        }

        private void StationHandle()
        {
            switch (SelectedStation)
            {
                case 0:
                    FirstPhoto();
                    break;
                case 1:
                    ScndPhoto();
                    break;
                case 2:
                    ThirdPhoto();
                    break;
                case 3:
                    FourthPhoto();
                    break;
                case 4:
                    FifthPhoto();
                    break;
            }
        }

        private void StationHotkey(string? key)
        {
            if (key == "PageUp" && SelectedStation > 0)
                SelectedStation--;

            if (key == "PageDown" && SelectedStation < 4)
                SelectedStation++;

            if (key == "CtrlPageDown")
                nextSegment();
            if (key == "CtrlPageUp")
                previousSegment();
        }
        public void FirstPhoto()
        {
            if (LeftImagesList.Count() > 0)

                LeftImageString = LeftImagesList[0];

            if (RightImagesList.Count() > 0)
                RightImageString = RightImagesList[0];

            LoadPhotos();
        }

        public void ScndPhoto()
        {
            if (LeftImagesList.Count() > 1)

                LeftImageString = LeftImagesList[1];

            if (RightImagesList.Count() > 1)
                RightImageString = RightImagesList[1];

            LoadPhotos();
        }

        public void ThirdPhoto()
        {
            if (LeftImagesList.Count() > 2)

                LeftImageString = LeftImagesList[2];

            if (RightImagesList.Count() > 2)
                RightImageString = RightImagesList[2];

            LoadPhotos();
        }
        public void FourthPhoto()
        {
            if (LeftImagesList.Count() > 3)

                LeftImageString = LeftImagesList[3];

            if (RightImagesList.Count() > 3)
                RightImageString = RightImagesList[3];

            LoadPhotos();
        }
        public void FifthPhoto()
        {
            if (LeftImagesList.Count() > 4)

                LeftImageString = LeftImagesList[4];

            if (RightImagesList.Count() > 4)
                RightImageString = RightImagesList[4];

            LoadPhotos();
        }
        public void previousSegment()
        {

            if (segment != 0)
            {
                //First save the current segment
                Log.Debug($"Saving segment {SegmentCurrent} encoding");
                SaveCodingCtx();
                Log.Debug("Save completed");
                SegmentGridData[segment] = ProcessSingleSegment(codingCtx[segment], ReadErrorCsv(), segment + 1);

                //Then change
                segment--;
                SegmentCurrent--;
                SelectedSegment = SegmentGridData.ElementAt(segment);

                this.SetContext();
            }

        }
        public void nextSegment()
        {
            //SegmentCurrent is only used for the progressbar
            if (segment < codingCtx.Count() - 1)
            {
                //First save the current segment
                Log.Debug($"Saving segment {SegmentCurrent} encoding");
                CrudHelper.RefreshContext();
                SaveCodingCtx();
                Log.Debug("Save completed");
                string OutPutAbas = string.Empty;
                if (CheckFieldsForNull(out OutPutAbas))
                {

                    if (!IsAllPropertiesCoded(codingCtx[segment + 1], out OutPutAbas))
                    {
                        CopyCoding(codingCtx[segment], codingCtx[segment + 1]);
                    }
                    SegmentCurrent++;
                    segment += 1;
                    SelectedSegment = SegmentGridData.ElementAt(segment);
                    SegmentGridData[segment - 1] = ProcessSingleSegment(codingCtx[segment - 1], ReadErrorCsv(), segment);


                    this.SetContext();
                }
                else
                {
                    DialogHelper.ShowOkDialog("NotChecked", OutPutAbas);
                }
            }
        }
        public void Export()
        {
            XlsxHandler.ExecuteOutput(projectId, 0);
        }

        public void LoadPhotos()
        {
            try
            {

                var proj = CrudHelper.dbCtx.Projects.Find(projectId);
                if (!Path.Exists(proj.ProjectPath))
                {
                    LeftImageString = "Foto não encontrada";
                    RightImageString = "Foto não encontrada";
                    Log.Error($"Error loading photos: Project Path not found -> {proj.ProjectPath}");

                }

                var rightPath = Path.Combine(proj.ProjectPath, "CAM 2", RightImageString);
                if (!Path.Exists(rightPath))
                    RightImage = null;
                else
                    RightImage = new Bitmap(rightPath);

                var leftPath = Path.Combine(proj.ProjectPath, "CAM 1", LeftImageString);
                if (!Path.Exists(leftPath))
                    LeftImage = null;
                else
                    LeftImage = new Bitmap(leftPath);
            }
            catch (Exception ex)
            {
                Log.Error(ex, "Error loading station photos");
            }
        }
        public async void SetContext()
        {
            try
            {
                if (currentProject.IsMph == null || currentProject.IsMph == false)
                {
                    SpeedLimitSource = new List<string> { ">=150km/h", ">=145km/h", "140km/h", "135km/h", "130km/h", "125km/h", "120km/h", "115km/h", "110km/h", "105km/h", "100km/h", "95km/h", "90km/h", "85km/h", "80km/h", "75km/h", "70km/h", "65km/h", "60km/h", "55km/h", "50km/h", "45km/h", "40km/h", "35km/h", "<30km/h" };
                }
                else
                {
                    SpeedLimitSource = new List<string> { ">=90mph", "85mph", "80mph", "75mph", "70mph", "65mph", "60mph", "55mph", "50mph", "45mph", "40mph", "35mph", "30mph", "25mph", "<24mph" };
                }

                codingId = codingCtx[segment].CodingId;
                //Aba a1
                CarriageWay = CrudHelper.MapCoding("CarriageWay", codingCtx[segment].CarriageWay);
                UpgradeCost = CrudHelper.MapCoding("UpgradeCost", codingCtx[segment].UpgradeCost);
                MotorcycleFlow = CrudHelper.MapCoding("ObservedFlow", codingCtx[segment].MotorcycleObserveredFlow);
                BicycleFlow = CrudHelper.MapCoding("ObservedFlow", codingCtx[segment].BicycleObservedFlow);
                PedestrianRoadFlow = CrudHelper.MapCoding("ObservedFlow", codingCtx[segment].PedestrianObservedFlow);
                PedestrianDriverFlow = CrudHelper.MapCoding("ObservedFlow", codingCtx[segment].PedestrianObservedAlongRoadDriver);
                PedestrianPassengerFlow = CrudHelper.MapCoding("ObservedFlow", codingCtx[segment].PedestrianObservedAlongRoadPassenger);
                LandUseWidthDriver = CrudHelper.MapCoding("PavedShoulder", codingCtx[segment].PavedShoulderDriversSide);
                LandUseWidthPassenger = CrudHelper.MapCoding("PavedShoulder", codingCtx[segment].PavedShoulderPassengerSide);
                AreaType = CrudHelper.MapCoding("AreaType", codingCtx[segment].AreaType);

                //Aba A2
                if (currentProject.IsMph == null || currentProject.IsMph == false)
                {
                    CarSpeedLimit = CrudHelper.MapCoding("SpeedLimit", codingCtx[segment].SpeedLimit);
                    TruckSpeedLimit = CrudHelper.MapCoding("SpeedLimit", codingCtx[segment].TruckSpeedLimit);
                    MotorcycleSpeedLimit = CrudHelper.MapCoding("SpeedLimit", codingCtx[segment].MotorcycleSpeedLimit);
                }
                else
                {
                    CarSpeedLimit = CrudHelper.MapCoding("SpeedLimitMPH", codingCtx[segment].SpeedLimit);
                    TruckSpeedLimit = CrudHelper.MapCoding("SpeedLimitMPH", codingCtx[segment].TruckSpeedLimit);
                    MotorcycleSpeedLimit = CrudHelper.MapCoding("SpeedLimitMPH", codingCtx[segment].MotorcycleSpeedLimit);
                }


                SoilDriver = CrudHelper.MapCoding("SoilUse", codingCtx[segment].LandUseDrivers);
                SoilPassenger = CrudHelper.MapCoding("SoilUse", codingCtx[segment].LandUsePassenger);
                MedianType = CrudHelper.MapCoding("MedianType", codingCtx[segment].MedianType);

                Delineation = codingCtx[segment].Delineation.HasValue
                    ? (codingCtx[segment].Delineation == 2 ? false : true)
                    : (bool?)null;


                DifferentialSpeed = codingCtx[segment].DifferentialSpeeds.HasValue
                    ? (codingCtx[segment].DifferentialSpeeds == 1 ? false : true)
                    : (bool?)null;

                SoundMiddle = codingCtx[segment].CentrelineRumbleStrips.HasValue
                    ? (codingCtx[segment].CentrelineRumbleStrips == 1 ? false : true)
                    : (bool?)null;
                SoundLandUse = codingCtx[segment].ShoulderRumbleStrips.HasValue
                    ? (codingCtx[segment].ShoulderRumbleStrips == 1 ? false : true)
                    : (bool?)null;
                //Aba a3
                RoadQuality = codingCtx[segment].RoadCondition.HasValue
                    ? codingCtx[segment].RoadCondition - 1
                    : (int?)null;
                Curvature = codingCtx[segment].Curvature.HasValue
                    ? codingCtx[segment].Curvature - 1
                    : (int?)null;
                CurvatureQuality = codingCtx[segment].QualityCurve.HasValue
                    ? codingCtx[segment].QualityCurve - 1
                    : (int?)null;

                PropertyAccess = CrudHelper.MapCoding("PropertyAccessPoints", codingCtx[segment].PropertyAccessPoints);
                Incline = CrudHelper.MapCoding("Grade", codingCtx[segment].Grade);
                RoadWork = CrudHelper.MapCoding("RoadWorks", codingCtx[segment].Roadworks);
                MarginRoad = codingCtx[segment].ServiceRoad == 1 ? false : true;
                VisibilityDistance = codingCtx[segment].SightDistance - 1;
                //Aba a4
                SeverityObjectDriver = CrudHelper.MapCoding("RoadsideSeverityObject", codingCtx[segment].RoadsideSeverityDriversSideObject);
                SeverityDistanceDriver = codingCtx[segment].RoadsideSeverityDriversSideDistance.HasValue
                     ? codingCtx[segment].RoadsideSeverityDriversSideDistance - 1
                     : (int?)null;
                SeverityObjectPassenger = CrudHelper.MapCoding("RoadsideSeverityObject", codingCtx[segment].RoadsideSeverityPassengerSideObject);
                SeverityDistancePassenger = codingCtx[segment].RoadsideSeverityPassengerSideDistance.HasValue
                     ? codingCtx[segment].RoadsideSeverityPassengerSideDistance - 1
                     : (int?)null;
                //Aba a5
                PedCrossInspected = CrudHelper.MapCoding("PedestrianCrossing", codingCtx[segment].PedestrianCrossingInspectedRoad);
                PedCrossTransversal = CrudHelper.MapCoding("PedestrianCrossing", codingCtx[segment].PedestrianCrossingFacilitiesSideRoad);
                CrossingQuality = codingCtx[segment].PedestrianCrossingQuality.HasValue
                     ? codingCtx[segment].PedestrianCrossingQuality - 1
                     : (int?)null;
                VehicleParking = codingCtx[segment].VehicleParking.HasValue
                     ? codingCtx[segment].VehicleParking - 1
                     : (int?)null;

                SpeedControl = codingCtx[segment].SpeedManagementTrafficCalming == 1 ? false : true;
                PedChanneling = codingCtx[segment].PedestrianFencing == 1 ? false : true;
                //Aba a6
                IntersectionType = CrudHelper.MapCoding("IntersectionType", codingCtx[segment].IntersectionType);
                IntersectionQuality = codingCtx[segment].IntersectionQuality.HasValue
                    ? codingCtx[segment].IntersectionQuality - 1
                    : (int?)null;

                IntersectionChanneling = codingCtx[segment].IntersectionChannelisation == 1 ? false : true;

                PublicLighthing = codingCtx[segment].StreetLighting == 1 ? false : true;

                TrafficVolumeTransversal = codingCtx[segment].IntersectingRoadVolume.HasValue
                    ? codingCtx[segment].IntersectingRoadVolume - 1
                    : (int?)null;
                SkidResistance = CrudHelper.MapCoding("SkidResistanceGrip", codingCtx[segment].SkidResistanceGrip);
                LaneNumber = CrudHelper.MapCoding("NumberLanes", codingCtx[segment].NumberLanes);
                LaneWidth = CrudHelper.MapCoding("LaneWidth", codingCtx[segment].LaneWidth);
                //Aba a7
                InfraMotorcycle = CrudHelper.MapCoding("FacilitiesMotorisedTwoWheelers", codingCtx[segment].FacilitiesMotorisedTwoWheelers);
                InfraBicycle = CrudHelper.MapCoding("BicycleFacility", codingCtx[segment].BicycleFacility);
                SideWalkDriver = CrudHelper.MapCoding("Sidewalk", codingCtx[segment].SidewalkDriversSide);
                SideWalkPassenger = CrudHelper.MapCoding("Sidewalk", codingCtx[segment].SidewalkPassengerSide);
                SchoolWarn = CrudHelper.MapCoding("SchoolZoneWarning", codingCtx[segment].SchoolZoneWarning);
                SchoolSupervisor = CrudHelper.MapCoding("SchoolZoneSupervisor", codingCtx[segment].SchoolZoneCrossingSupervisor);


                //Informações gerais
                Latitude = codingCtx[segment].Latitude;
                Longitude = codingCtx[segment].Longitude;
                CodingDate = codingCtx[segment].CodingDate.Date;
                CoderName = codingCtx[segment].CoderName;
                CodingDateString = CodingDate.ToShortDateString();
                Comments = codingCtx[segment].Comments;
                Landmark = codingCtx[segment].Landmark;
                //Verifica se o projeto é de pulso negativo
                if (currentProject.KmStart < currentProject.KmEnd)
                {
                    InitialKM = Math.Truncate((decimal)codingCtx[segment].InitialKm * 100) / 100;
                    FinalKM = Math.Truncate((decimal)codingCtx[segment].FinalKm * 100) / 100;
                }
                else
                {
                    FinalKM = Math.Truncate((decimal)codingCtx[segment].InitialKm * 100) / 100;
                    InitialKM = Math.Truncate((decimal)codingCtx[segment].FinalKm * 100) / 100;

                }
                SelectedStation = 0;

                LeftImagesList.Clear();
                RightImagesList.Clear();
                foreach (var codImage in codingImagesCtx)
                {
                    if (codImage.CodingId == codingCtx[segment].CodingId)
                    {
                        if (codImage.Type == 1)
                        {
                            LeftImagesList.Add(codImage.ImageName);
                        }
                        else
                        {
                            RightImagesList.Add(codImage.ImageName);
                        }
                    }
                }
                Debug.WriteLine("\nLeftCount:" + LeftImagesList.Count() + "RightCount:" + RightImagesList.Count());
                LeftImageString = LeftImagesList.Count > 0 ? LeftImagesList[0] : Localizer.Localizer.Instance["NoPhoto"];
                RightImageString = RightImagesList.Count > 0 ? RightImagesList[0] : Localizer.Localizer.Instance["NoPhoto"];
                LoadPhotos();
            }
            catch (Exception ex)
            {
                Log.Debug(ex, "Error Setting Coding Context");
            }
        }

        //Usado na hora de passar segmento ver quais abas não estão codificadas
        public bool CheckFieldsForNull(out string nullFieldsAbas)
        {
            List<string> nullAbas = new List<string>();

            // Check Aba A1
            if (CarriageWay == null || UpgradeCost == null || AreaType == null || MotorcycleFlow == null ||
                BicycleFlow == null || PedestrianRoadFlow == null || PedestrianDriverFlow == null ||
                PedestrianPassengerFlow == null || LandUseWidthDriver == null || LandUseWidthPassenger == null)
            {
                nullAbas.Add("A1");
            }

            // Check Aba A2
            if (CarSpeedLimit == null || MotorcycleSpeedLimit == null || TruckSpeedLimit == null ||
                Delineation == null || DifferentialSpeed == null || SoundLandUse == null || SoundMiddle == null ||
                SoilDriver == null || SoilPassenger == null || MedianType == null)
            {
                nullAbas.Add("A2");
            }

            // Check Aba A3
            if (RoadQuality == null || Curvature == null || CurvatureQuality == null || PropertyAccess == null ||
                Incline == null || RoadWork == null || MarginRoad == null || VisibilityDistance == null)
            {
                nullAbas.Add("A3");
            }

            // Check Aba A4
            if (SeverityObjectDriver == null || SeverityDistanceDriver == null || SeverityObjectPassenger == null ||
                SeverityDistancePassenger == null)
            {
                nullAbas.Add("A4");
            }

            // Check Aba A5
            if (PedCrossInspected == null || PedCrossTransversal == null || CrossingQuality == null ||
                VehicleParking == null || PedChanneling == null || SpeedControl == null)
            {
                nullAbas.Add("A5");
            }

            // Check Aba A6
            if (IntersectionType == null || IntersectionQuality == null || IntersectionChanneling == null ||
                PublicLighthing == null || TrafficVolumeTransversal == null || SkidResistance == null ||
                LaneNumber == null || LaneWidth == null)
            {
                nullAbas.Add("A6");
            }

            // Check Aba A7
            if (InfraMotorcycle == null || InfraBicycle == null || SideWalkDriver == null || SideWalkPassenger == null ||
                SchoolWarn == null || SchoolSupervisor == null)
            {
                nullAbas.Add("A7");
            }

            nullFieldsAbas = string.Join(" - ", nullAbas);
            return nullAbas.Count == 0;
        }
        //Usado para o grid de segmentos.
        public bool IsAllPropertiesCoded(Coding coding, out string nullProperties)
        {
            nullProperties = string.Empty;

            if (coding.CarriageWay == null) nullProperties += "CarriageWay, ";
            if (coding.UpgradeCost == null) nullProperties += "UpgradeCost, ";
            if (coding.MotorcycleObserveredFlow == null) nullProperties += "MotorcycleObservedFlow, ";
            if (coding.BicycleObservedFlow == null) nullProperties += "BicycleObservedFlow, ";
            if (coding.PedestrianObservedFlow == null) nullProperties += "PedestrianObservedFlow, ";
            if (coding.PedestrianObservedAlongRoadDriver == null) nullProperties += "PedestrianObservedAlongRoadDriver, ";
            if (coding.PedestrianObservedAlongRoadPassenger == null) nullProperties += "PedestrianObservedAlongRoadPassenger, ";
            if (coding.LandUseDrivers == null) nullProperties += "LandUseDrivers, ";
            if (coding.LandUsePassenger == null) nullProperties += "LandUsePassenger, ";
            if (coding.AreaType == null) nullProperties += "AreaType, ";
            if (coding.SpeedLimit == null) nullProperties += "SpeedLimit, ";
            if (coding.MotorcycleSpeedLimit == null) nullProperties += "MotorcycleSpeedLimit, ";
            if (coding.TruckSpeedLimit == null) nullProperties += "TruckSpeedLimit, ";
            if (coding.DifferentialSpeeds == null) nullProperties += "DifferentialSpeeds, ";
            if (coding.MedianType == null) nullProperties += "MedianType, ";
            if (coding.CentrelineRumbleStrips == null) nullProperties += "CentrelineRumbleStrips, ";
            if (coding.RoadsideSeverityDriversSideDistance == null) nullProperties += "RoadsideSeverityDriversSideDistance, ";
            if (coding.RoadsideSeverityDriversSideObject == null) nullProperties += "RoadsideSeverityDriversSideObject, ";
            if (coding.RoadsideSeverityPassengerSideDistance == null) nullProperties += "RoadsideSeverityPassengerSideDistance, ";
            if (coding.RoadsideSeverityPassengerSideObject == null) nullProperties += "RoadsideSeverityPassengerSideObject, ";
            if (coding.ShoulderRumbleStrips == null) nullProperties += "ShoulderRumbleStrips, ";
            if (coding.PavedShoulderDriversSide == null) nullProperties += "PavedShoulderDriversSide, ";
            if (coding.PavedShoulderPassengerSide == null) nullProperties += "PavedShoulderPassengerSide, ";
            if (coding.IntersectionType == null) nullProperties += "IntersectionType, ";
            if (coding.IntersectionChannelisation == null) nullProperties += "IntersectionChannelisation, ";
            if (coding.IntersectingRoadVolume == null) nullProperties += "IntersectingRoadVolume, ";
            if (coding.IntersectionQuality == null) nullProperties += "IntersectionQuality, ";
            if (coding.PropertyAccessPoints == null) nullProperties += "PropertyAccessPoints, ";
            if (coding.NumberLanes == null) nullProperties += "NumberLanes, ";
            if (coding.LaneWidth == null) nullProperties += "LaneWidth, ";
            if (coding.Curvature == null) nullProperties += "Curvature, ";
            if (coding.QualityCurve == null) nullProperties += "QualityCurve, ";
            if (coding.Grade == null) nullProperties += "Grade, ";
            if (coding.RoadCondition == null) nullProperties += "RoadCondition, ";
            if (coding.SkidResistanceGrip == null) nullProperties += "SkidResistanceGrip, ";
            if (coding.Delineation == null) nullProperties += "Delineation, ";
            if (coding.StreetLighting == null) nullProperties += "StreetLighting, ";
            if (coding.PedestrianCrossingInspectedRoad == null) nullProperties += "PedestrianCrossingInspectedRoad, ";
            if (coding.PedestrianCrossingQuality == null) nullProperties += "PedestrianCrossingQuality, ";
            if (coding.PedestrianCrossingFacilitiesSideRoad == null) nullProperties += "PedestrianCrossingFacilitiesSideRoad, ";
            if (coding.PedestrianFencing == null) nullProperties += "PedestrianFencing, ";
            if (coding.SpeedManagementTrafficCalming == null) nullProperties += "SpeedManagementTrafficCalming, ";
            if (coding.VehicleParking == null) nullProperties += "VehicleParking, ";
            if (coding.SidewalkDriversSide == null) nullProperties += "SidewalkDriversSide, ";
            if (coding.SidewalkPassengerSide == null) nullProperties += "SidewalkPassengerSide, ";
            if (coding.ServiceRoad == null) nullProperties += "ServiceRoad, ";
            if (coding.FacilitiesMotorisedTwoWheelers == null) nullProperties += "FacilitiesMotorisedTwoWheelers, ";
            if (coding.BicycleFacility == null) nullProperties += "BicycleFacility, ";
            if (coding.Roadworks == null) nullProperties += "Roadworks, ";
            if (coding.SightDistance == null) nullProperties += "SightDistance, ";
            if (coding.SchoolZoneWarning == null) nullProperties += "SchoolZoneWarning, ";
            if (coding.SchoolZoneCrossingSupervisor == null) nullProperties += "SchoolZoneCrossingSupervisor, ";

            // Remove the trailing comma and space, if any
            if (nullProperties.EndsWith(", "))
            {
                nullProperties = nullProperties.Substring(0, nullProperties.Length - 2);
            }

            // Return false if there are any null properties
            return string.IsNullOrEmpty(nullProperties);
        }


        public void CopyCoding(Coding source, Coding target)
        {
            if (source == null || target == null)
            {
                throw new ArgumentNullException("Source or target is null");
            }

            Debug.WriteLine(currentProject.ViaSeguraLabeled);

            if (currentProject.ViaSeguraLabeled != null)
            {
                if (!currentProject.ViaSeguraLabeled.Contains("carriageway"))
                    target.CarriageWay = source.CarriageWay;
                if (!currentProject.ViaSeguraLabeled.Contains("upgrade_cost"))
                    target.UpgradeCost = source.UpgradeCost;
                if (!currentProject.ViaSeguraLabeled.Contains("land_use"))
                {
                    target.LandUseDrivers = source.LandUseDrivers;
                    target.LandUsePassenger = source.LandUsePassenger;
                }
                if (!currentProject.ViaSeguraLabeled.Contains("area_type"))
                    target.AreaType = source.AreaType;
                if (!currentProject.ViaSeguraLabeled.Contains("property_acess_points"))
                    target.PropertyAccessPoints = source.PropertyAccessPoints;
                if (!currentProject.ViaSeguraLabeled.Contains("number_of_lanes"))
                    target.NumberLanes = source.NumberLanes;
                if (!currentProject.ViaSeguraLabeled.Contains("PreCurvature"))
                    target.Curvature = source.Curvature;
                if (!currentProject.ViaSeguraLabeled.Contains("quality_of_curve"))
                    target.QualityCurve = source.QualityCurve;
                if (!currentProject.ViaSeguraLabeled.Contains("road_condition"))
                    target.RoadCondition = source.RoadCondition;
                if (!currentProject.ViaSeguraLabeled.Contains("skid_resistance"))
                    target.SkidResistanceGrip = source.SkidResistanceGrip;
                if (!currentProject.ViaSeguraLabeled.Contains("delineation"))
                    target.Delineation = source.Delineation;
                if (!currentProject.ViaSeguraLabeled.Contains("street_lighting"))
                    target.StreetLighting = source.StreetLighting;
                if (!currentProject.ViaSeguraLabeled.Contains("speed_management"))
                    target.SpeedManagementTrafficCalming = source.SpeedManagementTrafficCalming;
                if (!currentProject.ViaSeguraLabeled.Contains("vehicle_parking"))
                    target.VehicleParking = source.VehicleParking;
                if (!currentProject.ViaSeguraLabeled.Contains("service_road"))
                    target.ServiceRoad = source.ServiceRoad;
                if (!currentProject.ViaSeguraLabeled.Contains("bicycle_facility"))
                    target.BicycleFacility = source.BicycleFacility;
            }
            else 
            {
                target.CarriageWay = source.CarriageWay;
                target.UpgradeCost = source.UpgradeCost;
                target.LandUseDrivers = source.LandUseDrivers;
                target.LandUsePassenger = source.LandUsePassenger;
                target.AreaType = source.AreaType;
                target.PropertyAccessPoints = source.PropertyAccessPoints;
                target.NumberLanes = source.NumberLanes;
                target.QualityCurve = source.QualityCurve;
                target.Curvature = source.Curvature;
                target.SkidResistanceGrip = source.SkidResistanceGrip;
                target.RoadCondition = source.RoadCondition;
                target.Delineation = source.Delineation;
                target.StreetLighting = source.StreetLighting;
                target.SpeedManagementTrafficCalming = source.SpeedManagementTrafficCalming;
                target.VehicleParking = source.VehicleParking;
                target.ServiceRoad = source.ServiceRoad;
                target.BicycleFacility = source.BicycleFacility;
            }

            target.MotorcycleObserveredFlow = source.MotorcycleObserveredFlow;
            target.BicycleObservedFlow = source.BicycleObservedFlow;
            target.PedestrianObservedFlow = source.PedestrianObservedFlow;
            target.PedestrianObservedAlongRoadDriver = source.PedestrianObservedAlongRoadDriver;
            target.PedestrianObservedAlongRoadPassenger = source.PedestrianObservedAlongRoadPassenger;
            
            
            target.SpeedLimit = source.SpeedLimit;
            target.MotorcycleSpeedLimit = source.MotorcycleSpeedLimit;
            target.TruckSpeedLimit = source.TruckSpeedLimit;
            target.DifferentialSpeeds = source.DifferentialSpeeds;
            target.MedianType = source.MedianType;
            target.CentrelineRumbleStrips = source.CentrelineRumbleStrips;
            target.RoadsideSeverityDriversSideDistance = source.RoadsideSeverityDriversSideDistance;
            target.RoadsideSeverityDriversSideObject = source.RoadsideSeverityDriversSideObject;
            target.RoadsideSeverityPassengerSideDistance = source.RoadsideSeverityPassengerSideDistance;
            target.RoadsideSeverityPassengerSideObject = source.RoadsideSeverityPassengerSideObject;
            target.ShoulderRumbleStrips = source.ShoulderRumbleStrips;
            target.PavedShoulderDriversSide = source.PavedShoulderDriversSide;
            target.PavedShoulderPassengerSide = source.PavedShoulderPassengerSide;
            target.IntersectionType = source.IntersectionType;
            target.IntersectionChannelisation = source.IntersectionChannelisation;
            target.IntersectingRoadVolume = source.IntersectingRoadVolume;
            target.IntersectionQuality = source.IntersectionQuality;
           
            target.LaneWidth = source.LaneWidth;
            
            target.Grade = source.Grade;
           
            target.PedestrianCrossingInspectedRoad = source.PedestrianCrossingInspectedRoad;
            target.PedestrianCrossingQuality = source.PedestrianCrossingQuality;
            target.PedestrianCrossingFacilitiesSideRoad = source.PedestrianCrossingFacilitiesSideRoad;
            target.PedestrianFencing = source.PedestrianFencing;
           
            target.SidewalkDriversSide = source.SidewalkDriversSide;
            target.SidewalkPassengerSide = source.SidewalkPassengerSide;
           
            target.FacilitiesMotorisedTwoWheelers = source.FacilitiesMotorisedTwoWheelers;
            
            target.Roadworks = source.Roadworks;
            target.SightDistance = source.SightDistance;
            target.VehicleFlow = source.VehicleFlow;
            target.MotorcyclePercentual = source.MotorcyclePercentual;
            target.PedestrianPeakHourFlowAcrossRoad = source.PedestrianPeakHourFlowAcrossRoad;
            target.PedestrianPeakHourFlowAlongRoadDriver = source.PedestrianPeakHourFlowAlongRoadDriver;
            target.PedestrianPeakHourFlowAlongRoadPassenger = source.PedestrianPeakHourFlowAlongRoadPassenger;
            target.BicyclePeakHourlyFlow = source.BicyclePeakHourlyFlow;
            target.OperatingSpeed85thPercentile = source.OperatingSpeed85thPercentile;
            target.OperatingSpeedMean = source.OperatingSpeedMean;
            target.RoadsCarsRead = source.RoadsCarsRead;
            target.CarStarRatingPolicyTarget = source.CarStarRatingPolicyTarget;
            target.MotorcycleStarRatingPolicyTarget = source.MotorcycleStarRatingPolicyTarget;
            target.PedestrianStarRatingPolicyTarget = source.PedestrianStarRatingPolicyTarget;
            target.BicycleStarRatingPolicyTarget = source.BicycleStarRatingPolicyTarget;
            target.AnnualFatalityGrowthMultiplier = source.AnnualFatalityGrowthMultiplier;
            target.SchoolZoneWarning = source.SchoolZoneWarning;
            target.SchoolZoneCrossingSupervisor = source.SchoolZoneCrossingSupervisor;

        }

    }
}
