using System;
using DevExpress.XtraEditors;
using System.Windows.Forms;
using LLNet.Controls;
using Microsoft.Win32;
using System.Threading;
using System.Collections;
using System.Reflection;
using System.Management;


namespace LLNet.GUI
{
    /// <summary>
    /// Clase Inicial de la Aplicacion
    /// </summary>
    public class CApp
    {
        #region Declaraciones

        public static LLNet.BLL.BLLServer bll;
        public static string conexion;
        public static string cnnDescription;
        public static Form MainForm;
        public static string ExeDir;
        public static string SkinName;
        public static string SkinFormat;
        public static string ModulePrefix;
        public static string SolutionModule;
        public static bool CreateModules;
        public static string idioma;
        public static string HelpFileName;
        public static string vLectorBac; 

        public static DevExpress.XtraGrid.Design.XAppearances xsGrid;
        public static DevExpress.XtraVerticalGrid.Design.XAppearances xsVGrid;
        public static DevExpress.XtraTreeList.Design.XAppearances xsTree;

        public static LLEventLog EventLog;

        private static string pUsuario;
        private static string pPassword;
        public static string Supervisor;
        private static decimal dDocument;

        public static decimal Document
        {
            get { return CApp.dDocument; }
            set { CApp.dDocument = value; }
        }

        public static string Sup;


        public static string usuario
        {
            get 
            {
                string retValue = null;
                if (Utils.Helpers.ObjToStr(Supervisor) != string.Empty)
                {
                    retValue = Supervisor;
                    Supervisor = null;
                }
                else
                    retValue = pUsuario;
                   
                return retValue; 
            }
            set { pUsuario = value; }
        }

        public static string password
        {
            get
            {
                string retValue = null;
                if (Utils.Helpers.ObjToStr(Supervisor) != string.Empty)
                {
                    retValue = pPassword;
                    pPassword = null;
                }
                else
                    retValue = pPassword;

                return retValue;
            }
            set { pPassword = value; }
        }
        
        #endregion

        #region Constructor

        public CApp()
        {
        }

        #endregion

        #region Skin Methods

        public static void InitSkinsDesigners()
        {
            xsGrid = new DevExpress.XtraGrid.Design.XAppearances(CApp.ExeDir + "DevExpress.XtraGrid.Appearances.xml");
            xsVGrid = new DevExpress.XtraVerticalGrid.Design.XAppearances(CApp.ExeDir + "DevExpress.XtraVerticalGrid.Appearances.xml");
            xsTree = new DevExpress.XtraTreeList.Design.XAppearances(CApp.ExeDir + "DevExpress.XtraTreeList.Appearances.xml");
        }

        public static void SetSkins(string SkinName)
        {
            //-- Inicializamos valores
            CApp.SkinName = SkinName;
            CApp.SkinFormat = "(Default)";
            //-- Procedemos segun el caso
            switch (SkinName)
            {
                case "Default":
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetDefaultStyle();
                    break;

                case "WindowsXP":
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetWindowsXPStyle();
                    //CApp.SkinFormat = "XP2View";
                    break;

                case "Office2000":
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetFlatStyle();
                    //CApp.SkinFormat = "Office1View";
                    break;

                case "OfficeXP":
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetUltraFlatStyle();
                    //CApp.SkinFormat = "ExplorerBarView";
                    break;

                case "Office2003":
                    CApp.SkinFormat = "Blue Office";
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetOffice2003Style();
                    break;

                default:
                    DevExpress.LookAndFeel.UserLookAndFeel.Default.SetSkinStyle(CApp.SkinName);
                    break;
            }
        }

        #endregion

        #region CreateForm

        public static FormBases.frmBase CreateForm(Type pFormBaseType, string pText)
        {
            return CreateForm(pFormBaseType, pText, false);
        }

        public static FormBases.frmBase CreateForm(Type pFormBaseType, bool pOpenModal)
        {
            return CreateForm(pFormBaseType, null, false, null, pOpenModal);
        }

        public static FormBases.frmBase CreateForm(Type pFormBaseType, string pText, bool pOneInstance)
        {
            return CreateForm(pFormBaseType, pText, pOneInstance, null);
        }

