using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.InteropServices;
using System.Text;

namespace GMLC01HerramientasCad.Logica
{

    /// <summary>
    /// Tipos de edición de un atributo
    /// </summary>
    public enum TiposEdicion
    {
        /// <summary>
        /// </summary>
        Entero,
        /// <summary>
        /// </summary>
        Doble,
        /// <summary>
        /// </summary>
        Texto,
        /// <summary>
        /// </summary>
        Combo
    }

    /// <summary>
    /// Definición del atributo para transferenicia con el módulo CAD
    /// </summary>
    public class Atributo:ICloneable
    {

        /// <summary>
        /// Constructor de la clase
        /// </summary>
        /// <param name="codigo">Código del atributo según aparece en el XSD</param>
        /// <param name="entidad">Entidad a la que pertenece el atributo según aparece en el XSD</param>
        /// <param name="nombres">Nombres del atributo en los diferentes idiomas soportados en el XSD</param>
        /// <param name="descripciones">Descripciones del atributo en los diferentes idiomas soportados en el XSD</param>
        /// <param name="tipoEdicion">Indica el tipo de control a usar en la edición alfanumérica</param>
        /// <param name="valor"></param>
        public Atributo(String codigo,
                        Entidad entidad,
                        Dictionary<string, string> nombres,
                        Dictionary<string, string> descripciones,
                        TiposEdicion tipoEdicion, String valor)
        {
            try
            {
                Codigo = codigo;
                Entidad = entidad;
                Nombres = nombres;
                Descripciones = descripciones;
                Valor = valor;
                TipoEdicion = tipoEdicion;
            }
            catch (Exception e)
            {
                Log.RegisterError(e);
                throw new ExcepcionGMLC(e.Message, e);
            }
        }

        /// <summary>
        /// Código del atributo
        /// </summary>
        public String Codigo { get; internal set; }

        /// <summary>
        /// Entidad a la que pertenece este atributo
        /// </summary>
        public Entidad Entidad { get; internal set; }

        /// <summary>
        /// Nombres del atributo en los diferentes idiomas soportados en el XSD
        /// </summary>
        public Dictionary<string, string> Nombres { get; internal set; }

        /// <summary>
        /// Nombre a mostrar del atributo según el idioma activo
        /// </summary>
        public String Nombre
        {
            get { return Nombres[ModComun.Idioma]; }
        }
        
        /// <summary>
        /// Descripciones del atributo en los diferentes idiomas soportados en el XSD
        /// </summary>
        public Dictionary<string, string> Descripciones { get; internal set; }

        /// <summary>
        /// Descripción a mostrar del atributo según el idioma activo
        /// </summary>
        public String Descripcion
        {
            get { return Descripciones[ModComun.Idioma]; }
        }

        /// <summary>
        /// Define el tipo de edición de un campo
        /// </summary>
        public TiposEdicion TipoEdicion { get; internal set; }

        /// <summary>
        /// 
        /// </summary>
        public String Valor { get; set; }

        /// <summary>
        /// 
        /// </summary>
        public String ValorOriginal { get; set; }

        /// <summary>
        /// Dominio del atributo, si es necesario
        /// </summary>
        public String NombreDominio { get; internal set; }

        public String Unidades { get; set; }

        private Boolean valorNulo;

        public Boolean Nillable 
        { 
            get
            {
                return valorNulo;
            }
            set{
                valorNulo = value;
            }
        }

        public String Action { get; set; }

        /// <summary>
        /// Implementa la clonación de un atributo
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            try
            {
                return this.MemberwiseClone();
            }
            catch (Exception e)
            {
                Log.RegisterError(e);
                throw new ExcepcionGMLC(e.Message, e);
            }
        }

        /// <summary>
        /// Indica si ha cambiado el valor del atributo respecto a su valor original
        /// </summary>
        public Boolean ValorCambiado
        {
            get { return  ValorOriginal != Valor; }
        }
    }

    
    /// <summary>
    /// Lista de atributos con accesibilidad por clave
    /// </summary>
    [ComVisible(false)]
    public class ListaAtributos : KeyedCollection<String, Atributo>
    {
        /// <summary>
        /// Define el código de atributo como clave de búsqueda en la lista
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        protected override string GetKeyForItem(Atributo item)
        {
            return item.Codigo;
        }
    }
}
