using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Globalization;
using System.ComponentModel;

namespace CaLib.User.PropertyGridUtil
{

	[AttributeUsage(AttributeTargets.All)]
	public class EnumDisplayNameAttribute : Attribute
	{
		public EnumDisplayNameAttribute(string name)
		{
			this.name = name;
		}

		public EnumDisplayNameAttribute(Type resourceManagerProvider, string resourceKey)
		{
			this.name = Util.LookupResource(resourceManagerProvider, resourceKey);
		}


		public string Name
		{
			get { return GetName(CultureInfo.CurrentCulture); }
		}
		public virtual string GetName(CultureInfo culture)
		{
			return this.name;
		}
		private string name;
	}

	public class EnumDisplayNameConverter : EnumConverter
	{
		public EnumDisplayNameConverter(Type type)
			: base(type)
		{
		}
		public override object ConvertFrom(ITypeDescriptorContext context,
										   CultureInfo culture,
										   object valueToConvert)
		{
			string value = valueToConvert as string;
			if (value != null)
			{
				foreach (FieldInfo field in base.EnumType.GetFields())
				{
					string name = this.GetDisplayName(field, culture);
					if (name == value)
						return field.GetValue(null);
				}
			}
			return base.ConvertFrom(context, culture, valueToConvert);
		}
		public override object ConvertTo(ITypeDescriptorContext context,
										 CultureInfo culture,
										 object value,
										 Type destinationType)
		{
			if (destinationType == typeof(string))
			{
				string valueName = Enum.GetName(base.EnumType, value);
				if (valueName != null)
				{
					FieldInfo field = base.EnumType.GetField(valueName);
					string name = this.GetDisplayName(field, culture);
					if (name != null)
						return name;
				}
			}
			return base.ConvertTo(context, culture, value, destinationType);
		}
		private string GetDisplayName(FieldInfo field, CultureInfo culture)
		{
			if (field == null)
				return null;
			Type type = typeof(EnumDisplayNameAttribute);
			Attribute attr = Attribute.GetCustomAttribute(field, type);
			EnumDisplayNameAttribute disp = attr as EnumDisplayNameAttribute;
			return (disp == null) ? null : disp.GetName(culture);
		}
	}
}
