using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.IO;
using System.Text;
using System.Windows.Forms;

using SmartX;
using ITC81DB_0H.Forms;
using ITC81DB_0H.DialogForms;
using ITC81DB_2H_ImageDll;
using ITC81DB_2H.Datastore;

namespace ITC81DB_0H.Controls
{
    public partial class ControlCenterEquipUpdate : UserControl
    {
        #region Field
        private FormMenu m_ParentForm;
        private Define.E_Step3 UpdateStep;

        private int Check;

        private string USBPath = "";
        private string UpdateFilePath = "";
        private string OldFilePath = "";
        private string RemoveFolderPath = "";

        private List<string> DllName = new List<string>();
        private List<long> LongOldDllFileLastWriteTime = new List<long>();
        private List<long> LongNewDllFileLastWriteTime = new List<long>();
        #endregion

        #region Constructor
        public ControlCenterEquipUpdate(FormMenu parent)
        {
            InitializeComponent();

            this.ParentForm = parent;

            this.InitializeDesign();
            this.DefaultSetting();
        }
        #endregion

        #region Property
        public FormMenu ParentForm
        {
            get { return this.m_ParentForm; }
            private set { this.m_ParentForm = value; }
        }
        #endregion

        #region Method
        public void InitializeDesign()
        {
            Class1 images = new Class1();

            if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.English)
            {
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Chinese)
            {
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Czech)
            {
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Russian)
            {
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.German)
            {
            }
            else
            {
            }
        }
        private void DefaultSetting()
        {
            this.UpdateStep = Define.E_Step3.Step1;
            this.UpdateLabelStatus(this.UpdateStep, this.ParentForm.ParentForm.SystemConfig1.Language);
        }

        private Define.E_UpdateCheck CheckError()
        {
            Define.E_UpdateCheck ret = Define.E_UpdateCheck.Fail;
            FileInfo[] newFiles;

            if (Directory.Exists("Hard Disk\\") == true)
                this.USBPath = "Hard Disk\\";
            else if (Directory.Exists("하드 디스크\\") == true)
                this.USBPath = "하드 디스크\\";
            else
                this.USBPath = "하드 디스크\\";

            this.UpdateFilePath = this.USBPath + "UpdateFiles\\";

            DirectoryInfo info = new DirectoryInfo(this.USBPath);
            DirectoryInfo directoryFolderUpdateFiles = new DirectoryInfo(this.UpdateFilePath);

            // USB 장착 유무 확인
            if (info.Exists == true)
            {
                // USB에 UpdateFiles 유무 확인
                if (directoryFolderUpdateFiles.Exists == true)
                {
                    newFiles = directoryFolderUpdateFiles.GetFiles();

                    if (newFiles.Length == 0)
                    {
                        ret = Define.E_UpdateCheck.NotFile;
                    }
                    else
                    {
                        ret = Define.E_UpdateCheck.Success;
                    }
                }
                else
                {
                    ret = Define.E_UpdateCheck.NotUpdateFolder;
                }
            }
            else
            {
                ret = Define.E_UpdateCheck.NotUsbMomery;
            }

            return ret;
        }
        private void CheckErrorMainBoard(DialogResult result)
        {
            FileInfo[] newFiles;
            bool isUpdateFile = false;
            string fileName = "";

            if (result == DialogResult.Yes)
            {
                if (Directory.Exists("Hard Disk\\") == true)
                    this.USBPath = "Hard Disk\\";
                else if (Directory.Exists("하드 디스크\\") == true)
                    this.USBPath = "하드 디스크\\";
                else
                    this.USBPath = "하드 디스크\\";

                this.UpdateFilePath = this.USBPath + "UpdateFilesMain\\";

                DirectoryInfo info = new DirectoryInfo(this.USBPath);
                DirectoryInfo directoryFolderUpdateFiles = new DirectoryInfo(this.UpdateFilePath);

                // USB 장착 유무 확인
                if (info.Exists == true)
                {
                    // USB에 UpdateFiles 유무 확인
                    if (directoryFolderUpdateFiles.Exists == true)
                    {
                        newFiles = directoryFolderUpdateFiles.GetFiles();

                        foreach (FileInfo file in newFiles)
                        {
                            fileName = file.Name.ToLower();

                            if (fileName == "itc81db_0h_main.int")
                            {
                                isUpdateFile = true;
                                this.UpdateFilePath += "itc81db_0h_main.int";

                                break;
                            }
                        }

                        if (newFiles.Length == 0 || isUpdateFile == false)
                        {
                            // USB에 업데이트 파일이 없습니다
                            DialogFormMessage message = new DialogFormMessage(7, this.ParentForm.ParentForm.SystemConfig1.Language);
                            message.ShowDialog();
                            return;
                        }
                        else
                        {
                            long a = 0;
                            byte[] byteData, version;
                            string sVersion = "";
                            FileStream fs = new FileStream(this.UpdateFilePath, FileMode.Open, FileAccess.Read);

                            version = new byte[8];
                            BinaryReader br = new BinaryReader(fs);
                            a = br.BaseStream.Length;
                            int i = int.Parse(a.ToString());
                            byteData = br.ReadBytes(i);
                            version[0] = byteData[20];
                            version[1] = byteData[21];
                            version[2] = byteData[22];
                            version[3] = byteData[23];
                            version[4] = byteData[24];
                            version[5] = byteData[25];
                            version[6] = byteData[26];
                            version[7] = byteData[27];
                            sVersion = Encoding.UTF8.GetString(version, 0, version.Length);

                            DialogFormYesNo myDlg = new DialogFormYesNo(this.ParentForm.ParentForm.SystemConfig1.Language, 3, this.ParentForm.ParentForm.SystemConfig1.MainBoardVersion, sVersion);
                            if (myDlg.ShowDialog() == DialogResult.Yes)
                            {
                                this.UpdateMainBoard();
                            }
                            else
                                return;
                        }
                    }
                    else
                    {
                        // USB에 업데이트 폴더가 없습니다
                        DialogFormMessage message = new DialogFormMessage(9, this.ParentForm.ParentForm.SystemConfig1.Language);
                        message.ShowDialog();
                        return;
                    }
                }
                else
                {
                    // USB메모리가 장착되지 않았습니다
                    DialogFormMessage message = new DialogFormMessage(5, this.ParentForm.ParentForm.SystemConfig1.Language);
                    message.ShowDialog();
                    return;
                }
            }
        }

