using CtrEditor.ObjetosSim;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Reflection;
namespace CtrEditor.Serialization
{
///
/// Clase para gestionar qué propiedades deben ser locales en objetos globales
///
public static class PropiedadesLocalesManager
{
// Definición de propiedades por defecto que se guardan localmente para todos los objetos
private static readonly List PropiedadesPorDefecto = new List
{
"Left", "Top", "Ancho", "Alto"
};
// Diccionario que contiene conjuntos de propiedades locales por tipo de objeto
private static readonly Dictionary> PropiedadesPorTipo = new Dictionary>();
///
/// Registra un conjunto de propiedades locales para un tipo específico de objeto
///
/// Tipo de objeto (debe heredar de osBase)
/// Lista de nombres de propiedades a registrar como locales
public static void RegistrarPropiedadesParaTipo(List propiedades) where T : osBase
{
PropiedadesPorTipo[typeof(T)] = propiedades;
}
///
/// Obtiene la lista de propiedades que deben ser locales para un objeto concreto
///
/// Objeto del que obtener las propiedades locales
/// Lista de nombres de propiedades
public static List ObtenerPropiedadesLocales(osBase objeto)
{
var resultado = new List(PropiedadesPorDefecto);
if (objeto != null && PropiedadesPorTipo.TryGetValue(objeto.GetType(), out var propiedadesExtra))
{
foreach (var prop in propiedadesExtra)
{
if (!resultado.Contains(prop))
resultado.Add(prop);
}
}
return resultado;
}
///
/// Crea un objeto dinámico que permite acceder a las propiedades locales de un objeto
///
/// Objeto del que crear una vista dinámica
/// Objeto dinámico con propiedades locales
public static dynamic CrearAccesoDinamico(osBase objeto)
{
return new PropiedadesLocalesDinamicas(objeto);
}
///
/// Clase interna que implementa un acceso dinámico a propiedades
///
private class PropiedadesLocalesDinamicas : DynamicObject
{
private readonly osBase _objeto;
private readonly List _propiedadesLocales;
public PropiedadesLocalesDinamicas(osBase objeto)
{
_objeto = objeto;
_propiedadesLocales = ObtenerPropiedadesLocales(objeto);
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
var nombrePropiedad = binder.Name;
if (_propiedadesLocales.Contains(nombrePropiedad))
{
var propInfo = _objeto.GetType().GetProperty(nombrePropiedad);
if (propInfo != null && propInfo.CanRead)
{
result = propInfo.GetValue(_objeto);
return true;
}
}
result = null;
return false;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
var nombrePropiedad = binder.Name;
if (_propiedadesLocales.Contains(nombrePropiedad))
{
var propInfo = _objeto.GetType().GetProperty(nombrePropiedad);
if (propInfo != null && propInfo.CanWrite)
{
try
{
var valorConvertido = Convert.ChangeType(value, propInfo.PropertyType);
propInfo.SetValue(_objeto, valorConvertido);
return true;
}
catch (Exception)
{
// Silenciar errores de conversión
}
}
}
return false;
}
public override IEnumerable GetDynamicMemberNames()
{
return _propiedadesLocales;
}
}
}
}