using ArcGIS.Core.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OliviaAddInPro.Helper;
using System.Collections.ObjectModel;
using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using OliviaAddInPro.Services;
using static OliviaAddInPro.Model.ComunDef;
using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using OliviaAddInPro.Services.LanzaSrv;

namespace OliviaAddInPro.Model
{
    public class Limpieza : TratamientoComun
    {
        //**********************************************
        //Se recogen en PaneLimpiezaSub1        
        /**
         * Ámbitos de trabajo elegidos
         */
        public bool[] AmbitosSel { get; set; } = new bool[(int)LimpiezaDef.AmbitsTra.AmbN];
        /**
         * Indica si respeta el sentido de circulación o no
         */
        public bool RespCirc { get; set; } = false;
        /**
         * Tipo de unidades del tiempo de tto
         */
        public int UdsTTto { get; set; } = (int)GeneralDef.OlvTiposTto.OlvTipTtoNoDef;        
        /**
         * Instancia para las funciones de exportación y demás
         */

        public LimpiezaServ Serv
        {
            get
            {
                return (LimpiezaServ)ServCom;
            }
            set
            {
                ServCom = value;
            }
        }
        public LanzaLimpSrv LanzaSrv { get; set; } = null;

        /**
          * Ancho de vía, en metros
          */
        public double AnchoVia { get; set; } = LimpiezaDef.Parametros.ancho_via;
        public Limpieza()
        {
            Serv = new LimpiezaServ(this);
			LanzaSrv = new LanzaLimpSrv();            
        }

       public override Respuesta<TiposEjecucion> Ejecuta(ModosEjec modo)
        {
            /////////////////////////////

            Respuesta<bool> res = new Respuesta<bool> { Value=false};
            Respuesta<TiposEjecucion> res2 = new Respuesta<TiposEjecucion> (){ Value = TiposEjecucion.FinEjecNOk };
            res = Serv.Ejecuta(modo);            
			if (res.Value)
            {
                res=LanzaSrv.ejec(this, modo, TipoTtoStr);
                if (res.Value)
                {                    
                    ProceSrv.ConfigConex();
                    res2 = ProceSrv.start(LanzaSrv.str_cfg, ProgrSrc._ProgrSrc);
                    if(!LanzaSrv.EsperaProcess(GeneralDef.NombOlvTasks))
                        res2.Error.Add("No se ha podido cerrar oliviaTask.");
                }
            }
            if (res.HasError)
            {
                res2.Error.AddRange(res.Error);
            }
            return res2;
        }

        /**
         * Descodifica el nombre del sahpefile de entrada identificando el tipo de tratamiento y los ámbitos de trabajo
         */
        public override void decode_gdb(string shapefile, out string tratamiento, out string ambitos)
        {
            int aux, auxl, mbito, indice, tratamient;
            string auxili, ambi, auxi;

            indice = shapefile.IndexOf("_");
            indice = indice + 2;//para saltarse la T que va antes del identificador del tipo de tratamiento
            auxili = shapefile.Substring(indice, 2);
            tratamient = Convert.ToInt32(auxili);
            tratamiento = LimpiezaDef.tto_gdb[tratamient];
            indice = shapefile.IndexOf("_", indice);
            indice = indice + 2;//para saltarse la A que va antes del identificador de los ámbitos que intervienen
            aux = shapefile.IndexOf("_", indice);
            auxl = aux - indice;
            auxi = "";
            while (auxl > 0)
            {
                ambi = shapefile.Substring(indice, 2);
                mbito = Convert.ToInt32(ambi);
                indice = indice + 2;
                auxl = auxl - 2;
                if (auxl != 0)
                    auxi = auxi + LimpiezaDef.ambs_gdb[mbito] + "_";
                else
                    auxi = auxi + LimpiezaDef.ambs_gdb[mbito];
            }
            ambitos = LimpiezaDef.preftto_gdb[tratamient] + "_" + auxi;

            //quita los espacios
            tratamiento = tratamiento.Replace(" ", "_");
            ambitos = ambitos.Replace(" ", "_");

            auxi = shapefile;
            //para poner la zona cuando es seleccionada
            for (int i = 0; i < 2; i++)
            {
                indice = auxi.LastIndexOf("_");
                auxi = auxi.Substring(0, indice);
            }
            auxl = indice - aux;
            if (auxl > 0)
            {
                auxili = shapefile.Substring(aux, auxl);
                ambitos = ambitos + auxili;
                
                aux = indice; //para coger el timestamp
            }
                
            //concatena el timestamp            
            ambitos = ambitos + shapefile.Substring(aux);

        }
        /**
         * Devuelve los campos característicos de la capa
         */ 
        public override string[] GetCampos(string capa=null)
        {
            string[] camps=null;
            var capa_ = !string.IsNullOrEmpty(capa) ? capa : CapaElems;
            if (string.IsNullOrEmpty(capa_))
            {
                ErrStr = "Error al comprobar campos en la capa.";
                return camps;
            }
            GeometryType tipo = HelperGdb.GetGeomType(capa_);
            if (tipo == GeometryType.Polyline)
            {
                int NCAMPS = 5;
                camps = new string[NCAMPS];
                camps[0] = LimpiezaDef.Campos.consulta_entidad;
                camps[1] = LimpiezaDef.Campos.consulta_mecan;
                camps[2] = LimpiezaDef.Campos.consulta_observ;
                camps[3] = LimpiezaDef.Campos.consulta_anch_tip;
                camps[4] = LimpiezaDef.Campos.consulta_tipolo;
            }
            else if (tipo == GeometryType.Point)//es mobiliario, con el tipo vale
            {
                int NCAMPS = 1;
                camps = new string[NCAMPS];
                camps[0] = LimpiezaDef.Campos.consulta_entidad;
            }
            else
            {
                ErrStr = "Error al comprobar campos en la capa.";
            }
            
            return camps;
        }
    }
}
