﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Playboard.Games.ChainPuzzle.Indexer
{
    /// <summary>
    /// 提供对二维坐标中的对象的存取支持
    /// </summary>
    /// <typeparam name="T">任意类型</typeparam>
    abstract class IndexerBase<T> : IEnumerable<T>
    {
        protected Dictionary<int, Dictionary<int, T>> dict = new Dictionary<int, Dictionary<int, T>>();

        /// <summary>
        /// 获取指定位置的元素
        /// </summary>
        /// <param name="p">表示指定位置的Point</param>
        /// <returns>获取到的元素，若为空则返回null</returns>
        public T this[Point p]
        {
            get { return this[p.X, p.Y]; }
            set { this[p.X, p.Y] = value; }
        }
        /// <summary>
        /// 获取指定位置的元素
        /// </summary>
        /// <param name="x">位置的X坐标</param>
        /// <param name="y">位置的Y坐标</param>
        /// <returns>获取到的元素，若为空则返回null</returns>
        public T this[int x, int y]
        {
            get
            {
                if (dict.ContainsKey(x) && dict[x].ContainsKey(y))
                {
                    return dict[x][y];
                }
                else
                {
                    return default(T);
                }
            }
            set
            {
                Dictionary<int, T> yDict = null;
                if (!dict.ContainsKey(x))
                {
                    yDict = dict[x] = new Dictionary<int, T>();
                }
                else
                {
                    yDict = dict[x];
                }
                yDict[y] = value;
            }
        }
        /// <summary>
        /// 清除定位器的数据
        /// </summary>
        public void Clear()
        {
            foreach (var pair in dict)
            {
                pair.Value?.Clear();
            }
        }
        /// <summary>
        /// 完全重置定位器的数据
        /// </summary>
        public void Reset()
        {
            Clear();
            dict.Clear();
            dict = new Dictionary<int, Dictionary<int, T>>();
        }
        /// <summary>
        /// 将定位器的数据还原为默认状态
        /// </summary>
        abstract public void SetToDefault();
        /// <summary>
        /// 对每项元素执行指定的操作
        /// </summary>
        /// <param name="action">要执行的操作</param>
        public void ForEach(Action<T> action)
        {
            foreach (var yDict in dict.Values)
            {
                foreach (var element in yDict.Values)
                {
                    action(element);
                }
            }
        }
        //private List<Point> changedLocations = new List<Point>();
        ///// <summary>
        ///// 将特定位置的元素标记为已更改
        ///// </summary>
        ///// <param name="location"></param>
        //public void SetAsChanged(Point location)
        //{
        //    changedLocations.Add(location);
        //}
        ///// <summary>
        ///// 对所以标记为已更改的元素执行指定的操作
        ///// </summary>
        ///// <param name="action">指定的操作</param>
        //public void ForEachChanged(Action<T> action)
        //{
        //    foreach (var location in changedLocations)
        //    {
        //        action(this[location]);
        //    }
        //}

        public IEnumerator<T> GetEnumerator()
        {
            foreach (var yDict in dict.Values)
            {
                foreach (var element in yDict.Values)
                {
                    yield return element;
                }
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}
