using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Exferia_Aplicacion.Visualizacion;
using System.Reflection;
using Exferia_Aplicacion.General;
using System.Threading;
using Exferia_Formularios;
using Exferia_General;
using static Exferia_Aplicacion.General.Enumerados;

namespace Exferia_Controles
{
    public partial class Exferia_TextBox_Busqueda : UserControl
    {
        //Se utiliza para entrar en el codigo desde otra libreria
        public void Prueba()
        {}

        #region Propiedades Privadas
        private BackgroundWorker g_TareaAsincrona_Buscar;
        private ABS_TextBox_Busqueda g_obj_ABS_TextBox_Busqueda = null;
        private INTERNO_OpcionesDetalle_Modelo g_mdl_INTERNO_OpcionesDetalle_Modelo = null;
        internal List<INTERNO_Permisos_Modelo> g_lst_INTERNO_Permisos_Modelo = null;

        #endregion

        #region Propiedades Publicas
        internal P_Base g_P_Base_Contenedor = null;
        public P_Base Exferia_TextBox_Busqueda_PantallaContenedora
        {
            set
            {
                g_P_Base_Contenedor = value;
            }
        }

        internal string g_str_NombreOpcion_BuscarDatos = "";
        public string Exferia_TextBox_Busqueda_PRINCIPAL_Opcion_BuscarDatos
        {
            set
            {
                g_str_NombreOpcion_BuscarDatos = value;

                //Buscar los Permisos
                if (value != null && value.Trim().Length >0)
                { 
                    g_lst_INTERNO_Permisos_Modelo = Datos_Generales.Permisos_Buscar(value);
                }
            }
            get
            {
                return g_str_NombreOpcion_BuscarDatos;
            }
        }

        internal bool g_bol_Obligatorio = false;
        public bool Exferia_TextBox_Busqueda_PRINCIPAL_Obligatorio
        {
            set
            {
                g_bol_Obligatorio = value;
                if (g_bol_Obligatorio)
                {
                    ex_txt_Codigo.Exferia_TextBox_Fondo = Colores.G_COLOR_FONDO_OBLIGATORIO;
                }
                else
                {
                    ex_txt_Codigo.Exferia_TextBox_Fondo = Color.White;
                }
            }
            get
            {
                return g_bol_Obligatorio;
            }
        }

        internal G_ENUM_TEXTBOX_BUSQUEDA g_enum_AnchoTitulo = G_ENUM_TEXTBOX_BUSQUEDA.Normal;
        public G_ENUM_TEXTBOX_BUSQUEDA Exferia_TextBox_Busqueda_Ancho_Titulo
        {
            set
            {
                g_enum_AnchoTitulo = value;

                //Normal
                int int_AnchoTitulo = 94;

                //Medio
                if (g_enum_AnchoTitulo.Equals(G_ENUM_TEXTBOX_BUSQUEDA.Medio))
                {
                    int_AnchoTitulo = 175;
                }
                //Grande
                else if (g_enum_AnchoTitulo.Equals(G_ENUM_TEXTBOX_BUSQUEDA.Grande))
                {
                    int_AnchoTitulo = 250;
                }
                //SuperGrande
                else if (g_enum_AnchoTitulo.Equals(G_ENUM_TEXTBOX_BUSQUEDA.SuperGrande))
                {
                    int_AnchoTitulo = 350;
                }
                //Pequeno
                else if (g_enum_AnchoTitulo.Equals(G_ENUM_TEXTBOX_BUSQUEDA.Pequeno))
                {
                    int_AnchoTitulo = 60;
                }
                //SuperPequeno
                else if (g_enum_AnchoTitulo.Equals(G_ENUM_TEXTBOX_BUSQUEDA.SuperPequeno))
                {
                    int_AnchoTitulo = 40;
                }

                ex_lbl_Titulo.Size = new Size(int_AnchoTitulo, ex_lbl_Titulo.Size.Height);

                ex_txt_Codigo.Location = new Point(int_AnchoTitulo+2, ex_txt_Codigo.Location.Y);
                ex_txt_Codigo.Size = new Size((this.Width - (int_AnchoTitulo + 2))-1, ex_txt_Codigo.Size.Height);

            }
            get
            {
                return g_enum_AnchoTitulo;
            }
        }

        public Exferia_TextBox Exferia_TextBox_Busqueda_PRINCIPAL_TextBox_Codigo
        {
            get
            {
                return ex_txt_Codigo;
            }
        }