        public static FormBases.frmBase CreateForm(Type pFormBaseType, string pText, object[] pArgs)
        {
            return CreateForm(pFormBaseType, pText, false, pArgs);
        }

        public static FormBases.frmBase CreateForm(Type pFormBaseType, string pText, bool pOneInstance, object[] pArgs)
        {
            return CreateForm(pFormBaseType, pText, pOneInstance, pArgs, false);
        }

        public static FormBases.frmBase CreateForm(Type pFormBaseType, string pText, bool pOneInstance, object[] pArgs, bool pOpenModal)
        {
            Cursor oldCursor = Cursor.Current;
            Cursor.Current = Cursors.WaitCursor;

            try
            {
                // Valida seguridad por ventana
                // string moduleName = pFormBaseType.Name.Substring(3, pFormBaseType.Name.Length - 3);
                // if (!CApp.ValidateAccess(moduleName, pText)) return null;

                if (pOneInstance)
                {
                    try
                    {
                        foreach (FormBases.frmBase frm in MainForm.MdiChildren)
                        {

                            if (frm.GetType() == pFormBaseType)
                            {
                                frm.Activate();
                                return frm;
                            }
                        }
                    }
                    catch
                    {

                    }
                }

                FormBases.frmBase openForm;
                try
                {
                    openForm = (FormBases.frmBase)Activator.CreateInstance(pFormBaseType);
                    if (pText != null) openForm.Text = pText;
                    openForm.Init(pArgs);
                    if (pOpenModal)
                    {
                        openForm.ShowDialog();
                    }
                    else
                    {
                        openForm.MdiParent = MainForm;
                        openForm.Show();
                    }
                    return openForm;
                }
                catch (Exception ex)
                {
                    XtraMessageBox.Show(ex.Message);
                    return null;
                }
            }
            finally
            {
                Cursor.Current = oldCursor;
            }

        }

        #endregion

        #region Métodos para validar acceso y obtener parametros

        /// <summary>
        /// Devuelve si tiene o no acceso a un módulo, si no tiene muestra un messagebox con el mensaje: 
        /// "No tiene privilegios para entrar a este módulo, consulte con su administrador"
        /// </summary>
        /// <param name="pModule">Nombre del módulo</param>
        /// <returns></returns>
        public static bool ValidateAccess(string pModule, string pDescription)
        {
            return ValidateAccess(pModule, pDescription, false);
        }

        public static bool ValidateAccess(string pModule, string pDescription, bool restrictedAccess)
        {
            // Código temporal, mientras se modifican los modulos
            // --------------------------------------------------
            long result = 0;

            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("MODULO", CApp.ModulePrefix + pModule);
            result = Utils.Helpers.ObjToInt64(CApp.bll.GetSingleValue("MODULEEXISTS", qParams, "General"));

            if (result == 0)
            {
                if (!CApp.CreateModules)
                    return true;
                else
                {
                    qParams.AddReplaceParam("PADRE", CApp.SolutionModule);
                    qParams.AddReplaceParam("DESCRIPCION", pDescription);
                    CApp.bll.ExecuteSql("InsertModule", qParams, "General");
                }

            }
            // --------------------------------------------------

            if (!GetAccess(CApp.ModulePrefix + pModule))
            {
                if (!restrictedAccess)
                {
                    GUI.Dialogs.MessageBoxes.frmPassword pwd = new LLNet.GUI.Dialogs.MessageBoxes.frmPassword();
                    pwd.Init(new object[] { CApp.ModulePrefix + pModule, pDescription });
                    pwd.ShowDialog();
                    if (pwd.textEdit1.Text != "" && pwd.textEdit1.Text != null)
                    {
                        qParams = new LLNet.Utils.QueryParams();
                        qParams.AddReplaceParam("PASSWORD", pwd.textEdit1.Text);
                        Sup = LLNet.Utils.Helpers.Nvl(GUI.CApp.bll.GetSingleValue("seguridad", qParams, "General"), "").ToString();
                    }

                    if (pwd.DialogResult == DialogResult.OK)
                        return true;
                    else
                        return false;
                }
                else
                {
                    GUI.CApp.ShowMessage("El usuario no tiene acceso a esta opción", pDescription, true);
                    return false;
                }
            }

            return true;

        }

