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

using SmartX;

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

namespace ITC81DB_2H.Controls
{
    public partial class ControlCenterLogHistory : UserControl
    {
        #region Field
        private FormMenu m_ParentForm;
        private int FileIndex;
        private int TotalCount;
        private int CurrentCount;
        private static int ListBoxLineCount = 16; // 화면에 보여지는 listBox 줄 수
        public bool IsFileOpen;

        private string SelectedNodeFullPath;
        private List<DataBackupYear> ListHistoryFile;
        private Collection<SmartListBox> CollectionListBox;
        private Collection<string[]> CollectionData;            // 파일에서 읽은 데이터

        private List<string> ListTime;
        private List<string> ListLoginID;
        private List<string> ListEvent;
        private List<string> ListDetail;
        private List<string> ListBefore;
        private List<string> ListAfter;
        #endregion

        #region Constructor
        public ControlCenterLogHistory(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()
        {
            if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.English)
            {
                this.labelTitleFileList.Text = "File List";
                this.labelTitleFileName.Text = "File name";
                this.labelTitleFind.Text = "Search line";
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Chinese)
            {
                this.labelTitleFileList.Text = "档案清单";
                this.labelTitleFileName.Text = "文件名";
                this.labelTitleFind.Text = "搜索行";
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Czech)
            {
                this.labelTitleFileList.Text = "File List";
                this.labelTitleFileName.Text = "File name";
                this.labelTitleFind.Text = "Vyhledávací řádek";
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Russian)
            {
                this.labelTitleFileList.Text = "Список файлов";
                this.labelTitleFileName.Text = "Имя файла";
                this.labelTitleFind.Text = "Строка поиска";
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.German)
            {
                this.labelTitleFileList.Text = "Dateiliste";
                this.labelTitleFileName.Text = "Dateinamen";
                this.labelTitleFind.Text = "Suchzeile";
            }
            else if (this.ParentForm.ParentForm.SystemConfig1.Language == Define.E_LanguageID.Spanish)
            {
                this.labelTitleFileList.Text = "Lista de archivos";
                this.labelTitleFileName.Text = "Nombre del archivo";
                this.labelTitleFind.Text = "Línea de búsqueda";
            }
            else
            {
                this.labelTitleFileList.Text = "파일 목록";
                this.labelTitleFileName.Text = "파일 이름";
                this.labelTitleFind.Text = "데이터 검색(Line)";
            }
        }
        private void DefaultSetting()
        {
            this.FileIndex = 0;
            this.TotalCount = 0;
            this.IsFileOpen = false;

            this.ListHistoryFile = new List<DataBackupYear>();
            this.CollectionData = new Collection<string[]>();

            this.ListTime = new List<string>();
            this.ListLoginID = new List<string>();
            this.ListEvent = new List<string>();
            this.ListDetail = new List<string>();
            this.ListBefore = new List<string>();
            this.ListAfter = new List<string>();

            this.CollectionListBox = new Collection<SmartListBox>();
            this.CollectionListBox.Clear();
            this.CollectionListBox.Add(this.listBoxTime);
            this.CollectionListBox.Add(this.listBoxLoginID);
            this.CollectionListBox.Add(this.listBoxEvent);
            this.CollectionListBox.Add(this.listBoxDetail);
            this.CollectionListBox.Add(this.listBoxBefore);
            this.CollectionListBox.Add(this.listBoxAfter);
        }
        private void UpdateInitialStatus()
        {
            this.labelFileName.Text = "";
            this.labelCurrentIndex.Text = "0";
            this.labelTotalIndex.Text = "0";
            this.labelFind.Text = "";

            this.ClearListBox();
            this.ClearData();
        }
        public void UpdateFileList()
        {
            int fileCount = 0;
            //TreeNode node;
            List<string> years = new List<string>();
            List<string> months = new List<string>();
            List<string> days = new List<string>();

            this.treeView.Nodes.Clear();
            this.ListHistoryFile.Clear();

            DirectoryInfo dir = new DirectoryInfo(this.ParentForm.ParentForm.PathDataHistoryFolder);
            List<string> fileNames = new List<string>();

            // 폴더 체크
            if (dir.Exists == false)
                dir.Create();

            // year 폴더 가져오기
            DirectoryInfo[] yearDirectorys = dir.GetDirectories();
            // year 폴더 정렬 
            years = this.ParentForm.DirectorySort(yearDirectorys);

            // History File 리스트 생성
            if (years.Count != 0)
            {
                // Year
                foreach (string year in years)
                {
                    DataBackupYear y = new DataBackupYear(year);
                    DirectoryInfo monthDir = new DirectoryInfo(string.Format("{0}{1}", this.ParentForm.ParentForm.PathDataHistoryFolder, year));
                    DirectoryInfo[] monthDirectorys = monthDir.GetDirectories();

                    months = this.ParentForm.DirectorySort(monthDirectorys);

                    if (months.Count != 0)
                    {
                        // Month
                        foreach (string month in months)
                        {
                            DirectoryInfo dayDir = new DirectoryInfo(string.Format("{0}{1}\\{2}", this.ParentForm.ParentForm.PathDataHistoryFolder, year, month));
                            FileInfo[] dayFiles = dayDir.GetFiles();

                            days = this.DayHistoryDirectorySort(dayFiles);

                            DataBackupMonth m = new DataBackupMonth(month);
                            m.Days = days;

                            y.Months.Add(m);
                        }

                        this.ListHistoryFile.Add(y);
                    }
                    else
                    {
                        this.ListHistoryFile.Add(y);
                    }
                }

                // node 생성
                for (int i = 0; i < this.ListHistoryFile.Count; i++)
                {
                    TreeNode node = new TreeNode(this.ListHistoryFile[i].Year);
                    for (int j = 0; j < this.ListHistoryFile[i].Months.Count; j++)
                    {
                        TreeNode nodeMonth = new TreeNode(this.ListHistoryFile[i].Months[j].Month);

                        for (int k = 0; k < this.ListHistoryFile[i].Months[j].Days.Count; k++)
                        {
                            nodeMonth.Nodes.Add(this.ListHistoryFile[i].Months[j].Days[k]);
                            fileCount++;
                        }
                        node.Nodes.Add(nodeMonth);
                    }
                    this.treeView.Nodes.Add(node);
                }
            }

            this.labelCount.Text = fileCount.ToString();
        }

