using System;
using System.Collections.Generic;
using Telerik.Web.UI;
using System.ComponentModel;

namespace Telerik.Web.Examples.Grid
{
    public class MyBusinessObjectCollection
    {
        const int _maxItems = 400;

        string[] names = new string[] { "Côte de Blaye", "Boston Crab Meat", "Singaporean Hokkien Fried Mee", "Gula Malacca", "Rogede sild", "Spegesild", "Zaanse koeken", "Chocolade", "Maxilaku", "Valkoinen suklaa" };
        double[] prizes = new double[] { 23.2500, 9.0000, 45.6000, 32.0000, 14.0000, 19.0000, 263.5000, 18.4000, 3.0000, 14.0000 };
        DateTime[] dates = new DateTime[] { new DateTime(2007, 5, 10), new DateTime(2008, 9, 13), new DateTime(2008, 2, 22), new DateTime(2009, 1, 2), new DateTime(2007, 4, 13), new DateTime(2008, 5, 12), new DateTime(2008, 1, 19), new DateTime(2008, 8, 26), new DateTime(2008, 7, 31), new DateTime(2007, 7, 16) };
        bool[] bools = new bool[] { true, false, true, false, true, false, true, false, true, false };

        public MyBusinessObjectCollection()
        {
        }

        public int SelectCount()
        {
            return _maxItems;
        }

        public List<MyBusinessObject> Select()
        {
            if (System.Web.HttpContext.Current.Cache["data"] == null)
            {
                System.Web.HttpContext.Current.Cache["data"] = Select(0, _maxItems);
            }
            return (List<MyBusinessObject>)System.Web.HttpContext.Current.Cache["data"];
        }

        public List<MyBusinessObject> Select(int startRowIndex, int maximumRows)
        {
            Random Random1 = new Random();

            List<MyBusinessObject> list = new List<MyBusinessObject>();

            int i = startRowIndex;
            while (i < Math.Min(_maxItems, startRowIndex + maximumRows))
            {
                MyBusinessObject Product1 = new MyBusinessObject();
                Product1.ID = i;
                Product1.Name = names[Random1.Next(9)];
                Product1.UnitPrice = prizes[Random1.Next(9)];
                Product1.Date = dates[Random1.Next(9)];
                Product1.Discontinued = bools[Random1.Next(9)];
                list.Add(Product1);
                i++;
            }
            return list;
        }
    }



    public class MyBusinessObject
    {
        private int _id;
        private string _name;
        private double _unitPrice;
        private DateTime _date;
        private bool _discontinued;

        public MyBusinessObject()
        {

        }

        public MyBusinessObject(int _id, string _name, double _unitPrice, DateTime _date, bool _discontinued)
        {
            this._id = _id;
            this._name = _name;
            this._unitPrice = _unitPrice;
            this._date = _date;
            this._discontinued = _discontinued;
        }