        public string Exferia_TextBox_Busqueda_Titulo
        {
            set
            {
                ex_lbl_Titulo.Text = value;
            }
            get
            {
                return ex_lbl_Titulo.Text;
            }
        }

        public string Exferia_TextBox_Busqueda_Codigo
        {
            set
            {
                ex_txt_Codigo.Text = value;
            }
            get
            {
                return ex_txt_Codigo.Text;
            }
        }

        public void Exferia_TextBox_Busqueda_Foco ()
        {
            ex_txt_Codigo.Exferia_TextBox_Foco();
        }

        bool g_bol_Bloqueable = true;
        public bool Exferia_TextBox_Busqueda_Bloqueable
        {
            set
            {
                g_bol_Bloqueable = value;
            }
            get
            {
                return g_bol_Bloqueable;
            }
        }

        #endregion

        #region Eventos publicos
        public event EventHandler<INTERNO_EventArgs_Dynamic> Exferia_TextBox_Busqueda_Evento_TerminoBusqueda;
        public event EventHandler Exferia_TextBox_Busqueda_Evento_TextChanged;
        #endregion

        public Exferia_TextBox_Busqueda()
        {
            InitializeComponent();

            // (Tarea Asincrona) Buscar ###############################################################
            g_TareaAsincrona_Buscar = new BackgroundWorker();
            g_TareaAsincrona_Buscar.DoWork += new DoWorkEventHandler(TareaAsincrona_Buscar_DoWork);
            g_TareaAsincrona_Buscar.RunWorkerCompleted += new RunWorkerCompletedEventHandler(TareaAsincrona_Buscar_Completed);
            g_TareaAsincrona_Buscar.WorkerReportsProgress = false;
            g_TareaAsincrona_Buscar.WorkerSupportsCancellation = true;
            // ##############################################################################################
        }

