using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.Reflection;

namespace digioz
{
    /// <summary>
    /// Extends the BindingList<T> class to offer additional functions like
    /// * Find(): Returns the index of the record having a property 
    /// matching the passed in value
    /// </summary>
    public class ExtendedBindingList<T> : BindingList<T>
    {
        public ExtendedBindingList()
        { }

        /// <summary>
        /// Indicate searching is implemented on the list.
        /// </summary>
        protected override bool SupportsSearchingCore
        {
            get
            {
                return true;
            }
        }

        /// <summary>
        /// Searches a list and returns the index of a found item.
        /// loProp -- > Property to search for
        /// loKey --> Value for the property to search for.
        /// Return -1 if item is not found
        /// </summary>
        /// <param name="loProp" ></param>
        /// <param name="loKey"></param>
        /// <returns></returns>
        protected override int FindCore(PropertyDescriptor loProp, object loKey)
        {
            int liRetValue = -1;
            // Get the property info for the specified property.
            PropertyInfo loPropInfo = typeof(T).GetProperty(loProp.Name);
            T item;

            if (loKey != null)
            {
                // Loop through the items to see if the key
                // value matches the property value.
                for (int i = 0; i < this.Count; ++i)
                {
                    item = (T)this.Items[i];
                    if (loPropInfo.GetValue(item, null).Equals(loKey))
                    {
                        liRetValue = i;
                    }
                }
            }
            return liRetValue;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="loProperty"></param>
        /// <param name="loKey"></param>
        /// <returns></returns>
        public int Find(string loProperty, object loKey)
        {
            int liRetValue = -1;
            // Check the properties for a property with the specified name.
            PropertyDescriptorCollection loProperties = TypeDescriptor.GetProperties(typeof(T));

            // Perform a case-insentive search of the property name
            PropertyDescriptor loProp = loProperties.Find(loProperty, true);

            // If there is not a match, return -1 otherwise pass search to
            // FindCore method.
            if (loProp != null)
            {
                liRetValue = FindCore(loProp, loKey);
            }

            return liRetValue;
        }
    }
}
