using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Linq;
using System.Reflection;

namespace Northwind.DAL.Common {

    /// <summary>
    /// 数据验证类
    /// </summary>
    /// <remarks>
    /// 维护人：zhaoshunlu
    /// 最后修改：2013-11-4
    /// </remarks>
    public class DataValidator {
      
        /// <summary>
        /// 获取安全的字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetSafeSqueryString(string str) {
            if (string.IsNullOrEmpty(str))
                return "";
            else
                return str.Trim().Replace(" ", "").Replace("'", "").Replace("%", "").Replace("--", "").Replace("or", "");
        }
        /// <summary>
        /// 日期格式验证 如：2013-06-01
        /// </summary>
        /// <param name="input"></param>
        /// <returns>bool</returns>
        /// <remarks>
        /// zhao 2013-11-01
        /// </remarks>
        public static bool IsDate(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input,
             @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]" +
@"|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|" +
@"1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?" +
@"2-(0?[1-9]|1\d|2[0-9]))|(((1[6-9]|[2-9]\d)(0[48]|[2468]" +
@"[048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$");

        }
        /// <summary>  
        /// 是否为时间型字符串  
        /// </summary>  
        /// <param name="source">时间字符串(15:00:00)</param>  
        /// <returns></returns>  
        public static bool IsTime(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, @"^((20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d)$");
        }

        /// <summary>  
        /// 是否为日期+时间型字符串  
        /// </summary>  
        /// <param name="source"></param>  
        /// <returns></returns>  
        public static bool IsDateTime(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input,
@"^(((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?" +
@"[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?" +
@"[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]" +
@"|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-" +
@"9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[" +
@"2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23" +
@"|[0-1]?\d):[0-5]?\d:[0-5]?\d)$ ");
        }

        /// <summary>
        /// 实数验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDecimal(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, "^[0-9]+[.]?[0-9]+$");
        }

        /// <summary>
        /// 带符号的实数验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsDecimalSign(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, "^[+-]?[0-9]+[.]?[0-9]+$");
        }

        /// <summary>
        /// 正整数验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNumber(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, "^[0-9]+$");
        }

        /// <summary>
        /// 整数验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsNumberSign(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, "^[+-]?[0-9]+$");
        }

        /// <summary>
        /// 邮编验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsPostCode(string input) {
            return (IsNumber(input) && (input.Length == 6));
        }

        /// <summary>
        /// 邮箱地址格式验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsEmail(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, @"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$");
        }

        /// <summary>
        /// IP地址验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsIP(string input) {
            return (!string.IsNullOrEmpty(input) && Regex.IsMatch(input.Trim(), @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$"));
        }

        /// <summary>
        /// URL验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsUrl(string input) {
            if (string.IsNullOrEmpty(input)) {
                return false;
            }
            return Regex.IsMatch(input, @"^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$");
        }

        /// <summary>
        /// 区号验证
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static bool IsAreaCode(string input) {
            return ((IsNumber(input) && (input.Length >= 3)) && (input.Length <= 5));
        }

        /// <summary>
        /// 用户名格式验证,长度[0,20],不能含有\\/\"[]:|<>+=;,?*@
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool IsValidUserName(string userName) {
            if (string.IsNullOrEmpty(userName)) {
                return false;
            }
            if (userName.Length > 20) {
                return false;
            }
            if (userName.Trim().Length == 0) {
                return false;
            }
            if (userName.Trim(new char[] { '.' }).Length == 0) {
                return false;
            }
            string str = "\\/\"[]:|<>+=;,?*@";
            for (int i = 0; i < userName.Length; i++) {
                if (str.IndexOf(userName[i]) >= 0) {
                    return false;
                }
            }
            return true;
        }
		
		
        /// <summary>
        /// 比较同一类型的两个对象实例的属性值有哪些不同
        /// </summary>
        /// <param name="oldModel">旧对象</param>
        /// <param name="newModel">新对象</param>
        /// <param name="AllKeys">特别指定需要比较的属性键集合,如果为null或者长度为0那么就比较所有属性，默认为null</param>
        /// <param name="FilterKeys">特别指定需要排除的属性键集合,默认为null</param>     
        /// <returns>返回不同的属性名称及两者内容 键值对</returns>
        /// <remarks>
        /// 创建：zhaoshunlu 日期：2014-10-11
        /// </remarks>
        /// <value>Hashtable</value>
        public static string[] UpdateDifferent<T>(T oldModel, T newModel, string[] CheckKeys = null, string[] FilterKeys = null)
        {
            //
           IList<string> names = new  List<string>();
            //
            Type type = typeof(T);
            //初始化属性组
            PropertyInfo[] props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
            //遍历属性比较(要是一个一个属性比较真心累)
            for (int i = 0; i < props.Length; i++)
            {
                //只处理在指定集合中的属性
                if (CheckKeys == null || (CheckKeys != null && CheckKeys.Length == 0) || CheckKeys.Contains(props[i].Name))
                {
                    // 
                    //跳过排除的项
                    if (!(FilterKeys != null && FilterKeys.Contains(props[i].Name)))
                    {
                        //跳过 Ilist~1 等集合属性
                        if (props[i].PropertyType.Name != "IList`1")
                        {
                            //
                            object oldfd = props[i].GetValue(oldModel, null);
                            object newfd = props[i].GetValue(newModel, null);
                            
                            //判断新旧值是否相同
                            if (oldfd != null && newfd != null && !oldfd.Equals(newfd))
                            {
                                props[i].SetValue(oldModel, newfd,null);
                                //计数
                                names.Add(props[i].Name);
                            }
                        }
                    }

                }
            }
            //
            return names.ToArray();
        }
    }
}