﻿using System;
using System.Windows.Forms;

namespace SuperComboBox
{
    public class DesignerStrongComboBox : ComboBox
    {
        public DesignerStrongComboBox()
        {
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="DesignerStrongComboBox" /> class.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="comboBox">The combo box.</param>
        public DesignerStrongComboBox(Type type, ComboBox comboBox = null)
        {
            var itemsType = typeof(DesignerStrongItemsCollection<>).MakeGenericType(type);
            object[] parameters = {this};
            Items = Activator.CreateInstance(itemsType, parameters);

            if (comboBox == null) return;
            //Current Properties if any
            FormattingEnabled = comboBox.FormattingEnabled;
            Location = comboBox.Location;
            Size = comboBox.Size;
        }

        /// <summary>
        /// Gets an object representing the collection of the items contained in this <see cref="T:System.Windows.Forms.ComboBox" />.
        /// </summary>
        public new dynamic Items { get; set; }
    }

    public class DesignerStrongItemsCollection<T> : ComboBox.ObjectCollection
    {
        private readonly string _currentCollectionType;

        /// <summary>
        /// Initializes a new instance of the <see cref="DesignerStrongItemsCollection{T}"/> class.
        /// </summary>
        /// <param name="owner">The <see cref="T:System.Windows.Forms.ComboBox" /> that owns this object collection.</param>
        public DesignerStrongItemsCollection(ComboBox owner) : base(owner)
        {
            _currentCollectionType = typeof(T).ToString();
        }

        /// <summary>
        /// Adds an item to the list of items for a <see cref="T:System.Windows.Forms.ComboBox" />.
        /// </summary>
        /// <param name="item">An object representing the item to add to the collection.</param>
        /// <returns>
        /// The zero-based index of the item in the collection.
        /// </returns>
        /// <exception cref="ArgumentException">This combobox only receives class type: {_currentCollectionType}</exception>
        public new int Add(object item)
        {
            if (item.GetType().ToString() != _currentCollectionType)
                throw new ArgumentException($"This combobox only receives class type: {_currentCollectionType}");
            base.Add(item);
            return IndexOf(item.ToString());
        }
    }
}