using System;
using System.ComponentModel;
using System.Reflection;

namespace icEveryCode
{

  public class TComboboxItem<T>
  {
    private Type type;
    private string FText = "";
    private T FTag = default( T );
    /// <summary>
    /// Текст, который будет показываться в списке Combobox
    /// </summary>
    public string Text { get { return FText; } }
    /// <summary>
    /// Элемент перечисления, связаный с объектом
    /// </summary>
    public T Tag { get { return FTag; } }
    public override string ToString ( )
    {
      return FText;
    }
    /// <summary>
    /// конструктор
    /// </summary>
    /// <param name="aTag">один из элементов Enum`а</param>
    public TComboboxItem (T aTag)
    {
      type = typeof( T );
      FTag = aTag;
      FText = GetEnumDescription( FTag );
    }
    /// <summary>
    /// Позволяет получать строку из атрибута Description, если он есть 
    /// </summary>
    /// <param name="aTag">один из элементов Enum`а</param>
    /// <returns>Дескриптор или, если нет, название элемента</returns>
    public static string GetEnumDescription (T aTag)
    {
      Type type = typeof( T );
      string Text = aTag.ToString( );
      if ( !type.IsEnum )
      {
        throw new ArgumentException( "Параметр должен быть типа Enum", "TComboBoxItem.GetEnumDescription" );
      }
      foreach ( MemberInfo memberInfo in type.GetMember( Text ) )
      {
        if ( memberInfo.IsDefined( typeof( DescriptionAttribute ), false ) )
          foreach ( object attr in memberInfo.GetCustomAttributes( typeof( DescriptionAttribute ), false ) )
          {
            return ( attr as DescriptionAttribute ).Description;
          }
      }
      return Text;
    }
    /// <summary>
    /// Позволяет получить значение Enum`а повыбранному элементу ComboBox`а
    /// </summary>
    /// <param name="C">ComboBox</param>
    /// <returns>Элемент Enum`а</returns>
    public static T GetComboIndex (System.Windows.Forms.ComboBox C)
    {
      if ( C.SelectedIndex >= 0 )
        if ( C.Items[ C.SelectedIndex ] is TComboboxItem<T> )
        {
          return ( C.Items[ C.SelectedIndex ] as TComboboxItem<T> ).Tag;
        }
      return default( T );
    }
    /// <summary>
    /// Позволяет установить установить выбраный элемент ComboBox`а, соответствующий элементу Enum`а
    /// </summary>
    /// <param name="C">ComboBox</param>
    /// <param name="Default">Элемент Enum`а</param>
    public static void SetComboIndex (System.Windows.Forms.ComboBox C, T Default)
    {
      for ( int i = 0; i < C.Items.Count; i++ )
      {
        if ( C.Items[ i ] is TComboboxItem<T> )
        {
          if ( ( C.Items[ i ] as TComboboxItem<T> ).Tag.Equals( Default ) )
          {
            C.SelectedIndex = i;
            return;
          }
        }
      }
    }
    /// <summary>
    /// Функция заполняет комбобокс элементами типа TComboBoxItem{T}
    /// </summary>
    /// <param name="C">ComboBox</param>
    public static void InitCombo (System.Windows.Forms.ComboBox C)
    {
      C.Items.Clear( );
      T[ ] TT = (T[ ])Enum.GetValues( typeof( T ) );
      foreach ( T MM in TT )
      {
        C.Items.Add( new TComboboxItem<T>( MM ) );
      }
    }
    /// <summary>
    /// Функция заполняет комбобокс элементами типа TComboBoxItem{T} и устанавливает выделенный элемент
    /// </summary>
    /// <param name="C">ComboBox</param>
    /// <param name="Default">Элемент Enum`а</param>
    public static void InitCombo (System.Windows.Forms.ComboBox C, T Default)
    {
      InitCombo( C );
      SetComboIndex( C, Default );
    }
  }
}

