using CommonLang.Property;
using System;
using System.Collections.Generic;
using System.Text;

namespace CommonLang.Formula
{
    public enum NumericComparisonOP
    {
        EQUAL,
        NOT_EQUAL,
        LESS_THAN,
        LESS_THAN_OR_EQUAL,
        GREATER_THAN,
        GREATER_THAN_OR_EQUAL,
    }

    public enum ObjectComparisonOP
    {
        EQUAL,
        NOT_EQUAL,
    }

    public enum BooleanOP
    {
        EQUAL,
        NOT_EQUAL,
        AND,
        OR,
        XOR,
    }

    public enum NumericOP
    {
        [DescAttribute("加")]
        ADD,
        [DescAttribute("减")]
        SUB,
        [DescAttribute("乘")]
        MUL,
        [DescAttribute("除")]
        DIV,
        [DescAttribute("求余")]
        MOD,
    }

    public static class FormulaHelper
    {
        public static bool Compare<T>(T a, NumericComparisonOP op, T b) where T : IComparable
        {
            int d = a.CompareTo(b) ;
            switch (op)
            {
                case NumericComparisonOP.EQUAL:
                    return d == 0;
                case NumericComparisonOP.NOT_EQUAL:
                    return d != 0;
                case NumericComparisonOP.LESS_THAN:
                    return d < 0;
                case NumericComparisonOP.LESS_THAN_OR_EQUAL:
                    return d <= 0;
                case NumericComparisonOP.GREATER_THAN:
                    return d > 0;
                case NumericComparisonOP.GREATER_THAN_OR_EQUAL:
                    return d >= 0;
            }
            throw new Exception("NumericComparisonOP未识别的操作数: " + op);
        }

        public static bool Compare(object a, ObjectComparisonOP op, object b)
        {
            if (a != null)
            {
                switch (op)
                {
                    case ObjectComparisonOP.EQUAL:
                        return a.Equals(b);
                    case ObjectComparisonOP.NOT_EQUAL:
                        return !a.Equals(b);
                }
            }
            else
            {
                return a == b;
            }
            throw new Exception("ObjectComparisonOP未识别的操作数: " + op);
        }

        public static bool Calculate(bool a, BooleanOP op, bool b)
        {
            switch (op)
            {
                case BooleanOP.EQUAL:
                    return a == b;
                case BooleanOP.NOT_EQUAL:
                    return a != b;
                case BooleanOP.AND:
                    return a && b;
                case BooleanOP.OR:
                    return a || b;
                case BooleanOP.XOR:
                    return a ^ b;
            }
            throw new Exception("BooleanOP未识别的操作数: " + op);
        }

        public static int Calculate(int a, NumericOP op, int b)
        {
            switch (op)
            {
                case NumericOP.ADD:
                    return a + b;
                case NumericOP.SUB:
                    return a - b;
                case NumericOP.MUL:
                    return a * b;
                case NumericOP.DIV:
                    return a / b;
                case NumericOP.MOD:
                    return a % b;
            }
            throw new Exception("NumericOP未识别的操作数: " + op);
        }

        public static float Calculate(float a, NumericOP op, float b)
        {
            switch (op)
            {
                case NumericOP.ADD:
                    return a + b;
                case NumericOP.SUB:
                    return a - b;
                case NumericOP.MUL:
                    return a * b;
                case NumericOP.DIV:
                    return a / b;
                case NumericOP.MOD:
                    return a % b;
            }
            throw new Exception("NumericOP未识别的操作数: " + op);
        }


        public static string ToString(NumericComparisonOP op)
        {
            switch (op)
            {
                case NumericComparisonOP.EQUAL:
                    return "等于";
                case NumericComparisonOP.NOT_EQUAL:
                    return "不等于";
                case NumericComparisonOP.LESS_THAN:
                    return "小于";
                case NumericComparisonOP.LESS_THAN_OR_EQUAL:
                    return "小于或等于";
                case NumericComparisonOP.GREATER_THAN:
                    return "大于";
                case NumericComparisonOP.GREATER_THAN_OR_EQUAL:
                    return "大于或等于";
            }
            return " nop ";
        }

        public static string ToString(ObjectComparisonOP op)
        {
            switch (op)
            {
                case ObjectComparisonOP.EQUAL:
                    return "等于";
                case ObjectComparisonOP.NOT_EQUAL:
                    return "不等于";
            }
            return " nop ";
        }


        public static string ToString(BooleanOP op)
        {
            switch (op)
            {
                case BooleanOP.EQUAL:
                    return "等于";
                case BooleanOP.NOT_EQUAL:
                    return "不等于";
                case BooleanOP.AND:
                    return "并且";
                case BooleanOP.OR:
                    return "或者";
                case BooleanOP.XOR:
                    return "异或";
            }
            return " nop ";
        }


        public static string ToString(NumericOP op)
        {
            switch (op)
            {
                case NumericOP.ADD:
                    return "+";
                case NumericOP.SUB:
                    return "-";
                case NumericOP.MUL:
                    return "*";
                case NumericOP.DIV:
                    return "/";
                case NumericOP.MOD:
                    return "%";
            }
            return " nop ";
        }
    }

}