        private List<string> DayHistoryDirectorySort(FileInfo[] files)
        {
            List<string> listFile = new List<string>();
            Dictionary<string, int> dirNames = new Dictionary<string, int>();
            Dictionary<string, int> dirNamesSort = new Dictionary<string, int>();

            foreach (FileInfo file in files)
            {
                if (file.Name.StartsWith("H") == true)
                    dirNames.Add(file.Name, int.Parse(file.Name.Substring(1, 8)));
            }

            var vrList = dirNames.Keys.ToList();
            vrList.Sort();

            foreach (var v in vrList)
                dirNamesSort.Add(v, dirNames[v]);

            foreach (var v in dirNamesSort)
                listFile.Add(v.Key);

            return listFile;
        }
        private void FileCopy(FileInfo file, string fileName)
        {
            try
            {
                if (this.FileIndex == 0)
                {
                    file.CopyTo(fileName);
                    this.FileIndex = 0;
                }
                else
                {
                    file.CopyTo(fileName.Insert(fileName.Length - 4, "_" + this.FileIndex.ToString()));
                    this.FileIndex = 0;
                }
            }
            catch
            {
                this.FileIndex++;
                this.FileCopy(file, fileName);
            }
        }

        private void SearchLineEnabled(bool bValue)
        {
            if (bValue == false)
                this.labelFind.BackColor = Color.Gray;
            else
                this.labelFind.BackColor = Color.White;

            this.labelFind.Enabled = bValue;
            this.buttonFind.Enabled = bValue;
        }