        public int ID
        {
            get { return _id; }
            set { _id = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public double UnitPrice
        {
            get { return _unitPrice; }
            set { _unitPrice = value; }
        }

        public DateTime Date
        {
            get { return _date; }
            set { _date = value; }
        }

        public bool Discontinued
        {
            get { return _discontinued; }
            set { _discontinued = value; }
        }
    }

    public class GridGenericSorter<T> : IComparer<T>
    {
        GridSortExpression _expression = null;
        PropertyDescriptor _descriptor = null;

        public GridGenericSorter(GridSortExpression expression)
        {
            _descriptor = TypeDescriptor.GetProperties(GetType().GetGenericArguments()[0]).Find(expression.FieldName, true);
            _expression = expression;
        }

        public int Compare(T o1, T o2)
        {
            IComparable comparable1 = (IComparable)_descriptor.GetValue(o1);
            IComparable comparable2 = (IComparable)_descriptor.GetValue(o2);

            if (_expression.SortOrder == GridSortOrder.Ascending)
            {
                return comparable1.CompareTo(comparable2);
            }
            else
            {
                return comparable2.CompareTo(comparable1);
            }
        }
    }

    public class GridGenericFilterer<T>
    {
        GridFilterExpression _expression = null;
        PropertyDescriptor _descriptor = null;
        Type _propertyType = null;
        GridKnownFunction _filterFunction;

        public GridGenericFilterer(GridFilterExpression expression)
        {
            _expression = expression;
            _descriptor = TypeDescriptor.GetProperties(GetType().GetGenericArguments()[0]).Find(expression.FieldName, true);
            _propertyType = _descriptor.PropertyType;
            _filterFunction = (GridKnownFunction)Enum.Parse(typeof(GridKnownFunction), _expression.FilterFunction);
        }

        public bool Filter(T item)
        {
            object value = _descriptor.GetValue(item);
            string stringValue = value.ToString();

            if (_propertyType == typeof(String))
            {
                if (_filterFunction == GridKnownFunction.Contains)
                {
                    return stringValue.Contains(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.DoesNotContain)
                {
                    return !stringValue.Contains(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.StartsWith)
                {
                    return stringValue.StartsWith(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.EndsWith)
                {
                    return stringValue.EndsWith(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.EqualTo)
                {
                    return stringValue.Equals(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.NotEqualTo)
                {
                    return !stringValue.Equals(_expression.FieldValue);
                }
                else if (_filterFunction == GridKnownFunction.IsEmpty)
                {
                    return stringValue.Equals(String.Empty);
                }
                else if (_filterFunction == GridKnownFunction.NotIsEmpty)
                {
                    return !stringValue.Equals(String.Empty);
                }
                else if (_filterFunction == GridKnownFunction.GreaterThan)
                {
                    return stringValue.CompareTo(_expression.FieldValue) > 0;
                }
                else if (_filterFunction == GridKnownFunction.GreaterThanOrEqualTo)
                {
                    return stringValue.CompareTo(_expression.FieldValue) >= 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThan)
                {
                    return stringValue.CompareTo(_expression.FieldValue) < 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThanOrEqualTo)
                {
                    return stringValue.CompareTo(_expression.FieldValue) <= 0;
                }
            }
            else if (_propertyType == typeof(Boolean))
            {
                if (_filterFunction == GridKnownFunction.EqualTo)
                {
                    return Boolean.Parse(stringValue).Equals(Boolean.Parse(_expression.FieldValue));
                }
                else if (_filterFunction == GridKnownFunction.NotEqualTo)
                {
                    return !Boolean.Parse(stringValue).Equals(Boolean.Parse(_expression.FieldValue));
                }
            }
            else if (_propertyType == typeof(DateTime))
            {
                if (_filterFunction == GridKnownFunction.EqualTo)
                {
                    return DateTime.Parse(stringValue).Equals(DateTime.Parse(_expression.FieldValue));
                }
                else if (_filterFunction == GridKnownFunction.NotEqualTo)
                {
                    return !DateTime.Parse(stringValue).Equals(DateTime.Parse(_expression.FieldValue));
                }
                else if (_filterFunction == GridKnownFunction.GreaterThan)
                {
                    return DateTime.Parse(stringValue).CompareTo(DateTime.Parse(_expression.FieldValue)) > 0;
                }
                else if (_filterFunction == GridKnownFunction.GreaterThanOrEqualTo)
                {
                    return DateTime.Parse(stringValue).CompareTo(DateTime.Parse(_expression.FieldValue)) >= 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThan)
                {
                    return DateTime.Parse(stringValue).CompareTo(DateTime.Parse(_expression.FieldValue)) < 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThanOrEqualTo)
                {
                    return DateTime.Parse(stringValue).CompareTo(DateTime.Parse(_expression.FieldValue)) <= 0;
                }
            }
            else if (IsNumeric(_propertyType))
            {
                if (_filterFunction == GridKnownFunction.EqualTo)
                {
                    return Decimal.Parse(stringValue).Equals(Decimal.Parse(_expression.FieldValue));
                }
                else if (_filterFunction == GridKnownFunction.NotEqualTo)
                {
                    return !Decimal.Parse(stringValue).Equals(Decimal.Parse(_expression.FieldValue));
                }
                else if (_filterFunction == GridKnownFunction.GreaterThan)
                {
                    return Decimal.Parse(stringValue).CompareTo(Decimal.Parse(_expression.FieldValue)) > 0;
                }
                else if (_filterFunction == GridKnownFunction.GreaterThanOrEqualTo)
                {
                    return Decimal.Parse(stringValue).CompareTo(Decimal.Parse(_expression.FieldValue)) >= 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThan)
                {
                    return Decimal.Parse(stringValue).CompareTo(Decimal.Parse(_expression.FieldValue)) < 0;
                }
                else if (_filterFunction == GridKnownFunction.LessThanOrEqualTo)
                {
                    return Decimal.Parse(stringValue).CompareTo(Decimal.Parse(_expression.FieldValue)) <= 0;
                }
            }

            if (_filterFunction == GridKnownFunction.IsNull)
            {
                return value.Equals(null);
            }
            else if (_filterFunction == GridKnownFunction.NotIsNull)
            {
                return !value.Equals(null);
            }

            return true;
        }

        static bool IsNumeric(Type type)
        {
            if (!type.IsEnum)
            {
                switch (Type.GetTypeCode(type))
                {
                    case TypeCode.Char:
                    case TypeCode.SByte:
                    case TypeCode.Byte:
                    case TypeCode.Int16:
                    case TypeCode.UInt16:
                    case TypeCode.Int32:
                    case TypeCode.UInt32:
                    case TypeCode.Int64:
                    case TypeCode.UInt64:
                    case TypeCode.Single:
                    case TypeCode.Double:
                    case TypeCode.Decimal:
                        return true;
                }
            }
            return false;
        }
    }
}
