using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Catalog;

namespace OliviaAddIn
{
    /**
     * Elementos comunes a Limpieza y Recogida
     */ 
    public class Comun
    {
        //*************************************************************************************        
        //Variables
        /**
         * Texto cuando no se ha seleccionado instalación
         */
        public string text_selec_instal = "Instalación de salida/llegada";
        /**
        * Coordenadas de la instalación de partida, si las huibiera, 0 si no
        */
        public double[] coords_instala = new double[2];
        /**
         * Texto cuando no se ha seleccionado capa de restricciones
         */
        public string text_selec_rest = "Capa de restric. circ.";
        /**
        * Geometría que componen las restricciones de acceso, null si nunguna
        */
        public IGeometry geom_rest_acces = null;
        /**
         * Texto cuando no se ha seleccionado capa de zonas
         */
        public string text_selec_zonas = "Capa de zonas";
        /**
        * Geometría que componen las zonas seleccionadas, null si nunguna
        */
        public IGeometry geom_zonas = null;
        /**
         * Texto cuando no se ha seleccionado capa de limpieza otra
         */
        public string text_capa_limp = "Cambiar capa de limpieza...";    
        /**
        * String de errores de ejecución
        */
        public string err_st = null;
        /**
         * Tiempo de trabajo al día por convenio, en minutos
         */
        public double t_conv = LimpiezaDef.Parametros.t_conv;
        /**
         * Tiempo de descanso del personal, en minutos
         */
        public double t_descan = LimpiezaDef.Parametros.t_descanso;
        /**
         * Tiempo de carga y descarga, en minutos
         */
        public double t_descarg = LimpiezaDef.Parametros.t_cardesc;
        /**
         * Tiempo de desplazamiento inicio/fin a las instalaciones, en minutos
         */
        public double t_despl_insta = LimpiezaDef.Parametros.t_desp;
        /**
        * hora de inicio de la jornada de trabajo, en minutos
        */
        public double h_ini = LimpiezaDef.Parametros.h_inicio;
        /**
        * Porcentaje de tráfico que se estima, ya que si no los vehículos irían siempre a la velocida máxima permitida por la vía
        */
        public double trafico = 80;
        /**
         * Número de puntos de control
         */
        public int n_ptsctrl = 3;
        /**
         * Número de sectores por defecto
         */
        public int n_secdef = 3;
        /**
        * Parámentro que indica si se tendrán en cuenta en el estudio los elementos aislados. Si 1 se descartan aislados. Si 0 se tienen en cuenta en el cálculo.
        */
        public int aislados = -1;
        /**
         * String que almacena qué zonas se han seleccionado
         */
        public string text_zon = "";
        /**
         * String que almacena qué restricciones se han seleccionado
         */
        public string text_restr = "";
        /**
        * Path de la clase de los ámbitos
        */

        //*************************************************************************************        
        //Funciones
        /**
         * Para la selección de puntos de instalación
         * Abre el dialogo de selección de capa y el form para seleccionar campo a leer y valor del campo
         */ 
        public bool selec_instal(string title, int wnd_handle, out string text_sal, out double x, out double y)
        {      
            ListCamposVal list;
            IFeature f = null;
            IFeatureClass fc = null;
            IGeometry geom = null;

            list = new ListCamposVal(title, wnd_handle, esriGeometryType.esriGeometryPoint);
            text_sal = "";
            x = y = 0;

            try
            {
                IPoint instalacion;
                string campo, clase_path, st;
                int elem;
                int[] ids;

                clase_path = null;
                campo = st="";
                ids = null;
                elem = -1;

                clase_path = list.selec_capa();
                if (clase_path != null)
                {
                    elem = list.selec_campo(out campo);
                    if (elem > -1 && campo != null)
                    {
                        elem = list.selec_valor_campo(campo, out st);
                        if (elem > -1)
                        {
                            ids = FunGDB.dame_ids_consulta(clase_path, ""); //consulta todos
                            if (ids != null)
                            {
                                fc=FunGDB.abre_ftclass(clase_path);
                                if (fc != null)
                                {
                                    f = fc.GetFeature(ids[elem]);
                                    geom = f.Shape;
                                    instalacion = (IPoint)geom;
                                    x = instalacion.X;
                                    y = instalacion.Y;
                                    text_sal = st;
                                }
                            }
                        }
                    }
                }                
            }
            catch (Exception)
            {
                x = 0;
            }

            FunGDB.libera(fc);
            FunGDB.libera(geom);
            FunGDB.libera(f);

            if (x==0) //algo ha ido mal
            {
                MessageBox.Show("Error al seleccionar capa de instalaciones. " + list.err_st, "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            return true;
        }

        /**
         * Para la selección de capas de polígonos
         * Abre el dialogo de selección de capa y el form para seleccionar campo a leer y valor del campo
         * Permite multiselección
         * Tiene que mostrar valores únicos, no repetidos
         * Devuelve la geom resultante
         * En text_sal van concatenados los valores que se han seleccionado unidos por '_'
         */
        public bool selec_polig(string title, int wnd_handle, out string text_sal, out IGeometry geom_sal)
        {
            ListCamposVal list;
            IFeature f = null;
            IFeatureClass fc = null;
            IGeometry geom = null;

            list = new ListCamposVal(title, wnd_handle, esriGeometryType.esriGeometryPolygon);
            text_sal = "";
            geom_sal = null;

            try
            {

                string campo, clase_path, consulta;
                string[] val_st;
                int nval;
                int[] ids, val_ids;
                int i,j;
                bool is_str = true;

                clase_path=null;
                campo=consulta="";
                val_st=null;
                val_ids=ids=null;
                nval=-1;

                clase_path = list.selec_capa();
                if (clase_path != null)
                {
                    nval = list.selec_campo(out campo);
                    if (nval > -1 && campo != null)
                    {
                        //mira a ver si el campo es str
                        is_str = FunGDB.is_str_field(clase_path,campo);
                        nval = list.selec_valores_campo(campo,out val_ids, out val_st);//valores únicos
                        if (nval > 0)
                        {
                            //se embucla para unir las geoms
                            for (i = 0; i < nval; i++)
                            {
                                if(is_str)
                                    consulta = campo + " = '" + val_st[i] + "'";
                                else
                                    consulta = campo + " = " + val_st[i];
                                ids = FunGDB.dame_ids_consulta(clase_path, consulta);
                                fc = FunGDB.abre_ftclass(clase_path);
                                if ((ids != null) && (fc != null))
                                {
                                    for(j=0;j<ids.Length;j++)
                                    {
                                        f = fc.GetFeature(ids[j]);
                                        geom = f.Shape;
                                        geom_sal = FunGDB.une_geoms(geom_sal, geom);
                                        FunGDB.libera(f);
                                    }                                     
                                }
                                FunGDB.libera(fc);
                                //Actualiza el texto de salida
                                text_sal = text_sal + val_st[i].Replace(" ", string.Empty);
                                /*if(i<(nval-1))//si es el último no le pone '_'
                                    text_sal = text_sal + "_";*/
                            }
                        }   
                    }
                }
            }
            catch (Exception)
            {
                geom_sal = null;
            }

            FunGDB.libera(fc);
            FunGDB.libera(f);

            if (geom_sal==null)
            {
                MessageBox.Show("Error al seleccionar capa de polígonos. " + list.err_st, "Olivia", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
            return true;
        }
    }
}
