using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ITC81DB_2
{
    public class Helper
    {
        /// <summary>
        /// Double형을 String형으로 변환하여 리턴(소수점 자릿수에 마춰 0을 채워서 리턴)
        /// </summary>
        /// <param name="value">Double형 데이터</param>
        /// <param name="decimalPlaces">소수점 자릿수</param>
        /// <returns>String형 데이터</returns>
        public static string DoubleToString(double value, int decimalPlaces)
        {
            if (decimalPlaces == 0)
                return string.Format("{0:F0}", value);
            else if (decimalPlaces == 1)
                return string.Format("{0:F1}", value);
            else if (decimalPlaces == 2)
                return string.Format("{0:F2}", value);
            else if (decimalPlaces == 3)
                return string.Format("{0:F3}", value);
            else if (decimalPlaces == 4)
                return string.Format("{0:F4}", value);
            else if (decimalPlaces == 5)
                return string.Format("{0:F5}", value);
            else if (decimalPlaces == 6)
                return string.Format("{0:F6}", value);
            else if (decimalPlaces == 7)
                return string.Format("{0:F7}", value);
            else
                return "0";
        }

        /// <summary>
        /// 소수점 없는 String 값을 소수점 추가 후 String 값으로 리턴
        /// </summary>
        /// <param name="value">소수점이 없는 값</param>
        /// <param name="decimalPlaces">소수점 자릿수</param>
        /// <returns>소수점 자리 추가 데이터</returns>
        public static string StringToDecimalPlaces(string value, int decimalPlaces)
        {
            string ret = "";
            double dValue = 0.0;

            dValue = StringToWeight(value, decimalPlaces);
            ret = DoubleToString(dValue, decimalPlaces);

            return ret;
        }

        /// <summary>
        /// 소수점 없는 String형 값을 소수점 추가후 Double형으로 리턴(부호가 포함된 String형값)
        /// </summary>
        /// <param name="value">소수점이 없는 값</param>
        /// <param name="decimalPlaces">소수점 자릿수</param>
        /// <returns>Double형 소수점 추가 데이터</returns>
        public static double StringToWeight(string value, int decimalPlaces)
        {
            double dValue = 0.0;
            string str = "", code = "";
            StringBuilder sb = new StringBuilder();
            sb.Append(value);

            try
            {
                if (sb.Length > 7)
                    return 0.0;
                if (sb[0] == '-')
                {
                    code = "-";
                    sb.Remove(0, 1);
                }

                str = sb.ToString();
                str = str.Trim();
                sb.Remove(0, sb.Length);
                sb.Append(str);

                for (int i = 0; i < decimalPlaces; i++)
                {
                    if (sb.Length > decimalPlaces)
                        break;

                    sb.Insert(0, "0");
                }

                sb.Insert(sb.Length - decimalPlaces, ".");
                str = sb.ToString();
                str = code + str;
                dValue = double.Parse(str);

                return dValue;

            }
            catch
            {
                return 0.0;
            }
        }

        /// <summary>
        /// 통신으로 받은 중량 값(소수점 미포함)을 소수점 자리수에 마추어 찍어주는 함수
        /// </summary>
        /// <param name="value"></param>
        /// <param name="decimalPlaces"></param>
        /// <returns></returns>
        public static string CommunicationWeightValueToString(string value, int decimalPlaces)
        {
            string sValue = "";
            double dValue = 0.0;

            dValue = Helper.StringToWeight(value, decimalPlaces);
            sValue = Helper.DoubleToString(dValue, decimalPlaces);

            return sValue;
        }

        public static Define.E_JudgmentStatus StringToJudgmentStatus(string value)
        {
            if (value.Length != 2)
                return Define.E_JudgmentStatus.Empty;

            if (value == "su")
                return Define.E_JudgmentStatus.Under;
            else if (value == "so")
                return Define.E_JudgmentStatus.Over;
            else if (value == "sp")
                return Define.E_JudgmentStatus.Pass;
            else if (value == "sd" || value == "sD")
                return Define.E_JudgmentStatus.Double;
            else if (value == "sm")
                return Define.E_JudgmentStatus.Metal;
            else if (value == "se")
                return Define.E_JudgmentStatus.ExNg;
            else
                return Define.E_JudgmentStatus.Empty;
        }
        public static Define.E_WeightStatus StringToWeightStatus(string value)
        {
            if (value.Length != 2)
                return Define.E_WeightStatus.Empty;

            if (value == "sn")
                return Define.E_WeightStatus.WeightChange;
            else if (value == "sz")
                return Define.E_WeightStatus.WeightZero;
            else if (value == "cn")
                return Define.E_WeightStatus.CalNomal;
            else if (value == "cB")
                return Define.E_WeightStatus.CalBalans;
            else if (value == "cb")
                return Define.E_WeightStatus.CalStandby;
            else if (value == "cF")
                return Define.E_WeightStatus.CalFinish;
            else if (value == "ce")
                return Define.E_WeightStatus.CalError;
            else
                return Define.E_WeightStatus.Empty;
        }

        /// <summary>
        /// 2자리에 마춰 공백을 0으로 채움
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string StringZeroFillDigits2(string value)
        {
            if (value.Length == 1)
                return string.Format("0{0}", value);
            else if (value.Length == 2)
                return value;
            else
                return "00";
        }
        /// <summary>
        /// 4자리에 마춰 공백을 0으로 채움
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string StringZeroFillDigits4(string value)
        {
            if (value.Length == 1)
                return string.Format("000{0}", value);
            else if (value.Length == 2)
                return string.Format("00{0}", value);
            else if (value.Length == 3)
                return string.Format("0{0}", value);
            else if (value.Length == 4)
                return value;
            else
                return "0000";
        }
        /// <summary>
        /// 5자리에 마춰 공백을 0으로 채움
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string StringZeroFillDigits5(string value)
        {
            if (value.Length == 1)
                return string.Format("0000{0}", value);
            else if (value.Length == 2)
                return string.Format("000{0}", value);
            else if (value.Length == 3)
                return string.Format("00{0}", value);
            else if (value.Length == 4)
                return string.Format("0{0}", value);
            else if (value.Length == 5)
                return value;
            else
                return "00000";
        }
        /// <summary>
        /// 6자리에 마춰 공백을 0으로 채움
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string StringZeroFillDigits6(string value)
        {
            if (value.Length == 1)
                return string.Format("00000{0}", value);
            else if (value.Length == 2)
                return string.Format("0000{0}", value);
            else if (value.Length == 3)
                return string.Format("000{0}", value);
            else if (value.Length == 4)
                return string.Format("00{0}", value);
            else if (value.Length == 5)
                return string.Format("0{0}", value);
            else if (value.Length == 6)
                return value;
            else
                return "000000";
        }
        /// <summary>
        /// 7자리에 마춰 공백을 0으로 채움
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string StringZeroFillDigits7(string value)
        {
            if (value.Length == 1)
                return string.Format("000000{0}", value);
            else if (value.Length == 2)
                return string.Format("00000{0}", value);
            else if (value.Length == 3)
                return string.Format("0000{0}", value);
            else if (value.Length == 4)
                return string.Format("000{0}", value);
            else if (value.Length == 5)
                return string.Format("00{0}", value);
            else if (value.Length == 6)
                return string.Format("0{0}", value);
            else if (value.Length == 7)
                return value;
            else
                return "0000000";
        }


        /// <summary>
        /// 16진수를 10진수로 변환(String to String)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string HexToDec(string value)
        {
            return Convert.ToInt64(value, 16).ToString();
        }

        /// <summary>
        /// 16진수를 2진수로 변환(String to String)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string HexToBin(string value)
        {
            return Convert.ToString(Convert.ToInt64(value, 16), 2);
        }

        /// <summary>
        /// 10진수를 2진수로 변환(String to String)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DecToBin(string value)
        {
            return Convert.ToString(Convert.ToInt64(value), 2);
        }

        /// <summary>
        /// 2진수를 10진수로 변환(String to String)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string BinToDec(string value)
        {
            return Convert.ToInt64(value, 2).ToString();
        }

        /// <summary>
        /// 2진수를 16진수로 변환(String to String)
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string BinToHex(string value)
        {
            return Convert.ToString(Convert.ToInt32(value, 2), 16);
        }

        /// <summary>
        /// string(255 이하의 숫자 string)을 16진수로 변환하는 방법
        /// </summary>
        /// <param name="value">1자리 string</param>
        /// <returns></returns>
        public static byte StringToHex(string value)
        {
            try
            {
                int iValue = int.Parse(value);

                if (0 <= iValue && iValue < 256)
                {
                    string temp = iValue.ToString("X");
                    return Convert.ToByte(temp, 16);
                }
                else
                    return 0x00;
            }
            catch
            {
                return 0x00;
            }
        }
        public static string StringToHexString(string strData)
        {
            string resultHex = string.Empty;
            byte[] arr_byteStr = Encoding.Default.GetBytes(strData);

            foreach (byte byteStr in arr_byteStr)
                resultHex += string.Format("{0:X2}", byteStr);

            return resultHex;
        }
        public static string ByteToHexString(byte[] array)
        {
            string resultHex = "";

            foreach (byte byteStr in array)
                resultHex += string.Format("{0:X2}", byteStr);

            return resultHex;
        }

        /// <summary>
        /// Remove Folder로 이동
        /// </summary>
        /// <param name="directory">Remove Folder로 이동할 폴더</param>
        public static void MoveToRemoveFolder(string directory)
        {
            bool removeFolderCheck = false;
            string currentFolderPath = "", removeFolderPath = "";

            currentFolderPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\";
            if (currentFolderPath.StartsWith("\\F") == true)
                removeFolderPath = "Flash Disk\\RemoveFile\\";
            else
                removeFolderPath = "SD Card\\RemoveFile\\";

            FileInfo[] oldFiles;
            DirectoryInfo[] oldDirectory;
            DirectoryInfo dirOldFolder = new DirectoryInfo(directory);
            DirectoryInfo dirFolderRemove = new DirectoryInfo(removeFolderPath);

            removeFolderCheck = dirFolderRemove.Exists;
            if (removeFolderCheck == false)
                dirFolderRemove.Create();

            oldDirectory = dirOldFolder.GetDirectories();

            foreach (DirectoryInfo subDirectory in oldDirectory)
            {
                oldFiles = subDirectory.GetFiles();
                foreach (FileInfo subFile in oldFiles)
                    subFile.MoveTo(removeFolderPath + DateTime.Now.ToString("yyyyMMddHHmmss") + subFile.Name.ToString());
            }
        }
        /// <summary>
        /// 폴더 복사
        /// </summary>
        /// <param name="departure">복사 출발점 폴더</param>
        /// <param name="destination">복사 도착점 폴더</param>
        public static void CopyToFolder(string departure, string destination)
        {
            DirectoryInfo dirDestinationFolder = new DirectoryInfo(destination);
            if (dirDestinationFolder.Exists == false)
                dirDestinationFolder.Create();

            DirectoryInfo dirDepartureFolder = new DirectoryInfo(departure);
            if (dirDepartureFolder.Exists == false)
                dirDepartureFolder.Create();

            FileInfo[] newFiles = dirDepartureFolder.GetFiles();

            foreach (FileInfo subFile in newFiles)
                subFile.CopyTo(destination + subFile.Name.ToString(), true);
        }
        /// <summary>
        /// 폴더 이동
        /// </summary>
        /// <param name="departure">복사 출발점 폴더</param>
        /// <param name="destination">복사 도착점 폴더</param>
        public static void MoveToFolder(string departure, string destination)
        {
            DirectoryInfo dirDestinationFolder = new DirectoryInfo(destination);
            if (dirDestinationFolder.Exists == false)
                dirDestinationFolder.Create();
            else
            {
                dirDestinationFolder.Delete(true);
                dirDestinationFolder.Create();
            }

            DirectoryInfo dirDepartureFolder = new DirectoryInfo(departure);
            if (dirDepartureFolder.Exists == false)
                dirDepartureFolder.Create();

            FileInfo[] newFiles = dirDepartureFolder.GetFiles();

            foreach (FileInfo subFile in newFiles)
                subFile.MoveTo(destination + subFile.Name.ToString());
        }

        public static byte ChecksumCalculator(byte[] array)
        {
            byte checksum = 0x00;

            for (int i = 0; i < array.Length; i++)
            {
                checksum = (byte)(checksum ^ array[i]);
            }

            return checksum;
        }
    }

    public static class FindByNameUtil
    {
        public static T FindByName<T>(this object targetClass, string name) where T : class
        {
            System.Reflection.FieldInfo fi = targetClass.GetType().GetField(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            return fi.GetValue(targetClass) as T;
        }
        public static T FindByName<T>(this string name, object targetClass) where T : class
        {
            System.Reflection.FieldInfo fi = targetClass.GetType().GetField(name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
            return fi.GetValue(targetClass) as T;
        }
        public static System.Windows.Forms.Label Is_Label_From(this string name, object targetClass)
        {
            return FindByName<System.Windows.Forms.Label>(targetClass, name);
        }
        public static System.Windows.Forms.TextBox Is_TextBox_From(this string name, object targetClass)
        {
            return FindByName<System.Windows.Forms.TextBox>(targetClass, name);
        }
        public static System.Windows.Forms.TextBox TextBox(string name, object targetClass)
        {
            return FindByName<System.Windows.Forms.TextBox>(targetClass, name);
        }
        public static System.Windows.Forms.Label Label(string name, object targetClass)
        {
            return FindByName<System.Windows.Forms.Label>(targetClass, name);
        }
        public static System.Windows.Forms.PictureBox PictureBox(string name, object targetClass)
        {
            return FindByName<System.Windows.Forms.PictureBox>(targetClass, name);
        }

        public static SmartX.SmartLabel SmartLabel(string name, object targetClass)
        {
            return FindByName<SmartX.SmartLabel>(targetClass, name);
        }
        public static SmartX.SmartProgressBar SmartProgressBar(string name, object targetClass)
        {
            return FindByName<SmartX.SmartProgressBar>(targetClass, name);
        }
        public static SmartX.SmartButton SmartButton(string name, object targetClass)
        {
            return FindByName<SmartX.SmartButton>(targetClass, name);
        }
        public static SmartX.SmartDraw SmartDraw(string name, object targetClass)
        {
            return FindByName<SmartX.SmartDraw>(targetClass, name);
        }
        public static SmartX.SmartListBox SmartListBox(string name, object targetClass)
        {
            return FindByName<SmartX.SmartListBox>(targetClass, name);
        }
    }
}