        /// <summary>
        /// Devuelve si tiene o no acceso a un módulo
        /// </summary>
        /// <param name="pModule">Nombre del módulo</param>
        /// <returns></returns>
        public static bool GetAccess(string pModule)
        {
            return GetAccess(pModule, CApp.usuario);
        }

        /// <summary>
        /// Devuelve si tiene o no acceso a un módulo
        /// </summary>
        /// <param name="pModule">Nombre del módulo</param>
        /// <param name="pUserId">Usuario</param>
        /// <returns></returns>
        public static bool GetAccess(string pModule, string pUserId)
        {
            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("USUARIO", pUserId);
            qParams.AddReplaceParam("MODULO", pModule);
            long result = Utils.Helpers.ObjToInt64(CApp.bll.GetSingleValue("USERINMODULE", qParams, "General"));

            if (result == 0)
                return false;
            else
                return true;

        }

        public static bool GetAccessByPassword(string pModule, string pPassword)
        {
            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("PASSWORD", pPassword);
            qParams.AddReplaceParam("MODULO", pModule);
            long result = Utils.Helpers.ObjToInt64(CApp.bll.GetSingleValue("USERINMODULEBYPWD", qParams, "General", true));

            if (result == 0)
                return false;
            else
                return true;

        }

        public static Dialogs.MessageBoxes.dlgMessageBox messageBoxForm;
        public static void ShowMessage(string Message, string Title, bool traducir)
        {
            if (messageBoxForm == null)
                messageBoxForm = new LLNet.GUI.Dialogs.MessageBoxes.dlgMessageBox();

            messageBoxForm.Title.Text = Title;
            messageBoxForm.Message.Text = Message;
            messageBoxForm.btnAceptar.Text = "[F12]                                                                  &Aceptar";

            if (traducir)
            {
                messageBoxForm.Title.Text = TraducirPalabra(Title);
                messageBoxForm.Message.Text = TraducirPalabra(Message);
                messageBoxForm.btnAceptar.Text = TraducirPalabra(messageBoxForm.btnAceptar.Text);
            }

            messageBoxForm.DialogResult = DialogResult.None;

            Form frmParent = messageBoxForm.FindForm();

            try
            {
                messageBoxForm.Parent = messageBoxForm.FindForm();
            }
            catch
            {
            }

            messageBoxForm.btnCancelar.Visible = false;
            
            try
            {
                messageBoxForm.ShowDialog(frmParent);
            }
            catch
            {
                messageBoxForm.ShowDialog();
            }

        }

        public static DialogResult ShowMessage(string Message, string Title,bool traducir, bool yesNo)
        {
            string yes = "[F12]                                                                  &Si";
            string no = "[Esc]                                                                  &No";
            string aceptar = "[F12]                                                                  &Aceptar";
            string cancelar = "[Esc]                                                                  &Cancelar";
            if (messageBoxForm == null)
                messageBoxForm = new LLNet.GUI.Dialogs.MessageBoxes.dlgMessageBox();

            messageBoxForm.Title.Text = Title;
            messageBoxForm.Message.Text = Message;

            if(traducir){
                messageBoxForm.Title.Text = TraducirPalabra(Title);
                messageBoxForm.Message.Text = TraducirPalabra(Message);
                yes = TraducirPalabra(yes);
                no = TraducirPalabra(no);
                aceptar = TraducirPalabra(aceptar);
                cancelar = TraducirPalabra(cancelar);
            }            

            if (yesNo)
            {
                messageBoxForm.btnAceptar.Text  = yes;
                messageBoxForm.btnCancelar.Text = no;
            }
            else
            {
                messageBoxForm.btnAceptar.Text  = aceptar;
                messageBoxForm.btnCancelar.Text = cancelar;
            }

            messageBoxForm.DialogResult = DialogResult.None;

            Form frmParent = messageBoxForm.FindForm();

            try
            {
                messageBoxForm.Parent = frmParent;
            }
            catch 
            {
            }

            messageBoxForm.btnCancelar.Visible = true;

            try
            {
                messageBoxForm.ShowDialog(frmParent);
            }
            catch
            {
                messageBoxForm.ShowDialog();
            }

            return messageBoxForm.DialogResult;
        }