        private void ProgramUpdate()
        {
            FileInfo[] newFiles;
            DirectoryInfo directoryFolderUpdateFiles = new DirectoryInfo(this.UpdateFilePath);
            newFiles = directoryFolderUpdateFiles.GetFiles();

            this.progressBarUpdate.Value += 20;

            this.TreatmentRemoveOldFile();

            this.progressBarUpdate.Value += 30;

            this.TreatmentCopyNewFile(newFiles);

            this.progressBarUpdate.Value += 100;
            this.ParentForm.ParentForm.SetTrackingHistoryData(Define.E_TrackingOperation.Update, "LCD");
            this.ParentForm.Enabled = false;
            this.UpdateStep = Define.E_Step3.Step3;
            this.UpdateLabelStatus(this.UpdateStep, this.ParentForm.ParentForm.SystemConfig1.Language);
        }
        private void TreatmentRemoveOldFile()
        {
            bool removeFolderCheck = false;
            FileInfo[] oldFiles;
            this.OldFilePath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\";
            if (this.OldFilePath.StartsWith("\\F") == true)
                this.RemoveFolderPath = "Flash Disk\\RemoveFile\\";
            else
                this.RemoveFolderPath = "SD Card\\RemoveFile\\";
            DirectoryInfo directoryFolderRun = new DirectoryInfo(this.OldFilePath);
            DirectoryInfo directoryFolderRemove = new DirectoryInfo(this.RemoveFolderPath);

            removeFolderCheck = directoryFolderRemove.Exists;
            oldFiles = directoryFolderRun.GetFiles();

            if (removeFolderCheck == false)
                directoryFolderRemove.Create();

            foreach (FileInfo subFile in oldFiles)
                subFile.MoveTo(RemoveFolderPath + DateTime.Now.ToString("yyyyMMddHHmmss") + subFile.Name.ToString());

            this.progressBarUpdate.Value += 20;
        }
        private void TreatmentCopyNewFile(FileInfo[] newFile)
        {
            // 새 파일 복사
            foreach (FileInfo subFile in newFile)
                subFile.CopyTo(this.OldFilePath + subFile.Name.ToString());

            this.progressBarUpdate.Value += 20;
        }