        private void Exferia_TextBox_Busqueda_Load(object sender, EventArgs e)
        {
            try
            {
                //Buscar los datos del Arbol
                g_mdl_INTERNO_OpcionesDetalle_Modelo = Datos_Generales.PRV_Opciones_Buscar_Detalles(g_str_NombreOpcion_BuscarDatos);

                //Cargamos el ensamblado
                Assembly m_assembly = Assembly.LoadFrom(Variables.G_STR_LIBRERIA_RUTAINICIAL + @"\" + g_mdl_INTERNO_OpcionesDetalle_Modelo.nombreLibreria + ".dll");
                //Obtenemos el tipo de la clase
                Type m_type = m_assembly.GetType(g_mdl_INTERNO_OpcionesDetalle_Modelo.nombreLibreria + "." + Variables.G_STR_LIBRERIA_OPCIONES);
                //creamos la instancia
                var obj_Clase = Activator.CreateInstance(m_type);
                //Cargamos el metodo solicitado
                MethodInfo obj_MethodInfo = obj_Clase.GetType().GetMethod(Variables.G_STR_LIBRERIA_OPCIONES_PROCEDIMIENTO_OBTENCION_ABS_TEXTBOXBUSQUEDA, BindingFlags.Instance | BindingFlags.NonPublic);

                //Obtener valores
                object[] arr_Parametros = { g_str_NombreOpcion_BuscarDatos };
                //Pasamos los parametros al metodo y lo ejecutamos
                g_obj_ABS_TextBox_Busqueda = (ABS_TextBox_Busqueda)obj_MethodInfo.Invoke(obj_Clase, arr_Parametros);
            }
            catch (Exception ex)
            {
                Control_Errores.Errores_Log(g_str_NombreOpcion_BuscarDatos, ex, nameof(Exferia_TextBox_Busqueda) + "/" + nameof(Exferia_TextBox_Busqueda_Load));
            }
        }

        #region Poner el Foco en TextBox
        /// <summary>
        /// Poner el Fodo en el TextBox de Codigo
        /// </summary>
        public void Foco_Codigo()
        {
            ex_txt_Codigo.Exferia_TextBox_Foco();
        }
        #endregion
      
        private void ex_txt_Exferia_TextBox_Evento_KeyPress(object sender, KeyPressEventArgs e)
        {
            g_P_Base_Contenedor.P_Base_SeModificoDatosPantalla = true;
        }

        #region Tarea asíncrona para buscar en la base de datos

        private bool g_bol_Cancelada = false;
        
        // Buscar el registro en base de datos 
        private void Buscar(string _str_filtro)
        {
            try
            {
                g_bol_Cancelada = true;

                while (g_TareaAsincrona_Buscar.IsBusy)
                    Application.DoEvents();

                List<object> lst_Argumentos = new List<object>();
                lst_Argumentos.Add(_str_filtro);

                g_TareaAsincrona_Buscar.RunWorkerAsync(lst_Argumentos);
            }
            catch (Exception ex)
            {
                Control_Errores.Errores_Log(ex.Message, nameof(Exferia_TextBox_Busqueda) + "/" + nameof(Buscar));
                Mensajes.MostrarMensaje(Mensajes.G_EXFERIA_TEXTBOX_BUSQUEDA_ERROR_BUSCAR());
            }
        }
        private void TareaAsincrona_Buscar_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                g_bol_Cancelada = false;

                // Parametros ######################################################
                List<object> lst_Argumentos = e.Argument as List<object>;
                string str_filtro = lst_Argumentos[0].ToString();
                // #################################################################

                //Cargamos el ensamblado
                Assembly m_assembly = Assembly.LoadFrom(Variables.G_STR_LIBRERIA_RUTAINICIAL + @"\" + g_mdl_INTERNO_OpcionesDetalle_Modelo.nombreLibreria + ".dll");
                //Obtenemos el tipo de la clase
                Type m_type = m_assembly.GetType("" + g_mdl_INTERNO_OpcionesDetalle_Modelo.nombreLibreria + "." + Variables.G_STR_LIBRERIA_OPCIONES);
                //creamos la instancia
                var obj_Clase = Activator.CreateInstance(m_type);
                //Cargamos el metodo solicitado
                MethodInfo obj_MethodInfo = obj_Clase.GetType().GetMethod(Variables.G_STR_LIBRERIA_OPCIONES_PROCEDIMIENTO_OBTENER_REGISTRO_TEXTBOXBUSQUEDA, BindingFlags.Instance | BindingFlags.NonPublic);

                //Obtener valores
                object[] arr_Parametros = { g_str_NombreOpcion_BuscarDatos,
                                            str_filtro,
                                            g_obj_ABS_TextBox_Busqueda.NOMBRE_CAMPO(),
                                            (g_P_Base_Contenedor.P_Base_ValoresGenerales!=null ? g_P_Base_Contenedor.P_Base_ValoresGenerales.lng_idEmpresa : -1),
                                            ((g_P_Base_Contenedor.P_Base_ValoresGenerales!=null && g_P_Base_Contenedor.P_Base_ValoresGenerales.EjercicioActivo!=null) ? g_P_Base_Contenedor.P_Base_ValoresGenerales.EjercicioActivo.id : -1)};
                //Pasamos los parametros al metodo y lo ejecutamos
                dynamic dnm_Modelo = obj_MethodInfo.Invoke(obj_Clase, arr_Parametros);

                // Valores a Devolver
                e.Result = dnm_Modelo;
            }
            catch (ThreadAbortException)
            {
                e.Cancel = true;
                Thread.ResetAbort();
            }
            catch (Control_Errores)
            {
                e.Cancel = true;
            }
            catch (Exception)
            {
                e.Cancel = true;
            }
        }
        private void TareaAsincrona_Buscar_Completed(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                if (e.Cancelled == false)
                {
                    if (g_bol_Cancelada == false)
                    {
                        dynamic dnm_ValoresADevolver = e.Result as dynamic;
                        INTERNO_EventArgs_Dynamic obj_INTERNO_EventArgs_Dynamic = new INTERNO_EventArgs_Dynamic(dnm_ValoresADevolver);
                        Exferia_TextBox_Busqueda_Evento_TerminoBusqueda?.Invoke(this, obj_INTERNO_EventArgs_Dynamic);
                    }
                }
            }
            catch (Exception)
            { }
        }

        #endregion

        #region Foco
        private string g_str_CodigoInicial = "";
        private void ex_txt_Codigo_GotFocus(object sender, EventArgs e)
        {
            g_str_CodigoInicial = ex_txt_Codigo.Text;
        }
        private void ex_txt_Codigo_LostFocus(object sender, EventArgs e)
        {
            if (!ex_txt_Codigo.Text.Equals(g_str_CodigoInicial))
            {
                Buscar(ex_txt_Codigo.Text);
            }
        }
        #endregion

        private void ex_txt_Codigo_Exferia_TextBox_Evento_TextChanged(object sender, EventArgs e)
        {
            //Salta el Evento de TextChange
            Exferia_TextBox_Busqueda_Evento_TextChanged?.Invoke(this, e);
        }
    }
}