        public static object GetParam(string paramName)
        {
            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("Param", paramName);
            return CApp.bll.GetSingleValue("GetParam", qParams, "General");
        }

        public static void SetParam(string paramName, string pValue)
        {
            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("Param", paramName);
            qParams.AddReplaceParam("Value", pValue);
            CApp.bll.ExecuteSql("SetParam", qParams, "General");
        }

        public static object GetSequence(string pSequence)
        {
            return GetSecuence(pSequence);
        }

        public static object GetSecuence(string pSequence)
        {
            Utils.QueryParams qParams = new LLNet.Utils.QueryParams();
            qParams.AddReplaceParam("SECUENCIA", pSequence);
            return CApp.bll.GetSingleValue("SECUENCIA", qParams, "General");
        }

        public static string GetCurrencySymbol(string moneda)
        {
            Utils.QueryParams qpMoneda = new LLNet.Utils.QueryParams();
            qpMoneda.AddReplaceParam("MONEDA", moneda);
            string simbolo = CApp.bll.GetSingleValue("SimboloMoneda", qpMoneda, "General").ToString();
            return simbolo;
        }

        public static string GetMeaning(string domain, string valor)
        {
            Utils.QueryParams qp = new LLNet.Utils.QueryParams();
            qp.AddReplaceParam("DOMAIN", domain);
            qp.AddReplaceParam("VALUE", valor);
            string meaning = CApp.bll.GetSingleValue("Significado", qp, "General").ToString();
            return meaning;
        }

        #endregion

        #region Manejo de Excepciones

        /// <summary>
        /// Evento que ocurre cuando da error bll
        /// </summary>
        /// <param name="errors"></param>
        public static void bll_OnBllError(LLNet.Model.Errors errors)
        {
            string strError = null;

            foreach (LLNet.Model.Errors.BLLErrorsRow row in errors.BLLErrors.Rows)
            {
                if (row.ErrorType == Utils.Types.ErrorTypes.ERROR)
                    strError += row.Message + "\n";
                else if (row.ErrorType == Utils.Types.ErrorTypes.MESSAGES)
                    XtraMessageBox.Show(MainForm, row.Message, "Información", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }

            if (strError != null)
            {
                errors.BLLErrors.Clear();
                throw new Exception(strError);
            }
        }

        #endregion

        public static void RunProcedure(string pProcedureName, string pModule, string pTitle)
        {
            RunProcedure(pProcedureName, pModule, pTitle, null);
        }

        /// <summary>
        /// Corre un procedimiento sin parametros y muestra una ventana de espera
        /// </summary>
        /// <param name="pProcedureName">QueryName con el que se identifica el procedimiento</param>
        /// <param name="pModule">Módulo en que se encuentra el QueryName</param>
        /// <param name="pTitle">Título de la aplicación</param>
        public static void RunProcedure(string pProcedureName, string pModule, string pTitle, Utils.QueryParams pQueryParams)
        {
            Cursor current = Cursor.Current;

            if (ValidateAccess(pProcedureName, pTitle))
            {
                object[] objParams = new object[] { pProcedureName, pModule, pQueryParams };
//                FormBases.dlgProcessing dlg = (FormBases.dlgProcessing)CApp.CreateForm(typeof(Bases.dlgProcessing), pTitle, true, objParams, true);
            }

        }
        public static string GetLineasDocumento()
        {
            //string result = "";
            RegistryKey key = Registry.CurrentUser;
            key = key.OpenSubKey(@"Software\Logistika\POS Retail 8.0.0", true);
            string LíneasDoc = key.GetValue("LineasDocumento", "").ToString();
            return LíneasDoc;

        }
 

        public static bool ValidateLicence()
        {
            bool result = true;

            //bool result = false;
            //RegistryKey key = Registry.CurrentUser;
            //key = key.OpenSubKey(@"Software\Logistika\POS Retail 8.0.0", true);
            //string licence = key.GetValue("Licence", "").ToString();
            //string procId = null;
           
            //try
            //{
            //    ManagementObjectSearcher searcher = new ManagementObjectSearcher
            //            ("select * from Win32_ComputerSystemProduct");

            //    foreach (ManagementObject share in searcher.Get())
            //    {
            //        procId = share.Properties["UUID"].Value.ToString().Trim();
            //    }
            //    searcher.Dispose();
            //}
            //catch (Exception ex)
            //{
            //    EventLog.WriteLog(Utils.Types.ErrorTypes.ERROR, ex.Message);
            //    GUI.CApp.ShowMessage(ex.Message, "Verificación de Licencia", true);
            //    result = false;
            //}

            //if (procId.Trim() == "00000000-0000-0000-0000-000000000000"  || procId == String.Empty ||
            //    procId.Trim() == "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF")
            //{
            //    RegistryKey keyGuid = Registry.LocalMachine;
            //    keyGuid = keyGuid.OpenSubKey(@"Software\Microsoft\Windows NT\CurrentVersion", true);
            //    procId = Utils.Helpers.ObjToStr(keyGuid.GetValue("CurrentUUID", "")).Trim();
            //    if (procId == string.Empty)
            //    {
            //        Guid uuid = Guid.NewGuid();
            //        procId = uuid.ToString().Trim();
            //        keyGuid.SetValue("CurrentUUID", procId);
            //    }
            //}

            //if (licence != string.Empty)
            //{
            //    try
            //    {
            //        result = LLNet.GenAdv.GenAdv.CompareLicence(licence, procId, "TDA800");
            //    }
            //    catch (Exception ex)
            //    {
            //        MessageBox.Show(ex.Message, "Validación de Licencia");
            //    }

            //    if (!result)
            //    {
            //        GUI.frmLicence lic = new frmLicence();
            //        lic.Init(new object[] { procId });
            //        lic.ShowDialog();                
            //    }
            //}
            //else
            //{
            //    GUI.frmLicence lic = new frmLicence();
            //    lic.Init(new object[] { procId });
            //    lic.ShowDialog();                
            //}

            return result;
        }


        #region Idioma

        public static void TraducirForm(System.Windows.Forms.Form form)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form);
        }