        private void UpdateMainBoard()
        {
            long a = 0;
            int count = 0, byteCount = 0;

            this.ParentForm.Enabled = false;
            this.buttonMainBoard.Enabled = false;
            this.buttonLCD.Enabled = false;

            FileStream fs = new FileStream(this.UpdateFilePath, FileMode.Open, FileAccess.Read);

            BinaryReader br = new BinaryReader(fs);
            a = br.BaseStream.Length;
            byteCount = int.Parse(a.ToString());
            this.ParentForm.ParentForm.UpdateForMain.ByteData = br.ReadBytes(byteCount);

            count = byteCount / 100;
            this.ParentForm.ParentForm.UpdateForMain.SendDataCount = count;

            this.UpdateStep = Define.E_Step3.Step2;
            this.UpdateLabelStatus(this.UpdateStep, this.ParentForm.ParentForm.SystemConfig1.Language);

            this.timerForMainBoard.Enabled = true;
        }
        public void SetProgressBarValue(int value)
        {
            this.progressBarUpdate.Value += value;
        }

        public void UpdateMainBoardFail(Define.E_LanguageID language)
        {
            this.ParentForm.Enabled = false;
            this.ParentForm.ParentForm.SetTrackingHistoryData(Define.E_TrackingOperation.Update, "Mainboard Fail");

            switch (language)
            {
                case Define.E_LanguageID.Korean:
                    this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage1.Text = "업데이트가 실패하였습니다.";
                    this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage2.Text = "메인보드를 체크해 주시기 바랍니다.";
                    break;
                case Define.E_LanguageID.English:
                    this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage1.Text = "Update Fail!";
                    this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage2.Text = "Please Check your MainBoard";
                    break;
                case Define.E_LanguageID.Chinese:
                    this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage1.Text = "更新失败!";
                    this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                    this.labelMessage2.Text = "请检查您的主板";
                    break;
                case Define.E_LanguageID.German:
                    this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                    this.labelMessage1.Text = "Update fehlgeschlagen!";
                    this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                    this.labelMessage2.Text = "Bitte überprüfen Sie Ihr MainBoard";
                    break;
                case Define.E_LanguageID.Russian:
                    this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                    this.labelMessage1.Text = "Ошибка обновления!";
                    this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                    this.labelMessage2.Text = "Пожалуйста, проверьте свою главную доску";
                    break;
                default:
                    break;
            } 
        }
        public void UpdateMainBoardFinish()
        {
            this.UpdateStep = Define.E_Step3.Step3;
            this.UpdateLabelStatus(this.UpdateStep, this.ParentForm.ParentForm.SystemConfig1.Language);
            this.ParentForm.ParentForm.SetTrackingHistoryData(Define.E_TrackingOperation.Update, "Mainboard Success");
        }
        private void UpdateLabelStatus(Define.E_Step3 step, Define.E_LanguageID language)
        {
            switch (step)
            {
                case Define.E_Step3.Step1:
                    #region Step1
                    switch (language)
                    {
                        case Define.E_LanguageID.Korean:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "USB를 본체에 삽입 하십시오";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "업데이트 할 항목을 선택해 주십시오";
                            break;
                        case Define.E_LanguageID.English:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "Please insert usb into the device";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "Please select an item to update";
                            break;
                        case Define.E_LanguageID.Chinese:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "请将usb插入设备中。";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "请选择一个项目来更新";
                            break;
                        case Define.E_LanguageID.German:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "USB nicht vom Gerät trennen";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "Drücken Sie nach dem USB-Anschluss die untere Taste";
                            break;
                        case Define.E_LanguageID.Russian:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "Пожалуйста, вставьте USB в устройство";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "Нажмите нижнюю кнопку после вставки";
                            break;
                        default:
                            break;
                    } 
                    #endregion
                    break;
                case Define.E_Step3.Step2:
                    #region Step2
                    switch (language)
                    {
                        case Define.E_LanguageID.Korean:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "업데이트 중...";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "USB를 본체에서 분리하지 마십시오";
                            break;
                        case Define.E_LanguageID.English:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "Updating...";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "Do not remove the USB from the device";
                            break;
                        case Define.E_LanguageID.Chinese:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "更新中...";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "请勿断开USB";
                            break;
                        case Define.E_LanguageID.German:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "Aktualisierung….";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "USB nicht vom Gerät trennen";
                            break;
                        case Define.E_LanguageID.Russian:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "Обновление...";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "Не отключайте USB";
                            break;
                        default:
                            break;
                    } 
                    #endregion
                    break;
                case Define.E_Step3.Step3:
                    #region Step3
                    this.labelMessage2.ForeColor = Color.Red;
                    switch (language)
                    {
                        case Define.E_LanguageID.Korean:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "프로그램 업데이트 완료";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "전원을 끄고 다시 켜주세요";
                            break;
                        case Define.E_LanguageID.English:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "Program update complete";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "Reset the system";
                            break;
                        case Define.E_LanguageID.Chinese:
                            this.labelMessage1.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage1.Text = "系统更新完成";
                            this.labelMessage2.Font = new Font("새굴림", 17, FontStyle.Regular);
                            this.labelMessage2.Text = "关掉电源,然后在打开电源";
                            break;
                        case Define.E_LanguageID.German:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "Programmaktualisierung abgeschlossen";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "Mit dem Hauptschalter aus- und einschalten";
                            break;
                        case Define.E_LanguageID.Russian:
                            this.labelMessage1.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage1.Text = "Обновление программы завершено";
                            this.labelMessage2.Font = new Font("새굴림", 12, FontStyle.Regular);
                            this.labelMessage2.Text = "Выключите питание и затем включите питание";
                            break;
                        default:
                            break;
                    } 
                    #endregion
                    this.progressBarUpdate.Value = 100;
                    break;
                default:
                    break;
            }

            this.Refresh();
        }
        private void ProgramUpdateCheck(DialogResult result)
        {
            Define.E_UpdateCheck check = Define.E_UpdateCheck.Fail;

            if (result == DialogResult.Yes)
            {
                check = this.CheckError();

                if (check == Define.E_UpdateCheck.Success)
                {
                    this.buttonMainBoard.Enabled = false;
                    this.buttonLCD.Enabled = false;
                    this.UpdateStep = Define.E_Step3.Step2;
                    this.UpdateLabelStatus(this.UpdateStep, this.ParentForm.ParentForm.SystemConfig1.Language);

                    this.ProgramUpdate();
                }
                else if (check == Define.E_UpdateCheck.NotUsbMomery)
                {
                    DialogFormMessage message = new DialogFormMessage(5, this.ParentForm.ParentForm.SystemConfig1.Language);
                    message.ShowDialog();
                }
                else if (check == Define.E_UpdateCheck.NotUpdateFolder)
                {
                    DialogFormMessage message = new DialogFormMessage(9, this.ParentForm.ParentForm.SystemConfig1.Language);
                    message.ShowDialog();
                }
                else if (check == Define.E_UpdateCheck.NotFile)
                {
                    DialogFormMessage message = new DialogFormMessage(7, this.ParentForm.ParentForm.SystemConfig1.Language);
                    message.ShowDialog();
                }
            }
        }

