using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;

namespace ChuPiao.Common.Utils
{
    /// <summary>
    /// 用于读取大数据的列表
    /// </summary>
    public class VirtualList<T> : ObservableCollection<T>, IList, IList<T>
    {
        #region IList 成员

        public int Add(object value)
        {
            throw new NotImplementedException();
        }

        public new void Clear()
        {
            throw new NotImplementedException();
        }

        public bool Contains(object value)
        {
            throw new NotImplementedException();
        }

        public int IndexOf(object value)
        {
            throw new NotImplementedException();
        }

        public void Insert(int index, object value)
        {
            throw new NotImplementedException();
        }

        public bool IsFixedSize
        {
            get { throw new NotImplementedException(); }
        }

        public new bool IsReadOnly
        {
            get { return true; }
        }

        public void Remove(object value)
        {
            throw new NotImplementedException();
        }

        public new void RemoveAt(int index)
        {
            throw new NotImplementedException();
        }

        public new object this[int index]
        {
            get
            {
                return ((IList<T>)this)[index];
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion

        #region ICollection 成员

        public void CopyTo(Array array, int index)
        {
            throw new NotImplementedException();
        }

        private int _count = -1;
        public new int Count
        {
            get
            {
                if (-1 == _count)
                {
                    if (null != OnQueryCount)
                    {
                        _count = OnQueryCount();
                    }
                }
                return _count == -1 ? 0 : _count;
            }
        }

        /// <summary>
        /// 需要查询列表总数时发生
        /// </summary>
        public event OnQueryCountDelegate OnQueryCount;
        public delegate int OnQueryCountDelegate();


        public bool IsSynchronized
        {
            get { return false; }
        }

        public object SyncRoot
        {
            get { return this; }
        }

        #endregion

        #region IEnumerable 成员

        public IEnumerator GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IList<T> 成员

        public new int IndexOf(T item)
        {
            throw new NotImplementedException();
        }

        public new void Insert(int index, T item)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 从虚拟表中根据Index查找项
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        T IList<T>.this[int index]
        {
            get
            {
                //如果没有数据就直接返回默认项目
                if (0 == this.Count)
                {
                    return default(T);
                }
                //如果数据在cache中则返回数据
                if (_headIndex <= index && index < _headIndex + _cachedItems.Count)
                {
                    return _cachedItems[index - _headIndex];
                }
                //否则就读取数据
                else
                {
                    //计算开始读取的位置
                    int headIndex = 0;
                    int radius = _fetchSize / 2;

                    //如果viewPoint到数据开始位置的距离小于半径，那么就从开始位置读取数据
                    if ((index - radius) < 0)
                    {
                        headIndex = 0;
                    }
                    //如果viewPoint离最后一条数据的位置小于半径，那么就从最后一条数据开始向上fetchSize的位置开始读取数据
                    else if ((index + radius) > _count)
                    {
                        headIndex = _count - _fetchSize;
                        //如果开始位置超过了起始位置，那么还要从起始位置开始读取数据
                        if (headIndex < 0)
                        {
                            headIndex = 0;
                        }
                    }
                    //如果viewPoint的上下半径范围都没有超过队首或者队尾，那么取数据的开始位置在index-radius的位置
                    else
                    {
                        headIndex = index - radius;
                    }
                    if (null != OnQueryPage)
                    {
                        _cachedItems = OnQueryPage(headIndex, _fetchSize);
                    }
                    else
                    {
                        throw new Exception("需要获取数据的方法");
                    }
                    _headIndex = headIndex;
                    _tailIndex = headIndex + _cachedItems.Count - 1;
                    return ((IList<T>)this)[index];
                }
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        /// <summary>
        /// 在内存中的数据
        /// </summary>
        private List<T> _cachedItems = new List<T>();

        /// <summary>
        /// 当需要从数据库中查询数据时发生
        /// 两个传入参数：
        /// 1.查询的起始位置
        /// 2.需要查询的条数
        /// 返回:符合条件的结果列表
        /// 
        /// </summary>
        public event Func<int, int, List<T>> OnQueryPage;

        #endregion

        #region ICollection<T> 成员

        public new void Add(T item)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        ///被依赖的服务 
        /// </summary>
        private string[] _byDepended;
        public string[] ByDepended { get { return _byDepended; } set { _byDepended=value; } }

        /// <summary>
        /// 依赖服务
        /// </summary>
        private string[] _depend;
        public string[] Depend { get { return _depend; } set { _depend = value; } }
        new bool Contains(T item)
        {
            throw new NotImplementedException();
        }

        public new void CopyTo(T[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public new bool Remove(T item)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IEnumerable<T> 成员

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
            throw new NotImplementedException();
        }

        #endregion

        /// <summary>
        /// 缓存中第一条数据对应的位置
        /// </summary>
        private int _headIndex = -1;

        /// <summary>
        /// 缓存中最后一条数据对应的位置
        /// </summary>
        private int _tailIndex = -1;

        private int _fetchSize = 100;
        /// <summary>
        /// 设置或获取每次获取数据的条数
        /// </summary>
        public int FetchSize
        {
            get
            {
                return _fetchSize;
            }
            set
            {
                _fetchSize = value;
            }
        }

        /// <summary>
        /// 复位列表
        /// </summary>
        public void Reset()
        {
            _headIndex = -1;
            _count = -1;
            _cachedItems.Clear();

            NotifyCollectionChangedEventArgs args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
            OnCollectionChanged(args);
        }
    }
}
