using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Customization;

using COMUN = GMLC01HerramientasCad.Logica;

// This line is not mandatory, but improves loading performances
[assembly: CommandClass(typeof(GMLC01HerramientasCad.Acad.Cui))]

namespace GMLC01HerramientasCad.Acad
{
    public static class Cui
    {
        /// <summary>
        /// Punto de entrada para el comando INVENTARIO INVENTARIO (Carga de los menus de inventario).
        /// </summary>
        [CommandMethod("GMLC01HerramientasCAD", "ICUI", CommandFlags.Modal)]
        public static void CuiRebuild()
        {
            try
            {
                Cui.RebuildCui();
                //Tras cargar la barra de botones, se muestra la paleta de herramientas.
                GMLCPaleteSet.LoadPaleteSet();
            }
            catch (System.Exception ex)
            {
                Log.RegisterError(ex);
                throw new System.FormatException("", ex);
            }
        }

        private static void RebuildCui()
        {
            try
            {
                // Si no se cargó el XSD, no se hará nada.
                if (GMLC01HerramientasCad.Logica.ModComun.XSD == null)
                {
                    System.Windows.Forms.MessageBox.Show(COMUN.Properties.Resources.ElFicheroXSDNoHaSidoCargado, "ERROR", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error, System.Windows.Forms.MessageBoxDefaultButton.Button1, 0);
                    return;
                }

                CustomizationSection cs;
                string cuiExtension = ".cuix";
                string mainCuiName = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("MENUNAME") + cuiExtension;
                if (System.IO.File.Exists(mainCuiName))
                {
                    cs = new CustomizationSection(mainCuiName);
                }
                else
                {
                    cuiExtension = ".cui";
                    mainCuiName = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("MENUNAME") + cuiExtension;
                    cs = new CustomizationSection(mainCuiName);
                }

                PartialCuiFileCollection pcfc = cs.PartialCuiFiles;

                string cuiName = "GMLC_" + COMUN.ModComun.Idioma;
                string cuiFile = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\cui\\" + cuiName + cuiExtension;
                cuiFile = cuiFile.Remove(0, 6);

                // check existence of cui to load
                if (pcfc.Contains(cuiFile) && System.IO.File.Exists(cuiFile))
                {
                    //La barra del idioma ya está cargada, no se requiere hacer nada.
                }
                else
                {
                    // Crea el archivo cui si no existe.
                    if (!System.IO.File.Exists(cuiFile)) CreateCui(ref cuiFile, cuiName);

                    //// Se intenta eliminar todas las barras de otros idiomas.
                    //foreach (COMUN.Idioma idioma in COMUN.ModComun.XSD.Idiomas)
                    //{
                    //    if (idioma.Codigo != COMUN.ModComun.Idioma)
                    //    {
                    //        string oldCuiName = "GMLC_" + idioma.Codigo;
                    //        string oldCuiFile = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\cui\\" + oldCuiName + cuiExtension;
                    //        oldCuiFile = oldCuiFile.Remove(0, 6);
                    //        // remove old cui
                    //        if (pcfc.Contains(oldCuiFile)) UnLoadCui(oldCuiName);
                    //    }
                    //}
                    
                    // Se intenta eliminar todas las barras de GMLC.
                    for (int i = 0; i < pcfc.Count; i++)
                    {
                        string oldCuiFile = pcfc[i];
                        string oldCuiName = System.IO.Path.GetFileNameWithoutExtension(oldCuiFile);
                        if (oldCuiName.StartsWith("gmlc_", StringComparison.OrdinalIgnoreCase))
                        {
                            // remove old cui
                            UnLoadCui(oldCuiName);
                        }
                    }

                    LoadCui(cuiFile);
                }
            }
            finally { }
        }