        public void DisplayRefresh(SystemStatus status)
        {
            this.ParentForm.ParentForm.CurrentSystemStatus.CurrentDisplay = Define.E_DisplayStore.EquipUpdate;
            this.ParentForm.ParentForm.SetDisplayMode(Define.E_DisplayMode.Menu);
            this.ParentForm.DisplayTitleRoot(this.ParentForm.ParentForm.CurrentSystemStatus);

            this.DefaultSetting();
        }
        #endregion

        #region Event Handler
        private void buttonMainBoard_Click(object sender, EventArgs e)
        {
            DialogFormYesNo myDlg = new DialogFormYesNo(this.ParentForm.ParentForm.SystemConfig1.Language, 3);
            DialogResult dr = myDlg.ShowDialog();
            myDlg.Close();

            this.Refresh();

            this.CheckErrorMainBoard(dr);
        }
        private void ButtonLCD_Click(object sender, EventArgs e)
        {
            DialogFormYesNo myDlg = new DialogFormYesNo(this.ParentForm.ParentForm.SystemConfig1.Language, 3);
            DialogResult dr = myDlg.ShowDialog();
            myDlg.Close();

            this.Refresh();

            this.ProgramUpdateCheck(dr);
        }

        private void timerForMainBoard_Tick(object sender, EventArgs e)
        {
            this.timerForMainBoard.Enabled = false;

            this.ParentForm.ParentForm.SendUpdateForMain(this.ParentForm.ParentForm.UpdateForMain.ByteData);
        }
        #endregion
    }
}