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

using GMLC01HerramientasCad.Logica;
using COMUN = GMLC01HerramientasCad.Logica;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;

namespace GMLC01HerramientasCad.Acad
{
    public class EtiquetarElementos : IEtiquetado
    {
        //private BCOM.Application app = BMI.Utilities.ComApp;
        #region IEtiquetado Members

        public void Etiquetar(CriterioEtiquetado criterio)
        {
            try
            {
                Etiqueta(criterio);
            }
            catch (System.Exception ex)
            {
                Log.RegisterError(ex);
                throw new COMUN.ExcepcionGMLC("", ex);
            }
        }

        private static void Etiqueta(CriterioEtiquetado criterio)
        {
            if (criterio.Entidades.Count == 0)
            {
                MessageBox.Show(COMUN.Properties.Resources.NoSeSeleccionaronEntidadesAEtiquetar, COMUN.Properties.Resources.Inventario, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0);
                return;
            }

            if (criterio.Altura == 0) criterio.Altura = 1;

            Texts.VerifyFont(criterio);

            foreach (Entidad ent in criterio.Entidades)
            {
                // Recuperación de las entidades a etiquetar.
                ObjectId[] oIds = SeleccionObjetosAutoCAD.GetEntitiesWithXData(ent.Codigo);

                if (oIds != null)
                {
                    try
                    {
                        // Si se produce un error al recuperar el nombre de dominio significa que
                        string attDomain = GetDomainName(ent.Codigo, criterio.Atributo);

                        if (attDomain != null)
                        {
                            // Comprobación de si tienen el atributo a etiquetar.
                            //Entidad ent = XData.GetXData(oIds[0], ent.Codigo);

                            foreach (Atributo att in ent.Atributos)
                            {
                                if (att.Codigo == criterio.Atributo)
                                {
                                    // Se activa la capa donde se generarán los textos.
                                    LayerManagement.PrepareLayer(ent.Codigo + criterio.Sufijo);


                                    // Estas entidades contienen el atributo a etiquetar.
                                    foreach (ObjectId oid in oIds)
                                    {
                                        // RECUPERAR EL TEXTO A INSERTAR
                                        string texto = "";
                                        Entidad ent2 = XData.GetXData(oid, ent.Codigo);
                                        foreach (Atributo att2 in ent2.Atributos)
                                        {
                                            if (att2.Codigo == criterio.Atributo)
                                            {
                                                if (String.IsNullOrEmpty(attDomain))
                                                    texto = att2.Valor;
                                                else
                                                    texto = GetDomainValue(attDomain, att2.Valor);
                                                break;
                                            }
                                        }
                                        if (!String.IsNullOrEmpty(texto))
                                        {
                                            // RECUPERAR LAS COORDENADAS
                                            Autodesk.AutoCAD.Geometry.Point3d ptoInserc;
                                            switch (ent.TipoGeometria)
                                            {
                                                case TiposGeometria.Punto:
                                                    ptoInserc = PuntosEtiquetas.GetInsPntPUNTO(oid);
                                                    break;
                                                case TiposGeometria.Linea:
                                                    ptoInserc = PuntosEtiquetas.GetInsPntLINEA(oid);
                                                    break;
                                                //case TiposGeometria.Area:
                                                default:
                                                    ptoInserc = PuntosEtiquetas.GetInsPntAREA(oid);
                                                    break;
                                            }

                                            // INSERTAR EL TEXTO
                                            Texts.InsertText(texto, ptoInserc, criterio);
                                        }
                                    }
                                    break;
                                }
                            }
                        }
                    }
                    finally
                    {
                    }
                }
                else
                {
                    MessageBox.Show(COMUN.Properties.Resources.ElDibujoNoContieneEntidadesDelTipoSeleccionado, COMUN.Properties.Resources.Inventario, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0);
                }
            }
        }

        /// <summary>
        /// Recupera el dominio de un atributo de una entidad
        /// </summary>
        /// <param name="codEnt"></param>
        /// <param name="CodAtt"></param>
        /// <returns></returns>
        private static string GetDomainName(string codEnt, string nomAtt)
        {
            string retVal = "";
            Elemento elemento = new Elemento();
            elemento.CodigoEntidad = codEnt;
            try
            {
                for (int i = 0; i < elemento.Atributos.Count; i++)
                {
                    if (elemento.Atributos[i].Codigo == nomAtt)
                    {
                        retVal = elemento.Atributos[nomAtt].NombreDominio;
                        if (retVal == null) retVal = "";
                        return retVal;
                    }
                }
                return null;
            }
            catch (IndexOutOfRangeException)
            {
                return null;
            }
            //return retVal;
        }

        /// <summary>
        /// Recupera la descripción de un código de dominio.
        /// </summary>
        /// <param name="attDomain"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private static string GetDomainValue(string attDomain, string code)
        {
            foreach (Dominio dom in ModComun.XSD.Dominios)
            {
                if (dom.Codigo == attDomain)
                {
                    foreach (ValorDominio val in dom.Valores)
                    {
                        if (val.Codigo == code) return val.Texto;
                    }
                    break;
                }
            }
            return "";
        }

        public void LanzaEtiquetarElementos()
        {
            try
            {
                ModComun.ActivarEtiquetado(this);
            }
            catch (COMUN.ExcepcionGMLC ex)
            {
                Log.RegisterError(ex);
            }
            catch (System.Exception ex)
            {
                Log.RegisterError(ex);
                throw new COMUN.ExcepcionGMLC("", ex);
            }
        }

        #endregion
    }
}