        public static void TraducirForm(System.Windows.Forms.UserControl form)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form);
        }

        public static void TraducirForm(LLNet.Controls.LLToolbar form)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form);
        }

        public static void TraducirForm(System.Windows.Forms.UserControl form, LLNet.Controls.LLToolbar toolbar)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form, toolbar);
        }

        public static void TraducirForm(System.Windows.Forms.Form form, LLNet.Controls.LLToolbar toolbar)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form, toolbar);
        }

        public static void TraducirForm(System.Windows.Forms.Form form, DevExpress.XtraBars.BarManager manager)
        {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            idioma.Traducir(form, manager);
        }

        public static string TraducirPalabra(string palabra) {
            GUI.Idioma idioma = new Idioma(GUI.CApp.idioma);
            return idioma.traduccion(palabra);
        }

        #endregion
    }

    #region Clase para Manejo de Excepciones

    // Creates a class to handle the exception event.
    public class CustomExceptionHandler
    {

        // Handles the exception event.
        public void OnThreadException(object sender, ThreadExceptionEventArgs t)
        {
            DialogResult result = DialogResult.Cancel;
            try
            {
                result = this.ShowThreadExceptionDialog(t.Exception);
            }
            catch
            {
                try
                {
                    CApp.EventLog.WriteLog(t.Exception);
                    XtraMessageBox.Show("Ocurrió un Error en la Aplicación: \r\n" + t.Exception.Message + "\r\nRepórtelo a su Departamento de Soporte", "Advertencia", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                finally
                {
                    Application.Exit();
                }
            }

            // Exits the program when the user clicks Abort.
            if (result == DialogResult.Abort)
                Application.Exit();
        }

        // Creates the error message and displays it.
        private DialogResult ShowThreadExceptionDialog(Exception e)
        {
            CApp.EventLog.WriteLog(e);
            if (e.Message.IndexOf("ORA-20000") >= 0)
            {
                GUI.CApp.ShowMessage(e.Message.Substring(11, e.Message.IndexOf("ORA-", 11) - 12), "Advertencia", true);
                return DialogResult.OK;
            }
            else
                return XtraMessageBox.Show("Ocurrió un Error en la Aplicación: \r\n" + e.Message + "\r\nRepórtelo a su Departamento de Soporte", "Advertencia", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
    
    #endregion

}