using CommonAI.RTS;
using CommonLang.Vector;
using CommonAI.Zone.Instance;
using System;
using System.Collections.Generic;
using System.Text;
using CommonLang;

namespace CommonAI.Zone.Helper
{
    public delegate bool Select<T>(T obj);

    public class RangeValue
    {
        private int mMin = 0;
        private int mMax = 0;
        private int mValue = 0;

        public int Min { get { return mMin; } }
        public int Max { get { return mMax; } }
        public int Value { get { return mValue; } }

        public RangeValue(int value, int min, int max)
        {
            mMin = Math.Min(min, max);
            mMax = Math.Max(min, max);
            SetValue(value);
        }
        public bool SetMin(int min)
        {
            if (min != mMin && min <= mMax)
            {
                mMin = min;
                mValue = Math.Min(mValue, mMax);
                mValue = Math.Max(mValue, mMin);
                return true;
            }
            return false;
        }
        public bool SetMax(int max, bool autoGenValue = false)
        {
            if (max != mMax && max >= mMin)
            {
                if (autoGenValue)
                {
					float addrat = (max / (float)mMax) - 1f;
					mMax = max;
					Add(CUtils.CastInt(mValue * addrat));
				}
                else
                {
                    mMax = max;
                    mValue = Math.Min(mValue, mMax);
                    mValue = Math.Max(mValue, mMin);
                }
                return true;
            }
            return false;
        }
        public bool SetValue(int value)
        {
            if (value != mValue)
            {
                value = Math.Min(value, mMax);
                value = Math.Max(value, mMin);

                if (value != mValue)
                {
                    mValue = value;
                    return true;
                }
            }
            return false;
        }
        public bool Add(int add)
        {
            if (add != 0)
            {
                return SetValue(mValue + add);
            }
            return false;
        }
    }
    public class RangeValueF
    {
        private float mMin = 0;
        private float mMax = 0;
        private float mValue = 0;

        public float Min { get { return mMin; } }
        public float Max { get { return mMax; } }
        public float Value { get { return mValue; } }

        public RangeValueF(float value, float min, float max)
        {
            mMin = Math.Min(min, max);
            mMax = Math.Max(min, max);
            SetValue(value);
        }
        public bool SetMin(float min)
        {
            if (min != mMin && min <= mMax)
            {
                mMin = min;
                mValue = Math.Min(mValue, mMax);
                mValue = Math.Max(mValue, mMin);
                return true;
            }
            return false;
        }
        public bool SetMax(float max, bool autoGenValue = false)
        {
            if (max != mMax && max >= mMin)
            {
                if (autoGenValue)
                {
                    float addrat = (max / mMax) - 1f;
                    mMax = max;
                    Add(mValue * addrat);
                }
                else
                {
                    mMax = max;
                    mValue = Math.Min(mValue, mMax);
                    mValue = Math.Max(mValue, mMin);
                }
                return true;
            }
            return false;
        }
        public bool SetValue(float value)
        {
            if (value != mValue)
            {
                value = Math.Min(value, mMax);
                value = Math.Max(value, mMin);

                if (value != mValue)
                {
                    mValue = value;
                    return true;
                }
            }
            return false;
        }
        public bool Add(float add)
        {
            if (add != 0)
            {
                return SetValue(mValue + add);
            }
            return false;
        }
    }

    /// <summary>
    /// 从小到大排序
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct ObjectSorterNearest<T> : IComparer<T> where T : IPositionObject
    {
        private float X;
        private float Y;
        public ObjectSorterNearest(float x, float y)
        {
            this.X = x;
            this.Y = y;
        }
        public int Compare(T x, T y)
        {
            float d0 = MathVector.getDistanceSquare(x.X, x.Y, this.X, this.Y);
            float d1 = MathVector.getDistanceSquare(y.X, y.Y, this.X, this.Y);
            if (d0 < d1)
                return -1;
            if (d0 > d1)
                return 1;
            return 0;
        }
    }
    /// <summary>
    /// 从大到小排序
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct ObjectSorterFarthest<T> : IComparer<T> where T : IPositionObject
    {
        private float X;
        private float Y;
        public ObjectSorterFarthest(float x, float y)
        {
            this.X = x;
            this.Y = y;
        }
        public int Compare(T x, T y)
        {
            float d0 = MathVector.getDistanceSquare(x.X, x.Y, this.X, this.Y);
            float d1 = MathVector.getDistanceSquare(y.X, y.Y, this.X, this.Y);
            if (d0 < d1)
                return 1;
            if (d0 > d1)
                return -1;
            return 0;
        }
    }

    /// <summary>
    /// 从小到大排序
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct ObjectBodySorterNearest<T> : IComparer<T> where T : IPositionObject
    {
        private float X;
        private float Y;
        private float R;
        public ObjectBodySorterNearest(float x, float y, float r)
        {
            this.X = x;
            this.Y = y;
            this.R = r;
        }
        public int Compare(T x, T y)
        {
            float d0 = Math.Abs(MathVector.getDistance(x.X, x.Y, this.X, this.Y) - (x.RadiusSize + R));
            float d1 = Math.Abs(MathVector.getDistance(y.X, y.Y, this.X, this.Y) - (y.RadiusSize + R));
            if (d0 < d1)
                return -1;
            if (d0 > d1)
                return 1;
            return 0;
        }
    }
    /// <summary>
    /// 从大到小排序
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public struct ObjectBodySorterFarthest<T> : IComparer<T> where T : IPositionObject
    {
        private float X;
        private float Y;
        private float R;
        public ObjectBodySorterFarthest(float x, float y, float r)
        {
            this.X = x;
            this.Y = y;
            this.R = r;
        }
        public int Compare(T x, T y)
        {
            float d0 = Math.Abs(MathVector.getDistance(x.X, x.Y, this.X, this.Y) - (x.RadiusSize + R));
            float d1 = Math.Abs(MathVector.getDistance(y.X, y.Y, this.X, this.Y) - (y.RadiusSize + R));
            if (d0 < d1)
                return 1;
            if (d0 > d1)
                return -1;
            return 0;
        }
    }
}