        public void ClearData()
        {
            this.CollectionData.Clear();

            this.ListTime.Clear();
            this.ListLoginID.Clear();
            this.ListEvent.Clear();
            this.ListDetail.Clear();
            this.ListBefore.Clear();
            this.ListAfter.Clear();
        }
        public void ClearListBox()
        {
            for (int i = 0; i < this.CollectionListBox.Count; i++)
                this.CollectionListBox[i].ClearAll();
        }

        private void ListBoxScrollUp(int value)
        {
            if (this.CurrentCount == ListBoxLineCount || (this.CurrentCount < ListBoxLineCount && this.CurrentCount == this.TotalCount)
                || this.listBoxTime.ItemCount == 0)
                return;

            int startIndex = 0, endIndex = 0;

            this.ClearData();
            this.ClearListBox();

            if (this.CurrentCount - value <= ListBoxLineCount)
            {
                startIndex = 0 + 1;
                endIndex = ListBoxLineCount + 1;

                this.CurrentCount = ListBoxLineCount;
            }
            else
            {
                this.CurrentCount = this.CurrentCount - value;

                startIndex = this.CurrentCount - ListBoxLineCount;
                endIndex = this.CurrentCount;
            }

            this.UpdateData(startIndex, endIndex);
        }
        private void ListBoxScrollDown(int value)
        {
            if (this.TotalCount == this.CurrentCount || this.listBoxTime.ItemCount == 0)
                return;

            int startIndex = 0, endIndex = 0;

            this.ClearData();
            this.ClearListBox();

            if (this.CurrentCount + value >= this.TotalCount)
            {
                startIndex = this.TotalCount - ListBoxLineCount + 1;
                endIndex = this.TotalCount + 1;

                this.CurrentCount = this.TotalCount;
            }
            else
            {
                this.CurrentCount = this.CurrentCount + value;

                startIndex = this.CurrentCount - ListBoxLineCount;
                endIndex = this.CurrentCount;
            }

            this.UpdateData(startIndex, endIndex);
        }

        private void UpdateData(int startIndex, int endIndex)
        {
            for (int i = startIndex; i < endIndex; i++)
                this.CollectionData.Add(this.smartFile1.ReadStringBuffer(i).Split(','));

            this.UpdateListData();
            this.UpdateListBoxDataDisplay();
            this.UpdateListBoxCount();
        }
        private void UpdateListBoxCount()
        {
            this.labelTotalIndex.Text = this.TotalCount.ToString();
            this.labelCurrentIndex.Text = this.CurrentCount.ToString();
        }
        private void UpdateListData()
        {
            // List Item Add
            for (int i = 0; i < this.CollectionData.Count; i++)
            {
                this.ListTime.Add(this.CollectionData[i][1]);
                this.ListLoginID.Add(this.CollectionData[i][2]);
                this.ListEvent.Add(this.CollectionData[i][3]);
                this.ListDetail.Add(this.CollectionData[i][4]);
                this.ListBefore.Add(this.CollectionData[i][5]);
                this.ListAfter.Add(this.CollectionData[i][6]);
            }
        }
        private void UpdateListBoxDataDisplay()
        {
            for (int i = 0; i < this.ListTime.Count; i++)
            {
                this.listBoxTime.AddItem(this.ListTime[i]);
                this.listBoxLoginID.AddItem(this.ListLoginID[i]);
                this.listBoxEvent.AddItem(this.ListEvent[i]);
                this.listBoxDetail.AddItem(this.ListDetail[i]);
                this.listBoxBefore.AddItem(this.ListBefore[i]);
                this.listBoxAfter.AddItem(this.ListAfter[i]);
            }
        }

