using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;

namespace EQNetwork.Utility
{
    public class EQParse
    {
        public static int? IntOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return int.Parse(str);
        }

        public static int IntOrZero(object obj)
        {
            if (obj == null)
                return 0;
            string str = obj.ToString();
            if (str.Length == 0)
                return 0;
            return int.Parse(str);
        }

        public static long? LongOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return long.Parse(str);
        }

        public static long LongOrZero(object obj)
        {
            if (obj == null)
                return 0;
            string str = obj.ToString();
            if (str.Length == 0)
                return 0;
            return long.Parse(str);
        }

        public static float? FloatOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return float.Parse(str);
        }

        public static float FloatOrZero(object obj)
        {
            if (obj == null)
                return 0;
            string str = obj.ToString();
            if (str.Length == 0)
                return 0;
            return float.Parse(str);
        }

        public static bool Bool(string str)
        {
            if (str == "1") return true;
            if (str.ToLower().StartsWith("y")) return true;
            if (str.ToLower().StartsWith("t")) return true;
            return false;
        }

        public static bool? BoolOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return bool.Parse(str);
        }

        public static bool BoolOrFalse(object obj)
        {
            if (obj == null)
                return false;
            string str = obj.ToString();
            if (str.Length == 0)
                return false;
            return bool.Parse(str);
        }

        public static DateTime? DateTimeOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return DateTime.Parse(str);
        }

        public static DateTime DateTimeOrMinVal(object obj)
        {
            if (obj == null)
                return DateTime.MinValue;
            string str = obj.ToString();
            if (str.Length == 0)
                return DateTime.MinValue;
            return DateTime.Parse(str);
        }

        public static Guid? GuidOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return new Guid(str);
        }

        public static Guid GuidOrEmpty(object obj)
        {
            if (obj == null)
                return Guid.Empty;
            string str = obj.ToString();
            if (str.Length == 0)
                return Guid.Empty;
            return new Guid(str);
        }

        public static TimeSpan? TimeSpanOrNull(object obj)
        {
            if (obj == null)
                return null;
            string str = obj.ToString();
            if (str.Length == 0)
                return null;
            return TimeSpan.FromSeconds(double.Parse(str));
        }

        public static TimeSpan TimeSpanOrZero(object obj)
        {
            if (obj == null)
                return TimeSpan.FromSeconds(0);
            string str = obj.ToString();
            if (str.Length == 0)
                return TimeSpan.FromSeconds(0);
            return TimeSpan.FromSeconds(double.Parse(str));
        }

        public static List<int> IntList(object obj)
        {
            List<int> list = new List<int>();
            if (obj != null)
            {
                string[] arr = obj.ToString().Split(',');
                foreach (string str in arr)
                    if (!string.IsNullOrEmpty(str))
                        list.Add(int.Parse(str));
            }
            return list;
        }

        public static void SetPropertiesWithXmlAttributes(object obj, XmlNode node)
        {
            Dictionary<string, PropertyInfo> dict = new Dictionary<string, PropertyInfo>(StringComparer.OrdinalIgnoreCase);
            var props = obj.GetType().GetProperties();
            foreach (var prop in props)
                dict.Add(prop.Name, prop);
    
            foreach (XmlAttribute attr in node.Attributes)
            {
                if (dict.ContainsKey(attr.Name))
                {
                    var prop = dict[attr.Name];
                    Type type = prop.PropertyType;
                    if (type == typeof(string))
                        prop.SetValue(obj, attr.Value, null);
                    else if (type == typeof(int?))
                        prop.SetValue(obj, EQParse.IntOrNull(attr.Value), null);
                    else if (type == typeof(int))
                        prop.SetValue(obj, EQParse.IntOrZero(attr.Value), null);
                    else if (type == typeof(long?))
                        prop.SetValue(obj, EQParse.LongOrNull(attr.Value), null);
                    else if (type == typeof(long))
                        prop.SetValue(obj, EQParse.LongOrZero(attr.Value), null);
                    else if (type == typeof(float?))
                        prop.SetValue(obj, EQParse.FloatOrNull(attr.Value), null);
                    else if (type == typeof(float))
                        prop.SetValue(obj, EQParse.FloatOrZero(attr.Value), null);
                    else if (type == typeof(bool?))
                        prop.SetValue(obj, EQParse.BoolOrNull(attr.Value), null);
                    else if (type == typeof(bool))
                        prop.SetValue(obj, EQParse.BoolOrFalse(attr.Value), null);
                    else if (type == typeof(DateTime?))
                        prop.SetValue(obj, EQParse.DateTimeOrNull(attr.Value), null);
                    else if (type == typeof(DateTime))
                        prop.SetValue(obj, EQParse.DateTimeOrMinVal(attr.Value), null);
                    else if (type == typeof(Guid?))
                        prop.SetValue(obj, EQParse.GuidOrNull(attr.Value), null);
                    else if (type == typeof(Guid))
                        prop.SetValue(obj, EQParse.GuidOrEmpty(attr.Value), null);
                    else if (type == typeof(TimeSpan?))
                        prop.SetValue(obj, EQParse.TimeSpanOrNull(attr.Value), null);
                    else if (type == typeof(TimeSpan?))
                        prop.SetValue(obj, EQParse.TimeSpanOrZero(attr.Value), null);
                    else
                        Console.WriteLine("Attribute '" + attr.Name + "' property (" + type.Name + ") unable to set in object " + obj.GetType().Name);
                }
                else
                    Console.WriteLine("Attribute '" + attr.Name + "' property (" + attr.Value + ") not found in object " + obj.GetType().Name);
            }
        }
    }
}
