using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Catalog;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Editing;
using ArcGIS.Desktop.Extensions;
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using System.Collections.ObjectModel;
using ArcGIS.Desktop.Framework.Dialogs;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using OliviaAddInPro.Helper;
using OliviaAddInPro.Model;
using System.Windows.Media.Imaging;
using static OliviaAddInPro.Model.ComunDef;


namespace OliviaAddInPro
{
    internal class PaneRecogidaViewModel : PanelViewModelBase
    {
        private PaneRecogidaSub1ViewModel _subPanel1ViewModel;
         Recogida reco;

        public PaneRecogidaViewModel()
        {
            _subPanel1ViewModel = new PaneRecogidaSub1ViewModel();
            _subPanel2ViewModel = new PaneLimpiezaSub2ViewModel();
            _subPanel3ViewModel = new PaneLimpiezaSub3ViewModel();
            _subPanel4ViewModel = new PaneLimpiezaSub4ViewModel();

            OptionsMenu = new ObservableCollection<OptionsMenuItem>
            {
               new OptionsMenuItem(new BitmapImage(new Uri("pack://application:,,,/OliviaAddInPro;component/Resources/inicio.png")), Resource1.String_tto, _subPanel1ViewModel),
                new OptionsMenuItem(new BitmapImage(new Uri("pack://application:,,,/OliviaAddInPro;component/Resources/zonas.png")), Resource1.String_zonif, _subPanel2ViewModel),
                new OptionsMenuItem(new BitmapImage(new Uri("pack://application:,,,/OliviaAddInPro;component/Resources/ptosctrl.png")), Resource1.String_ctrol, _subPanel3ViewModel),
                new OptionsMenuItem(new BitmapImage(new Uri("pack://application:,,,/OliviaAddInPro;component/Resources/time.png")), Resource1.String_tiempos, _subPanel4ViewModel)
            };
            SelectedOption = OptionsMenu[0];
            reco = OliviaGlob.Reco;
            CambiaParaPlanif();
        }
        public override string DisplayName
        {
            get { return Resource1.String_header_limpieza; }
        }
        private ObservableCollection<OptionsMenuItem> _optionsMenu = new ObservableCollection<OptionsMenuItem>();
        public ObservableCollection<OptionsMenuItem> OptionsMenu
        {
            get { return _optionsMenu; }
            set { SetProperty(ref _optionsMenu, value, () => OptionsMenu); }
        }

        private PanelViewModelBase _currentSubPanelPage;
        public PanelViewModelBase CurrentSubPanelPage
        {
            get { return _currentSubPanelPage; }
            set { SetProperty(ref _currentSubPanelPage, value, () => CurrentSubPanelPage); }
        }

        private OptionsMenuItem _selectionOption;
        public OptionsMenuItem SelectedOption
        {
            get { return _selectionOption; }
            set
            {
                SetProperty(ref _selectionOption, value, () => SelectedOption);
                CurrentSubPanelPage = value.SubPanelViewModel;
            }
        }
        public PaneRecogidaSub1ViewModel PaneSub1
        {
            get { return _subPanel1ViewModel; }
        }
        