        public void LoadDatas(string fullFilePath)
        {
            int startIndex = 0, endIndex = 0;

            try
            {
                this.ClearData();
                this.ClearListBox();

                this.ParentForm.SplashStart();

                this.smartFile1.FilePathName = fullFilePath;
                if (this.smartFile1.Open(2000000) == true)
                    this.IsFileOpen = true;
                bool bValue = this.smartFile1.ReadStringAllBuffer();
                if (bValue == false)
                {
                    this.FileClose();

                    return;
                }

                long lineNum = this.smartFile1.GetCount();
                this.TotalCount = (int)lineNum;

                if (this.TotalCount > ListBoxLineCount)
                {
                    startIndex = this.TotalCount - ListBoxLineCount;
                    endIndex = this.TotalCount;
                }
                else
                {
                    startIndex = 0 + 1; // 맨 첫 줄은 제목
                    endIndex = this.TotalCount;
                }

                this.TotalCount = (int)lineNum - 1; // 맨 첫 줄 제외
                this.CurrentCount = this.TotalCount;

                if (this.TotalCount < ListBoxLineCount)
                    this.SearchLineEnabled(false);
                else
                    this.SearchLineEnabled(true);

                this.labelFind.Text = this.CurrentCount.ToString();
                this.UpdateData(startIndex, endIndex);
                
                // File Name
                string[] data = fullFilePath.Split('\\');
                this.labelFileName.Text = data[data.Length - 1];

                this.ParentForm.SplashFinish();

                this.Enabled = true;
            }
            catch
            {
                DialogFormMessage myMsg = new DialogFormMessage(16, this.ParentForm.ParentForm.SystemConfig1.Language);
                myMsg.ShowDialog();
                this.ParentForm.SplashFinish();
                this.FileClose();
                this.Enabled = true;
            }
        }
        public void FileClose()
        {
            if (this.IsFileOpen == true)
            {
                this.ParentForm.ParentForm.IsLogProcessing = false;

                this.smartFile1.Close();
                this.IsFileOpen = false;

                this.ClearData();
                this.ClearListBox();

                this.labelFileName.Text = "";
                this.labelCurrentIndex.Text = "0";
                this.labelTotalIndex.Text = "0";
                this.labelFind.Text = "";
            }
        }

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

            this.UpdateInitialStatus();
            this.UpdateFileList();
            this.treeView.ExpandAll();
            this.TotalCount = 0;
            this.SelectedNodeFullPath = "";

            if (int.Parse(this.labelCount.Text) == 0)
            {
                DialogFormMessage msg = new DialogFormMessage(37, this.ParentForm.ParentForm.SystemConfig1.Language);
                msg.ShowDialog();
                return;
            }
        }
        #endregion