        private static void CreateCui(ref string cuiFile, string cuiName)
        {

            if (System.IO.File.Exists(cuiFile)) System.IO.File.Delete(cuiFile);

            // rebuild the new cui   
            // Create a customization section for our partial menu
            CustomizationSection pcs = new CustomizationSection();
            pcs.MenuGroupName = cuiName;

            // add a menu group
            MacroGroup mg = new MacroGroup(pcs.MenuGroupName, pcs.MenuGroup);

            // search through the current assembly for CommandMethods
            Assembly asm = Assembly.GetExecutingAssembly();

            object[] objs = asm.GetCustomAttributes(typeof(CommandClassAttribute), true);
            Type[] tps;
            int numTypes = objs.Length;

            if (numTypes > 0)
            {
                tps = new Type[numTypes];
                for (int i = 0; i < numTypes; i++)
                {
                    CommandClassAttribute cca = objs[i] as CommandClassAttribute;
                    if (cca != null)
                    {
                        tps[i] = cca.Type;
                    }
                }
            }
            else
            {
                tps = asm.GetExportedTypes();
            }

            ArrayList toolBars = new ArrayList();
            ArrayList menus = new ArrayList();
            StringCollection sc = new StringCollection();
            string mnuGMLC = COMUN.Properties.Resources.Inventario;
            sc.Add("t_" + mnuGMLC);
            foreach (Type tp in tps)
            {
                if (tp.Name.ToUpper(System.Globalization.CultureInfo.CurrentCulture) != "CUI") // exclude the cui class
                {
                    bool toolbarCreated = false;
                    MethodInfo[] meths = tp.GetMethods();

                    foreach (MethodInfo meth in meths)
                    {
                        objs = meth.GetCustomAttributes(typeof(CommandMethodAttribute), true);
                        foreach (object obj in objs)
                        {
                            CommandMethodAttribute attb = (CommandMethodAttribute)obj;
                            string globalName = attb.GlobalName;
                            string iconsFolder = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\icons\\";
                            string iconFullName = iconsFolder + globalName + ".bmp";
                            //SOLO SE AGREGAN BOTONES CON ICONO.
                            if (System.IO.File.Exists(iconFullName.Replace("file:\\",""))) //globalName.StartsWith("I"))
                            {
                                // create the toolbar for this commands if does not exist yet
                                if (toolbarCreated == false)
                                {
                                    toolBars.Add(new Toolbar(mnuGMLC, pcs.MenuGroup));
                                    menus.Add(new PopMenu(mnuGMLC, sc, "p_" + mnuGMLC, pcs.MenuGroup));
                                    toolbarCreated = true;
                                }

                                // create the macro for the commandMethod
                                MenuMacro mm1 = new MenuMacro(mg, meth.Name, globalName, meth.Name);
                                // set macro icon - the name of the icon file must be the same as the method name
                                iconFullName = iconFullName.Remove(0, 6);
                                mm1.macro.SmallImage = iconFullName;
                                // create button in the toolbar for the macro 
                                ToolbarButton tbBtn1 = new ToolbarButton(mm1.ElementID, GetName4Item(globalName), (Toolbar)toolBars[toolBars.Count - 1], -1);
                                tbBtn1.ToString();
                                PopMenuItem pi = new PopMenuItem(mm1, GetName4Item(globalName), (PopMenu)menus[menus.Count - 1], ((PopMenu)menus[menus.Count - 1]).PopMenuItems.Count);
                                pi.ToString();
                            }
                        }
                    }
                }
            }
            pcs.SaveAs(cuiFile);
            cuiFile = pcs.CUIFileName;
        }

        private static void LoadCui(string cuiFile)
        {
            Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            object oldMutt = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("NOMUTT");
            object oldFileDia = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("FILEDIA");
            try // Se produce un error "eNoDocument" si se esta tratando de cargar la barra cuando de abre autocad.
            {
                doc.SendStringToExecute(
                  "(setvar \"NOMUTT\" "
                  + "1"
                  + ")(princ) ",
                  false, false, false);

                doc.SendStringToExecute(
                  "(setvar \"FILEDIA\" "
                  + "0"
                  + ")(princ) ",
                  false, false, false
                );

                doc.SendStringToExecute("_.cuiload \"" + cuiFile + "\" ", false, false, false);

                doc.SendStringToExecute(
                  "(setvar \"FILEDIA\" "
                  + oldFileDia.ToString()
                  + ")(princ) ",
                  false, false, false
                );

                doc.SendStringToExecute(
                  "(setvar \"NOMUTT\" "
                  + oldMutt.ToString()
                  + ")(princ) ",
                  false, false, false);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception)
            {

            }
            finally
            {
            }
        }

        private static void UnLoadCui(string cuiName)
        {
            try // Se produce un error "eNoDocument" si se esta tratando de cargar la barra cuando de abre autocad.
            {
                Autodesk.AutoCAD.ApplicationServices.Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
                object oldMutt = Autodesk.AutoCAD.ApplicationServices.Application.GetSystemVariable("NOMUTT");
                doc.SendStringToExecute("(setvar \"NOMUTT\" " + oldMutt.ToString() + ")(princ) ", false, false, false);
                doc.SendStringToExecute("(command \"_.menuunload\" \"" + cuiName + "\") ", false, false, false);
                doc.SendStringToExecute("(setvar \"NOMUTT\" " + oldMutt.ToString() + ")(princ) ", false, false, false);
            }
            catch (Autodesk.AutoCAD.Runtime.Exception)
            {

            }
            finally
            {
            }
        }

        private static string GetName4Item(string commandName)
        {
            string mainCult = System.Threading.Thread.CurrentThread.CurrentCulture.Name;
            if (!String.IsNullOrEmpty(MyPlugin.cultureName))
            {
                System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(MyPlugin.cultureName);
            }

            string retVal;
            switch (commandName)
            {
                case "IDIBUJAR":
                    retVal = COMUN.Properties.Resources.Dibujar;
                    break;
                case "ICONSULTAR":
                    retVal = COMUN.Properties.Resources.ConsultarEditar;
                    break;
                case "ITEMATICO":
                    retVal = COMUN.Properties.Resources.GenerarTematico;
                    break;
                case "IBUSCAR":
                    retVal = COMUN.Properties.Resources.BuscarSeleccionar;
                    break;
                case "IETIQUETAR":
                    retVal = COMUN.Properties.Resources.Etiquetado;
                    break;
                case "IIMPORTARGML":
                    retVal = COMUN.Properties.Resources.ImportarDeGML;
                    break;
                case "IEXPORTARGML":
                    retVal = COMUN.Properties.Resources.ExportarAGML;
                    break;
                case "IIDIOMA":
                    retVal = COMUN.Properties.Resources.Idioma;
                    break;
                case "IACERCADE":
                    retVal = COMUN.Properties.Resources.Acerca_De;
                    break;
                default:
                    retVal = commandName;
                    break;
            }
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(mainCult);

            return retVal;
        }
    }
}