        //cambia algunos textos para adaptarlo a la planificación
        public void CambiaParaPlanif()
        {
            _subPanel2ViewModel.TextLblNiv = "Turnos";
            _subPanel4ViewModel.TextTCargDesc = "Descarga en planta";
            _subPanel4ViewModel.TextTDesplIniFin = "Salida/llegada Inst.";
        }
        /**
         * Lee los paneles y sus elementos
         */ 
        public bool Lee(out string err_str)
        {
            err_str = "";
            try
            {
                //Rellena el array de filtros
                reco.RellenaFiltrosReco();

                ////////////////////////////////////////////////////////////
                ///Lee el panel 1
                if (!_subPanel1ViewModel.CapaAbierta || string.IsNullOrEmpty(_subPanel1ViewModel.CapaElems))
                {
                    err_str = "No se ha seleccionado ninguna Capa de Limpieza";
                    return false;
                }
                reco.CapaElems = _subPanel1ViewModel.CapaElems;               
                //lee la fracción
                reco.TipoFrac = _subPanel1ViewModel.TipoFrac;
                if (reco.TipoFrac == -1)
                {
                    err_str = "No se ha seleccionado ningún Tipo de Fracción";
                    return false;
                }
                reco.TipoFracStr = RecogidaDef.tipos_fracc_str[reco.TipoFrac];
                reco.TipoTto = reco.TipoFrac;
                reco.TipoTtoStr = RecogidaDef.tipos_fracc_str[reco.TipoFrac];

                //lee la densidad del contenedor
                //si se ha seleccionado que se recogen los contenedores llenos hay que comprobar que se ha rellenado la densidad de los contenedores
                if (RecogidaDef.lleno )
                {
                    try
                    {
                        reco.DensCont = Convert.ToInt32(_subPanel1ViewModel.TextDensCont);
                        if (reco.DensCont <= 0 || reco.DensCont > 1000)
                        {
                            err_str = "El valor introducido para la densidad del contenedor no es válido.";
                            return false;
                        }
                    }
                    catch (Exception)
                    {
                        err_str = "El formato introducido para la densidad del contenedor no es válido.";
                        return false;
                    }
                }
                else
                    reco.DensCont = -1;

                //lee el tipo de carga
                reco.TipoCarg = _subPanel1ViewModel.TipoCarg;
                if (reco.TipoCarg == -1)
                {
                    err_str = "No se ha seleccionado ningún Tipo de Carga";
                    return false;
                }
                reco.TipoCargStr=RecogidaDef.tipos_carg_str[reco.TipoCarg];

                //lee la lateralidad
                reco.TipoLate = -1;
                if (reco.TipoCarg == (int)RecogidaDef.TiposCarga.Lateral)
                {
                    reco.TipoLate = _subPanel1ViewModel.TipoLate;
                    if (reco.TipoLate == -1)
                    {
                        err_str = "No se ha seleccionado ningún Tipo de Lateralidad";
                        return false;
                    }
                }

                //lee el tipo de vehic
                reco.TipoVehic = _subPanel1ViewModel.TipoVehic;
                if (reco.TipoVehic == -1)
                {
                    err_str = "No se ha seleccionado ningún Tipo de Vehículo";
                    return false;
                }

                reco.GiroVehic = (int)RecogidaDef.giro_vehic[reco.TipoVehic];

                //recoge la carga máxima del vehículo que se ha configurado
                try
                {
                    reco.KgMaxVehic = Convert.ToInt32(_subPanel1ViewModel.TextKgCapac);
                    if ((reco.KgMaxVehic <= 0) || (reco.KgMaxVehic > RecogidaDef.Parametros.kgmaxM) || (reco.KgMaxVehic < RecogidaDef.Parametros.kgmaxm))
                    {
                        err_str = "El valor introducido para la carga máxima del vehículo no es válido.";
                        return false;
                    }
                }
                catch (Exception)
                {
                    err_str = "El formato introducido para la carga máxima del vehículo no es válido.";
                    return false;
                }
                //recoge el tiempo de vaciado que se ha configurado
                try
                {
                    reco.TVaciCont = Convert.ToInt32(_subPanel1ViewModel.TextTVaci);
                    if ((reco.TVaciCont <= 0) || (reco.TVaciCont > RecogidaDef.Parametros.t_vaciM) || (reco.TVaciCont < RecogidaDef.Parametros.t_vacim))
                    {
                        err_str = "El valor introducido para el tiempo de vaciado no es válido.";
                        return false;
                    }
                }
                catch (FormatException)
                {
                    err_str = "El formato introducido para el tiempo de vaciado no es válido.";
                    return false;
                }
                //revisa las coordenadas de la planta de descarga
                reco.CoordsPlanta = _subPanel1ViewModel.CoordsPlanta;
                if (reco.CoordsPlanta.Equals(new Coordinate2D(0, 0)))
                {
                    err_str = "No se ha seleccionado planta de descarga";
                    return false;
                }

                //revisa coordenadas de instalación
                if (_subPanel2ViewModel.CoordsInstal.Equals(new Coordinate2D(0, 0)))
                {
                    err_str = "No se ha seleccionado instalación de salida/llegada";
                    return false;
                }

                //lee las propiedades comunes a recogida
                if (!LeeComun(reco, out err_str))
                {
                    return false;
                }
                return true;
            }
            catch
            {
                err_str = "Error al leer ventana de descarga: "+ err_str;
                return false;
            }
        }

        /**
            * Acciones para comenzar ejecución
            */
        public void Ejecuta(OliviaAddInPro.Services.ModosEjec modo)
        {
            string err = "";
            //comprueba datos de la ventana
            if (!Lee(out err))
            {
                HelperGlobal.ponMsg(err);
                return;
            }
            //marchando
            OliviaGlob.Reco.ProgrSrc = new MyCancelableProgressorSource(OliviaGlob.progrDialog.GetViewModel());

            OliviaGlob.Limp.ProgrSrc._ProgrSrc.SetProceso("");
            OliviaGlob.Limp.ProgrSrc._ProgrSrc.SetEstado("");
            OliviaGlob.Limp.ProgrSrc._ProgrSrc.SetProgress(0);
            OliviaGlob.Limp.ProgrSrc._ProgrSrc.SetTextBtn("Cancelar");
            OliviaGlob.Limp.ProgrSrc._ProgrSrc.PonBarColorVerde();
            //oculta la ventana
            OliviaGlob.ShowHidePane(false);

            OliviaGlob.Reco.ComienzaEjec(modo);
        }
    }
}