        #region Event Handler
        private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Text.Substring(0, 1) == "H")
            {
                if (e.Node.Checked == true)
                    e.Node.Checked = false;
                else
                    e.Node.Checked = true;

                //this.labelFileName.Text = e.Node.Text;
                this.SelectedNodeFullPath = this.treeView.SelectedNode.FullPath;
            }
            //else
            //{
            //    var node = e.Node;
            //    int count = node.Nodes.Count;

            //    for (int i = 0; i < count; i++)
            //        node.Nodes[i].Checked = node.Checked;
            //}
        }
        private void buttonRead_Click(object sender, EventArgs e)
        {
            if (this.SelectedNodeFullPath == "" || this.SelectedNodeFullPath == null)
                return;

            this.FileClose();
            this.ParentForm.ParentForm.IsLogProcessing = true;

            this.Enabled = false;

            this.LoadDatas(this.ParentForm.ParentForm.PathDataHistoryFolder + this.SelectedNodeFullPath);
        }

        private void labelFind_Click(object sender, EventArgs e)
        {
            if (this.listBoxTime.ItemCount == 0)
                return;

            string value = "";
            DialogFormNumKeyPad myKeyPad = new DialogFormNumKeyPad(this.labelFind.Text, 6, 0, false, this.ParentForm.ParentForm.SystemConfig1.Language);

            if (myKeyPad.ShowDialog() == DialogResult.OK)
            {
                if (myKeyPad.doubleValue < 0)
                {
                    // 입력범위를 확인하세요
                    DialogFormMessage myMsg = new DialogFormMessage(1, this.ParentForm.ParentForm.SystemConfig1.Language);
                    myMsg.ShowDialog();
                }
                else if (myKeyPad.doubleValue > this.TotalCount)
                {
                    this.labelFind.Text = this.TotalCount.ToString();
                }
                else
                {
                    this.labelFind.Text = myKeyPad.StringValue;

                    if (this.labelFind.Text == "" || this.labelFind.Text == null || this.listBoxTime.ItemCount == 0)
                        return;

                    int startIndex = 0, endIndex = 0;
                    int index = int.Parse(this.labelFind.Text);

                    try
                    {
                        this.ClearData();
                        this.ClearListBox();

                        if (this.TotalCount > ListBoxLineCount)
                        {
                            if (index - ListBoxLineCount < 0)
                            {
                                startIndex = 0 + 1;
                                endIndex = ListBoxLineCount + 1;

                                this.CurrentCount = ListBoxLineCount;
                            }
                            else
                            {
                                startIndex = index - ListBoxLineCount;
                                endIndex = index;

                                this.CurrentCount = index;
                            }
                        }
                        else
                        {
                            startIndex = 0 + 1;
                            endIndex = this.TotalCount + 1;

                            this.CurrentCount = this.TotalCount;
                        }

                        this.UpdateData(startIndex, endIndex);
                    }
                    catch
                    {
                        DialogFormMessage myMsg = new DialogFormMessage(16, this.ParentForm.ParentForm.SystemConfig1.Language);
                        myMsg.ShowDialog();
                    }
                }
            }
        }
        private void buttonFind_Click(object sender, EventArgs e)
        {
            if (this.labelFind.Text == "" || this.labelFind.Text == null || this.listBoxTime.ItemCount == 0)
                return;

            int startIndex = 0, endIndex = 0;
            int index = int.Parse(this.labelFind.Text);

            try
            {
                this.ClearData();
                this.ClearListBox();

                if (this.TotalCount > ListBoxLineCount)
                {
                    if (index - ListBoxLineCount < 0)
                    {
                        startIndex = 0 + 1;
                        endIndex = ListBoxLineCount + 1;

                        this.CurrentCount = ListBoxLineCount;
                    }
                    else
                    {
                        startIndex = index - ListBoxLineCount;
                        endIndex = index;

                        this.CurrentCount = index;
                    }
                }
                else
                {
                    startIndex = 0 + 1;
                    endIndex = this.TotalCount + 1;

                    this.CurrentCount = this.TotalCount;
                }

                this.UpdateData(startIndex, endIndex);
            }
            catch
            {
                DialogFormMessage myMsg = new DialogFormMessage(16, this.ParentForm.ParentForm.SystemConfig1.Language);
                myMsg.ShowDialog();
            }
        }

        private void buttonBackup_Click(object sender, EventArgs e)
        {
            this.FileClose();
            this.ParentForm.Backup(Define.E_DataType.History, this.treeView);

            if (this.ParentForm.ParentForm.SystemConfig3.IsPart11 == false)
            {
                this.UpdateFileList();
                this.treeView.ExpandAll();
            }
        }

        private void buttonUp_Click(object sender, EventArgs e)
        {
            this.ListBoxScrollUp(ListBoxLineCount);
        }
        private void buttonDown_Click(object sender, EventArgs e)
        {
            this.ListBoxScrollDown(ListBoxLineCount);
        }

        private void listBox_Click(object sender, EventArgs e)
        {
            SmartX.SmartListBox listBox = sender as SmartX.SmartListBox;

            listBox.SelectItemIndex = -1;
        }
        #endregion
    }
}
