using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Web;
using System.Data;
using System.IO;
using System.Security.Cryptography;
using System.Globalization;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace SFI.COMM.LIB
{
    public static class Converts
    { 
        #region General Converts
        public static DateTime ConvertToDateTime(string Value_)
        {
            try
            {
                return DateTime.ParseExact(Value_, "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
            }
            catch
            {
                return DateTime.Now;
            }
        }
        public static DateTime ToDateTime(this object Value_)
        {
            return Converts.ConvertToDateTime(Convert.ToString(Value_));
        }

        public static decimal ConvertToDecimal(object Value_)
        {
            decimal x = 0;
            try
            {
                //x = Convert.ToDecimal(Value_, System.Globalization.NumberFormatInfo.CurrentInfo);
                x = decimal.Parse(Convert.ToString(Value_), new NumberFormatInfo() { NumberDecimalSeparator = "," });
            }
            catch
            {
                try
                {
                    string[] Sayi = Value_.ToString().Split('T');

                    //x = Convert.ToDecimal(Sayi[0]);
                    x = decimal.Parse(Convert.ToString(Sayi[0]), new NumberFormatInfo() { NumberDecimalSeparator = "," });

                }
                catch { }
            }
            return x;
        }
        public static decimal ToDecimal(this object Value_)
        {
            return Converts.ConvertToDecimal(Value_);
        }

        public static bool ToBool(this object Value_)
        {
            bool x = false;
            try
            {
                x = Convert.ToBoolean(Value_);
            }
            catch
            {
                x = false;
            }
            return x;
        }
        public static bool ToBool(this int Value_)
        {
            bool x = false;
            if (Value_ == 1) x = true;
            if (Value_ == 0) x = false;
            return x;
        }

        public static float ToFloat(this object Value_)
        {
            Int64 x = 0;

            try
            {
                x = Convert.ToInt64(Value_);

            }
            catch { }

            return x;
        }
        public static double ToDouble(this object Deger)
        {
            double x = 0;

            try
            {
                x = Convert.ToDouble(Deger, System.Globalization.NumberFormatInfo.CurrentInfo);

            }
            catch { }

            return x;
        }

        public static Int64 ToInt64(this object Value_)
        {
            if (string.IsNullOrEmpty(Value_.ToString())) return 0;
            if (Value_ == null) return 0;

            Int64 x = 0;
            try
            {
                x = Convert.ToInt64(Value_, System.Globalization.NumberFormatInfo.CurrentInfo);
            }
            catch { }
            return x;
        }
        public static int ToInt(this object Value_)
        {
            Int32 x = 0;
            try
            {
                x = Convert.ToInt32(Value_, System.Globalization.NumberFormatInfo.CurrentInfo);
            }
            catch { }
            return x;
        }

         
        public static string ToAjaxTurkishReplace(this string Value_)
        {
            Value_ = Value_.Replace("&#220;", "Ü");
            Value_ = Value_.Replace("&#199;", "Ç");
            Value_ = Value_.Replace("&#214;", "Ö");
            Value_ = Value_.Replace("Å&#158;", "Ş");
            Value_ = Value_.Replace("Ä&#158;", "Ğ");
            Value_ = Value_.Replace("&#252;", "ü");
            Value_ = Value_.Replace("&#246;", "ö");
            Value_ = Value_.Replace("&#231;", "ç");
            Value_ = Value_.Replace("&nVTAp;", "");
            Value_ = Value_.Replace("Ãœ", "Ü");
            Value_ = Value_.Replace("Ã‡", "Ç");
            Value_ = Value_.Replace("Ä°", "İ");
            Value_ = Value_.Replace("Ã–", "Ö");
            Value_ = Value_.Replace("Ã¼", "ü");
            Value_ = Value_.Replace("ÅŸ", "ş");
            Value_ = Value_.Replace("Ã§", "ç");
            Value_ = Value_.Replace("Ä±", "ı");
            Value_ = Value_.Replace("Ã¶", "ö");
            Value_ = Value_.Replace("ÄŸ", "ğ");
            return Value_;
        }
        public static string ToMD5Code(this string Value_)
        {
            MD5CryptoServiceProvider Kod = new MD5CryptoServiceProvider();
            HashAlgorithm alg = Kod;
            byte[] byteDegeri = System.Text.Encoding.UTF8.GetBytes(Value_);
            byte[] sifreliByte = alg.ComputeHash(byteDegeri);
            return Convert.ToBase64String(sifreliByte);
        }
        
        #endregion
         
        #region Object Returns

        public static T ObjectValue<T>(this object Value_, T DefaultValue_) where T : struct
        {
            if (Value_ == null || Convert.ToString(Value_) == string.Empty)
                return Inheritance.GetValue<T>(DefaultValue_.ToString());
            return Inheritance.GetValue<T>(Value_.ToString());
        }
        public static T ObjectValue<T>(this object Value_) where T : struct
        {
            if (Value_ == null || Convert.ToString(Value_) == string.Empty)
                return Inheritance.GetValue<T>(string.Empty);
            return Inheritance.GetValue<T>(Value_.ToString());
        }

        public static string ObjectValue(this object Value_, string DefaultValue_)
        {
            if (Value_ == null || Convert.ToString(Value_) == string.Empty)
                return DefaultValue_.ToString();
            return Value_.ToString();
        }
        public static string ObjectValue(this object Value_)
        {
            if (Value_ == null || Convert.ToString(Value_) == string.Empty)
                return string.Empty;
            return Convert.ToString(Value_);
        }

        public static T ObjectValue<T>(this DataRow DataRow_, string FieldName_, T DefaultValue_) where T : struct
        {
            if (!DataRow_.Table.Columns.Contains(FieldName_))
            {
                return DefaultValue_;
            }
            if (DataRow_[FieldName_] == null || DataRow_[FieldName_].ToString() == "")
                return Inheritance.GetValue<T>(DefaultValue_.ToString());
            return Inheritance.GetValue<T>(DataRow_[FieldName_].ToString());
        }
        public static T ObjectValue<T>(this DataRow DataRow_, string FieldName_) where T : struct
        {
            if (!DataRow_.Table.Columns.Contains(FieldName_))
                return Inheritance.GetValue<T>(string.Empty);

            if (DataRow_[FieldName_] == null || DataRow_[FieldName_].ToString() == string.Empty)
                return Inheritance.GetValue<T>(string.Empty);

            return Inheritance.GetValue<T>(DataRow_[FieldName_].ToString());
        }

        public static string ObjectValue(this System.Data.DataRow DataRow_, string FieldName_, string DefaultValue_)
        {
            if (!DataRow_.Table.Columns.Contains(FieldName_))
            {
                return DefaultValue_;
            }
            if (DataRow_[FieldName_] == null || DataRow_[FieldName_].ToString() == "")
                return DefaultValue_.ToString();
            return DataRow_[FieldName_].ToString();
        }
        public static string ObjectValue(this System.Data.DataRow DataRow_, string FieldName_)
        {
            if (!DataRow_.Table.Columns.Contains(FieldName_))
                return string.Empty;
            if (DataRow_[FieldName_] == null || DataRow_[FieldName_].ToString() == string.Empty)
                return string.Empty;
            if (DataRow_.Table.Columns[FieldName_].DataType == typeof(Decimal))
                return Convert.ToString(DataRow_[FieldName_]).Replace(".", ",");
            else
                return Convert.ToString(DataRow_[FieldName_]);
        }

        public static T ObjectValue<T>(System.Data.DataTable DataTable_, int RowIndex_, string FieldName_, T DefaultValue_) where T : struct
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return Inheritance.GetValue<T>(DataTable_.Rows[RowIndex_][FieldName_].ToString());
            else
                return DefaultValue_;
        }
        public static T ObjectValue<T>(System.Data.DataTable DataTable_, int RowIndex_, string FieldName_) where T : struct
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return Inheritance.GetValue<T>(DataTable_.Rows[RowIndex_][FieldName_].ToString());
            else
                return Inheritance.GetValue<T>(string.Empty);
        }

        public static string ObjectValue(System.Data.DataTable DataTable_, int RowIndex_, string FieldName_, string DefaultValue_)
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return DataTable_.Rows[RowIndex_][FieldName_].ToString();
            else
                return DefaultValue_;
        }
        public static string ObjectValue(System.Data.DataTable DataTable_, int RowIndex_, string FieldName_)
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return DataTable_.Rows[RowIndex_][FieldName_].ToString();
            else
                return string.Empty;
        }

        public static T ObjectValue<T>(System.Data.DataTable DataTable_, string FieldName_, T DefaultValue_) where T : struct
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return Inheritance.GetValue<T>(DataTable_.Rows[0][FieldName_].ToString());
            else
                return DefaultValue_;
        }
        public static T ObjectValue<T>(System.Data.DataTable DataTable_, string FieldName_) where T : struct
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return Inheritance.GetValue<T>(DataTable_.Rows[0][FieldName_].ToString());
            else
                return Inheritance.GetValue<T>(string.Empty);
        }

        public static string ObjectValue(System.Data.DataTable DataTable_, string FieldName_, string DefaultValue_)
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return DataTable_.Rows[0][FieldName_].ToString();
            else
                return DefaultValue_;
        }
        public static string ObjectValue(System.Data.DataTable DataTable_, string FieldName_)
        {
            if (DataTable_ != null && DataTable_.Rows.Count > 0 && DataTable_.Columns.Contains(FieldName_))
                return DataTable_.Rows[0][FieldName_].ToString();
            else
                return string.Empty;
        }



        #endregion
 

        public static T ToEnum<T>(this string value)
        {
            return (T)Enum.Parse(typeof(T), value, true);
        }

        public static T Clone<T>(T source)
        {
            if (!typeof(T).IsSerializable)
            {
                throw new ArgumentException("The type must be serializable.", nameof(source));
            }

            // Don't serialize a null object, simply return the default for that object
            if (Object.ReferenceEquals(source, null))
            {
                return default(T);
            }

            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();
            using (stream)
            {
                formatter.Serialize(stream, source);
                stream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(stream);
            }
        }

        public static byte[] ToByteArray(this Stream @this)
        {
            using (var ms = new MemoryStream())
            {
                @this.CopyTo(ms);
                return ms.ToArray();
            }
        }
    }
}
