using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;

namespace Quiz.Utility
{
    public class RequestGeter
    {
        private Dictionary<string, object> values;
        private IList<RequestGeter.Rule> rules;
        private List<string> messages;
        private NameValueCollection namevalues;
        private bool geted;
        private bool checkok;

        public object this[string formname]
        {
            get
            {
                if (this.values == null)
                    return (object)null;
                formname = formname.ToLower();
                if (!this.values.ContainsKey(formname))
                    return (object)null;
                return this.values[formname];
            }
            set
            {
                if (this.values == null)
                    this.values = new Dictionary<string, object>();
                formname = formname.ToLower();
                if (!this.values.ContainsKey(formname))
                    this.values.Add(formname, value);
                else
                    this.values[formname] = value;
            }
        }

        public string GetParam(string formname)
        {
            string str = string.Empty;
            try
            {
                str = this[formname].ToString();
            }
            catch
            {
            }
            if (string.IsNullOrEmpty(str)) return "";
            return str;
        }

        public bool GetParamBoolean(string formname)
        {
            string str = string.Empty;
            try
            {
                str = this[formname].ToString();
            }
            catch
            {
            }
            if (string.IsNullOrEmpty(str) || str == "false" || str == "0") return false;
            return true;
        }
        public int GetParamInt(string formname)
        {
            try
            {
                return int.Parse(GetParam(formname));
            }
            catch
            {
                return 0;
            }
        }
        public long GetParamLong(string formname)
        {
            try
            {
                return long.Parse(GetParam(formname));
            }
            catch
            {
                return 0;
            }
        }
        public DateTime GetParamDateTime(string formname)
        {
            try
            {
                return DateTime.Parse(GetParam(formname));
            }
            catch
            {
                return new DateTime(1970, 1, 1, 0, 0, 0);
            }
        }
        public decimal GetParamDecimal(string formname)
        {
            try
            {
                return decimal.Parse(this.GetParam(formname));
            }
            catch
            {
                return 0m;
            }
        }
        public float GetParamFloat(string formname)
        {
            try
            {
                return float.Parse(this.GetParam(formname));
            }
            catch
            {
                return 0.0f;
            }
        }
        public double GetParamDouble(string formname)
        {
            try
            {
                return double.Parse(this.GetParam(formname));
            }
            catch
            {
                return 0.0f;
            }
        }

        public List<string> Messages
        {
            get { return this.messages; }
        }
        public bool Geted { get { return geted; } }
        
        public RequestGeter(NameValueCollection form)
        {
            this.checkok = true;
            this.namevalues = form;
            this.values = new Dictionary<string, object>();
            if (!form.HasKeys())
                return;
            this.geted = true;
            this.rules = (IList<RequestGeter.Rule>)new List<RequestGeter.Rule>();
            this.messages = new List<string>();
        }

        public void AddValue(string key, object value)
        {
            key = key.ToLower();
            if (this.values.ContainsKey(key))
                return;
            this.values.Add(key, value);
        }

        public bool ValueEqual(string key, object value)
        {
            object obj = this[key];
            if (value == null && obj == null)
                return true;
            if (obj == null || value == null || Type.GetTypeCode(value.GetType()) != Type.GetTypeCode(obj.GetType()))
                return false;
            return value.Equals(obj);
        }

        public bool ValueContains(string key, object value)
        {
            object obj = this[key];
            if (value == null && obj == null)
                return true;
            if (obj == null || value == null || (!(obj is string) || !(value is string)))
                return false;
            return ((string)obj).IndexOf((string)value) == 0;
        }

        public bool ValueContains(string key, object value, object dataitem, ref object relation)
        {
            object obj = this[key];
            if (value == null && obj == null)
                return true;
            if (obj == null || value == null ||
                (!(obj is string) || !(value is string) || ((string)obj).IndexOf((string)value) != 0))
                return false;
            relation = dataitem;
            return true;
        }

        public void AddRule(RequestGeter.Rule rule)
        {
            if (this.rules == null)
                return;
            for (int index = 0; index < this.rules.Count; ++index)
            {
                if (this.rules[index].formname == rule.formname)
                {
                    this.rules.RemoveAt(index);
                    break;
                }
            }
            this.rules.Add(rule);
        }
        /// <summary>
        /// 获取错误消息
        /// </summary>
        /// <param name="single">消息数</param>
        /// <param name="separator">消息分隔符, 默认为","</param>
        /// <returns></returns>
        public string GetMessages(bool single = true, string separator = ", ")
        {
            if (this.messages == null || this.messages.Count <= 0) return string.Empty;
            return single ? this.messages[0] : string.Join(separator, this.messages.ToArray());
        }
        public bool Check()
        {
            if (!this.namevalues.HasKeys())
                return false;
            this.values.Clear();
            if (this.messages != null)
                this.messages.Clear();
            for (int index = 0; this.rules != null && index < this.rules.Count; ++index)
            {
                if (!this.RuleCheck(this.rules[index]))
                    this.checkok = false;
            }
            return this.checkok;
        }

        public void ClearValue()
        {
            this.values.Clear();
        }

        public void ClearRule()
        {
            if (this.rules == null)
                return;
            this.rules.Clear();
        }

        public void ClearAll()
        {
            if (this.values != null)
                this.values.Clear();
            if (this.rules == null)
                return;
            this.rules.Clear();
        }

        private bool RuleCheck(RequestGeter.Rule rule)
        {
            string str = this.namevalues[rule.formname];
            if (str == null)
            {
                if (rule.msg == null)
                    return true;
                this.messages.Add(rule.msg);
                return false;
            }
            bool flag1 = false;
            bool flag2;
            switch (rule.valuetype)
            {
                case TypeCode.Boolean:
                    bool result1 = false;
                    flag1 = bool.TryParse(str, out result1);
                    if (!this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)(result1 ? 1 : 0));
                    return true;
                case TypeCode.Char:
                    char result2 = char.MinValue;
                    bool flag3 = char.TryParse(str, out result2);
                    if (!flag3)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag3 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)(flag3 ? 1 : 0));
                    return true;
                case TypeCode.SByte:
                    sbyte result3 = sbyte.MinValue;
                    bool flag4 = sbyte.TryParse(str, out result3);
                    if (!flag4)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    sbyte result4 = sbyte.MinValue;
                    sbyte result5 = sbyte.MinValue;
                    if (rule.morethan != null && sbyte.TryParse(rule.morethan.ToString(), out result4) &&
                        (int)result3 < (int)result4)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && sbyte.TryParse(rule.lessthan.ToString(), out result5) &&
                        (int)result3 > (int)result5)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag4 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result3);
                    return true;
                case TypeCode.Byte:
                    byte result6 = (byte)0;
                    bool flag5 = byte.TryParse(str, out result6);
                    if (!flag5)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    byte result7 = (byte)0;
                    byte result8 = (byte)0;
                    if (rule.morethan != null && byte.TryParse(rule.morethan.ToString(), out result7) &&
                        (int)result6 < (int)result7)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && byte.TryParse(rule.lessthan.ToString(), out result8) &&
                        (int)result6 > (int)result8)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag5 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result6);
                    return true;
                case TypeCode.Int16:
                    short result9 = short.MinValue;
                    bool flag6 = short.TryParse(str, out result9);
                    if (!flag6)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    short result10 = short.MinValue;
                    short result11 = short.MinValue;
                    if (rule.morethan != null && short.TryParse(rule.morethan.ToString(), out result10) &&
                        (int)result9 < (int)result10)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && short.TryParse(rule.lessthan.ToString(), out result11) &&
                        (int)result9 > (int)result11)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag6 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result9);
                    return true;
                case TypeCode.UInt16:
                    ushort result12 = (ushort)0;
                    bool flag7 = ushort.TryParse(str, out result12);
                    if (!flag7)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    ushort result13 = (ushort)0;
                    ushort result14 = (ushort)0;
                    if (rule.morethan != null && ushort.TryParse(rule.morethan.ToString(), out result13) &&
                        (int)result12 < (int)result13)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && ushort.TryParse(rule.lessthan.ToString(), out result14) &&
                        (int)result12 > (int)result14)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag7 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result12);
                    return true;
                case TypeCode.Int32:
                    int result15 = int.MinValue;
                    bool flag8 = int.TryParse(str, out result15);
                    if (!flag8)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    int result16 = int.MinValue;
                    int result17 = int.MinValue;
                    if (rule.morethan != null && int.TryParse(rule.morethan.ToString(), out result16) &&
                        result15 < result16)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && int.TryParse(rule.lessthan.ToString(), out result17) &&
                        result15 > result17)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag8 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result15);
                    return true;
                case TypeCode.UInt32:
                    uint result18 = 0U;
                    bool flag9 = uint.TryParse(str, out result18);
                    if (!flag9)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    uint result19 = 0U;
                    uint result20 = 0U;
                    if (rule.morethan != null && uint.TryParse(rule.morethan.ToString(), out result19) &&
                        result18 < result19)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && uint.TryParse(rule.lessthan.ToString(), out result20) &&
                        result18 > result20)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag9 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result18);
                    return true;
                case TypeCode.Single:
                    float result21 = float.MinValue;
                    bool flag10 = float.TryParse(str, out result21);
                    if (!flag10)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    float result22 = float.MinValue;
                    float result23 = float.MinValue;
                    if (rule.morethan != null && float.TryParse(rule.morethan.ToString(), out result22) &&
                        (double)result21 < (double)result22)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && float.TryParse(rule.lessthan.ToString(), out result23) &&
                        (double)result21 > (double)result23)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag10 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result21);
                    return true;
                case TypeCode.Double:
                    double result24 = double.MinValue;
                    bool flag11 = double.TryParse(str, out result24);
                    if (!flag11)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    double result25 = double.MinValue;
                    double result26 = double.MinValue;
                    if (rule.morethan != null && double.TryParse(rule.morethan.ToString(), out result25) &&
                        result24 < result25)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && double.TryParse(rule.lessthan.ToString(), out result26) &&
                        result24 > result26)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag11 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result24);
                    return true;
                case TypeCode.Decimal:
                    Decimal result27 = new Decimal(-1, -1, -1, true, (byte)0);
                    bool flag12 = Decimal.TryParse(str, out result27);
                    if (!flag12)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    Decimal result28 = new Decimal(-1, -1, -1, true, (byte)0);
                    Decimal result29 = new Decimal(-1, -1, -1, true, (byte)0);
                    if (rule.morethan != null && Decimal.TryParse(rule.morethan.ToString(), out result28) &&
                        result27 < result28)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && Decimal.TryParse(rule.lessthan.ToString(), out result29) &&
                        result27 > result29)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag12 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result27);
                    return true;
                case TypeCode.DateTime:
                    DateTime result30 = DateTime.MinValue;
                    bool flag13 = DateTime.TryParse(str, out result30);
                    if (!flag13)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    flag2 = false;
                    DateTime result31 = DateTime.MinValue;
                    DateTime result32 = DateTime.MinValue;
                    if (rule.morethan != null && DateTime.TryParse(rule.morethan.ToString(), out result31) &&
                        result30 < result31)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.lessthan != null && DateTime.TryParse(rule.lessthan.ToString(), out result32) &&
                        result30 > result32)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (flag13 && !this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)result30);
                    return true;
                default:
                    if (rule.trim)
                        str = str.Trim();
                    flag2 = false;
                    int byteCount = Encoding.Default.GetByteCount(str);
                    if (rule.minlength > 0 && byteCount < rule.minlength)
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.maxlength > 0 &&
                        (byteCount > (rule.issbc ? rule.maxlength * 2 : rule.maxlength) || str.Length > rule.maxlength))
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (rule.regpattern != null && !Regex.IsMatch(str, rule.regpattern, RegexOptions.IgnoreCase))
                    {
                        if (rule.msg == null)
                            return true;
                        this.messages.Add(rule.msg);
                        return false;
                    }
                    if (!this.values.ContainsKey(rule.formname))
                        this.values.Add(rule.formname, (object)str);
                    return true;
            }
        }

        public class Rule
        {
            internal string formname;
            internal string msg;
            internal string regpattern;
            internal TypeCode valuetype;
            internal int minlength;
            internal int maxlength;
            internal bool trim;
            internal bool issbc;
            internal object morethan;
            internal object lessthan;

            public Rule(string formname, TypeCode valuetype, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = valuetype;
                this.msg = msg;
            }

            public Rule(string formname, TypeCode valuetype, object morethan, object lessthan, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = valuetype;
                this.morethan = morethan;
                this.lessthan = lessthan;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, int maxlength, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.maxlength = maxlength;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, int maxlength, bool issbc, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.maxlength = maxlength;
                this.issbc = issbc;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, int minlength, int maxlength, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.minlength = minlength;
                this.maxlength = maxlength;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, int minlength, int maxlength, bool issbc, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.minlength = minlength;
                this.maxlength = maxlength;
                this.issbc = issbc;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, string regpattern, string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.regpattern = regpattern;
                this.msg = msg;
            }

            public Rule(string formname, bool trim, int minlength, int maxlength, bool issbc, string regpattern,
                string msg)
            {
                this.formname = formname.ToLower();
                this.valuetype = TypeCode.String;
                this.trim = trim;
                this.regpattern = regpattern;
                this.minlength = minlength;
                this.maxlength = maxlength;
                this.issbc = issbc;
                this.msg = msg;
            }
        }
    }
}