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

namespace IControls_FireManager
{
    public partial class Frame_Tree : Form
    {
        // Device Tree 에서 사용자가 선택한 노드
        public TreeNode SystemTree_SelectedNode;

        // 수신기 를 표시하기 위한 델리게이트
        delegate void TreeView_SetTextCallback(TreeNode pNode, _RECEIVER RECEIVER);

        // 수신기 전체 삭제 여부 대화 팝업창 
        public Form Popup_ReceiverAllDelInform = new Form();

        // 수신기 삭제 여부 대화 팝업창 
        public Form Popup_ReceiverDelInform = new Form();

        // 페이지 전체 삭제 여부 대화 팝업창
        public Form Popup_PageAllDelInform = new Form();

        // 페이지 삭제 여부 대화 팝업창
        public Form Popup_PageDelInform = new Form();

        // 페이지 저장 여부 대화 팝업창
        public Form Popup_PageSaveInform = new Form();

        // 동기화 진행시 트리 노드에 접근하기 위한 델리게이트
        delegate void TreeView_SyncXmlDataNodeCallback();

        // 동기화 진행 여부 대화 팝업창 
        public Form Popup_XmlSyncStartInform = new Form();

        // 동기화 진행시 진행 팝업창
        public Form Popup_XmlSyncStartProgress = new Form();
        public int Popup_XmlSyncStartProgress_Count = 0; // 카운트 
        public int Popup_XmlSyncStartProgress_Count_End = 3; // 최종카운트

        // 디바이스 정보를 DB에 저장 시 진행팝업창
        public Form Popup_DeviceIconSave_Progress = new Form();
        public int Popup_DeviceIconSave_Progress_Count = 0; // 카운트 
        public int Popup_DeviceIconSave_Progress_Count_End = 0; // 최종카운트

        // 프로젝트 -> 수신기 추가 -> 확인 버튼을 누르는 경우, 수신기 정보를 임시 저장하는 클래스
        public _RECEIVER Temp_RECEIVER = new _RECEIVER();

        // 맵디자이너에서 페이지 동기화 스레드
        public Thread WorkingThread = null;

        //
        // 가변엑티브 레포트용 데이타
        //

        // 수신기 - 포인트 - 출력
        string[] ColumnNames_Point_Output = _Convert.String_to_ArrayString(_Text.UI_WORKFRAME_POINT_OUTPUT_COLUMNNAME);
        // 수신기 - 포인트 - 입력
        string[] ColumnNames_Point_Input = _Convert.String_to_ArrayString(_Text.UI_WORKFRAME_POINT_INPUT_COLUMNNAME);
        // 컬럼헤더 
        public Single temp = 1.51F; // 0.280     
        public Single temp2 = 1.11F;
        public ArrayList Point_Input_ColumnHeader = new ArrayList();  // 1.728
        public ArrayList Point_Output_ColumnHeader = new ArrayList();  // 1.728

        // 화면캡쳐
        public int Caputure_Process_Cnt = 0;
        public string Capure_Receiver_ID = null;
        public int Capture_Page_Index = 0;
        public Form Capture_Warning = null;

        // 생성자
        public Frame_Tree()
        {
            ///
            /// 초기화
            /// 

            InitializeComponent();

            ///
            /// 이벤트
            ///

            // 폼닫기 이벤트를 등록 (이벤트 핸들러 해제용)
            this.FormClosing += new FormClosingEventHandler(CreateForm_FormClosing);

            // 트리뷰에 페이지 노드를 생성 및 편집하기 위한 이벤트 등록
            _Event.TreeView_PageNodeSet_SendMessage_Event += new _Event.TreeView_PageNodeSet_SendMessage_Handler(_Event_TreeView_PageNodeSet_SendMessage_Event);

            // 트리 추가 이벤트 핸들러 등록
            _Event.TreeView_ReceiverNodeSet_SendMessage_Event += new _Event.TreeView_ReceiverNodeSet_SendMessage_Handler(_Event_TreeView_ReceiverNodeSet_SendMessage_Event);

            // 다른이름으로 페이지 명을 변경하여 저장하는 이벤트 핸들러 등록
            _Event.Page_Rename_SendMessage_Event += new _Event.Page_Rename_SendMessage_Handler(_Event_Page_Rename_SendMessage_Event);

            // 페이지 저장 (XML 및 DB 저장) 이벤트 핸들러 등록
            _Event.Page_Save_SendMessage_Event += new _Event.Page_Save_SendMessage_Handler(_Event_Page_Save_SendMessage_Event);

            // 트리뷰 초기화 이벤트 및 프로젝트 열기 혹은 새로만들기 겸용 핸들러 등록 
            _Event.TreeView_Clear_SendMessage_Event += new _Event.TreeView_Clear_SendMessage_Handler(_Event_TreeView_Clear_SendMessage_Event);

            // 수신기 초기화 이벤트 핸들러 등록
            _Event.Receiver_Clear_SendMessage_Event += new _Event.Receiver_Clear_SendMessage_Handler(_Event_Receiver_Clear_SendMessage_Event);

            // 수신기 추가 및 편집 폼에서 작업 완료 이벤트 핸들러 등록
            _Event.WorkViewPageName_Receiver_SendMessage_Event += new _Event.WorkViewPageName_Receiver_SendMessage_Handler(_Event_WorkViewPageName_Receiver_SendMessage_Event);

            ///
            /// UI 셋팅
            ///

            // 트리 초기화
            this.treeView_SystemTree.Nodes.Clear();

            // 가변레포트용 데이타

            // 입력포인트
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[0], ColumnNames_Point_Input[0], 0.31F);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[1], ColumnNames_Point_Input[1], temp2);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[2], ColumnNames_Point_Input[2], temp2);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[3], ColumnNames_Point_Input[3], temp2);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[4], ColumnNames_Point_Input[4], temp2);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[5], ColumnNames_Point_Input[5], temp2);
            _ActiveReport.Print_Default_Column(Point_Input_ColumnHeader, ColumnNames_Point_Input[6], ColumnNames_Point_Input[6], temp2);

            // 출력포인트
            _ActiveReport.Print_Default_Column(Point_Output_ColumnHeader, ColumnNames_Point_Output[0], ColumnNames_Point_Output[0], 0.31F);
            _ActiveReport.Print_Default_Column(Point_Output_ColumnHeader, ColumnNames_Point_Output[1], ColumnNames_Point_Output[1], temp);
            _ActiveReport.Print_Default_Column(Point_Output_ColumnHeader, ColumnNames_Point_Output[2], ColumnNames_Point_Output[2], temp);
            _ActiveReport.Print_Default_Column(Point_Output_ColumnHeader, ColumnNames_Point_Output[3], ColumnNames_Point_Output[3], temp);
            _ActiveReport.Print_Default_Column(Point_Output_ColumnHeader, ColumnNames_Point_Output[4], ColumnNames_Point_Output[4], temp);
        }

        // _Receiver.xml 제거 : cyim 2012.8.29
        /////
        ///// Receiver XML 로 부터 읽은 값을 토대로 트리에 표시하기
        /////

        //private void treeView_Read_Receiver_XML()
        //{
        //    // 프로젝트명이 있는 경우에 한해서 트리를 자동으로 추가해주자
        //    // 단, Receiver.xml 에 아무런 데이타가 없다면 표시할 의미가 없다
        //    if (_Data.HASH_XMLRECEIVER.Count != 0)
        //    {
        //        foreach (string XMLRECEIVER_ID in _Data.LIST_XMLRECEIVER_ID)
        //        {
        //            _RECEIVER RECEIVER = new _RECEIVER();
        //            // 수신기 아이디
        //            RECEIVER.ID = ((_ReceiverXML)_Data.HASH_XMLRECEIVER[XMLRECEIVER_ID]).ID;
        //            // 수신기 아이피
        //            RECEIVER.IP = ((_ReceiverXML)_Data.HASH_XMLRECEIVER[XMLRECEIVER_ID]).IP;
        //            // 수신기 이름
        //            RECEIVER.KEY_NAME = ((_ReceiverXML)_Data.HASH_XMLRECEIVER[XMLRECEIVER_ID]).KEY_NAME;

        //            // 해쉬에 추가 
        //            if (_Hash.Add(_Data.HASH_RECEIVER, RECEIVER.ID, RECEIVER) == true)
        //            {
        //                // 키리스트에 추가
        //                _Data.LIST_RECEIVER_ID.Add(RECEIVER.ID);
        //            }
        //        }

        //        // 파일 읽기에 사용한 정보는 클리어
        //        _Data.LIST_XMLRECEIVER_ID.Clear();
        //        _Data.HASH_XMLRECEIVER.Clear();

        //        // 저장된 정보를 토대로 트리에 표시
        //        foreach (string RECEIVER_ID in _Data.LIST_RECEIVER_ID)
        //        {
        //            // 수신기 노드 추가
        //            _Event_TreeView_ReceiverNodeSet_SendMessage_Event((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]);
        //        }

        //        // 동기화 작업 시작
        //        // 리스트 및 해쉬 삭제
        //        _Data.LIST_PAGE_ID.Clear();
        //        _Data.HASH_PAGE.Clear();

        //        ///
        //        /// 스레드 시작전에 첫번째 수신기의 그래픽 노드를 선택했다고 지정하자
        //        /// 

        //        // 서브키를 조회하기 위해 임시로 클래스 생성
        //        _RECEIVER tempRECEIVER = new _RECEIVER();
        //        // 첫번째 수신기의 그래픽 노드 키값 조회
        //        string temp_key = tempRECEIVER.Set_SubKey(((_RECEIVER)_Data.HASH_RECEIVER[_Data.LIST_RECEIVER_ID[0].ToString()]), _Text.UI_TREE_IMAGE);
        //        // 해당 그래픽 노드 정보
        //        TreeNode tempNode = _Tree.GetNode_By_Name(this.treeView_SystemTree, temp_key);
        //        // 선택된 노드를 지정
        //        SystemTree_SelectedNode = tempNode;

        //        // 스레드 시작
        //        Sync_Xml_Data_Thread(((_RECEIVER)_Data.HASH_RECEIVER[_Data.LIST_RECEIVER_ID[0].ToString()]));
        //    }
        //}


        ///
        /// Device Tree 노드의 마우스 클릭
        /// 

        private void treeView_SystemTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            // LOG
            _Event.DebugView_SendMessage_Write(e.Node.Name + _Text.Minus + e.Node.Text + _Text.Blank + _Text.LOG_PushTreeNode);

            // 오른쪽마우스를 누르면 왼쪽마우스 버튼을 누른것처럼 포커스를 이동한다 
            treeView_SystemTree.SelectedNode = treeView_SystemTree.GetNodeAt(e.X, e.Y);

            // 선택한 트리 노드를 저장한다
            SystemTree_SelectedNode = e.Node;

            // 왼쪽마우스 혹은 오른쪽 마우스 버튼으로 노드를 선택하면 페이지가 출력된다
            switch (e.Node.ImageIndex)
            {
                // 프로젝트 
                case (int)Object_Type.PROJECT:
                    _Event.WorkViewPageName_SendMessage_Write(null, Object_Type.PROJECT, null, null);
                    break;
                // 수신기
                case (int)Object_Type.RECEIVER:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Name, Object_Type.RECEIVER, null, null);
                    break;
                // 수신기 - 입출력
                case (int)Object_Type.INOUT:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Name, Object_Type.INOUT, null, null);
                    break;
                // 수신기 - 입출력 - 통신보드
                case (int)Object_Type.COM_BOARD:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.COM_BOARD, null, null);
                    break;
                // 수신기 - 입출력 - IO보드
                case (int)Object_Type.IO_BOARD:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.IO_BOARD, null, null);
                    break;
                // 수신기 - 입출력 - 키패드 
                case (int)Object_Type.KEYPAD:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.KEYPAD, null, null);
                    break;
                // 수신기 -입출력 - 비상방송
                case (int)Object_Type.EMERGENCY_BROADCAST:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.EMERGENCY_BROADCAST, null, null);
                    break;
                // 수신기 - 포인트
                case (int)Object_Type.POINT:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Name, Object_Type.POINT, null, null);
                    break;
                // 수신기 - 포인트 - 입력
                case (int)Object_Type.INPUT:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.INPUT, null, null);
                    break;
                // 수신기 - 포인트 - 출력
                case (int)Object_Type.OUTPUT:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.OUTPUT, null, null);
                    break;
                // 수신기 - 연동
                case (int)Object_Type.OPER:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Name, Object_Type.OPER, null, null);
                    break;
                // 수신기 - 연동 - 그룹
                case (int)Object_Type.OPER_GROUP:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.OPER_GROUP, null, null);
                    break;
                // 수신기 - 연동 - 연동설정
                case (int)Object_Type.OPER_SET:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.OPER_SET, null, null);
                    break;
                // 수신기 - 그래픽
                case (int)Object_Type.IMAGE:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Name, Object_Type.IMAGE, null, null);
                    break;
                // 수신기 - 그래픽 - 페이지
                case (int)Object_Type.PAGE:
                    _Event.WorkViewPageName_SendMessage_Write(SystemTree_SelectedNode.Parent.Parent.Name, Object_Type.PAGE, SystemTree_SelectedNode.Name, SystemTree_SelectedNode.Text);
                    break;
            }

            // 오른쪽마우스 버튼
            if (e.Button == System.Windows.Forms.MouseButtons.Right)
            {
                switch (e.Node.ImageIndex)
                {
                    // 프로젝트를 선택하는 경우 
                    case (int)Object_Type.PROJECT:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.ReceiverAdd + ";" +
                                _Text.ContextStripSeparator + ";" +
                                _Text.TreeCollapse + ";" +
                                _Text.TreeExpand + ";" +
                                _Text.ContextStripSeparator + ";" +
                                _Text.ReceiverAllDel + ";" +
                                _Text.ContextStripSeparator + ";" + // cyim 2016.12.15 : 모바일앱용 사용자 관리
                                _Text.UserEdit + ";" +
                                _Text.ContextStripSeparator,
                                //+ ";" + // 엑셀로부터 이벤트타입을 읽어오는 방법으로 수정하였으므로 필요없음
                                //_Text.EventTypeCreate,
                                Selected_Project_Menustrip_ItemClicked);
                        }
                        break;
                    // 수신기를 선택하는 경우 
                    case (int)Object_Type.RECEIVER:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.ReceiverDel + ";" +
                                _Text.ReceiverEdit,
                                Selected_Receiver_Menustrip_ItemClicked);
                        }
                        break;
                    // 수신기 입출력을  선택하는 경우 
                    case (int)Object_Type.INOUT:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.INOUTEdit,
                                Selected_InOut_Menustrip_ItemClicked);
                        }
                        break;
                    // 포인트를 선택하는 경우
                    case (int)Object_Type.POINT:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.ExcelImport,
                                Selected_Point_Menustrip_ItemClicked);
                        }
                        break;
                    // 포인트중 입력을 선택하는 경우
                    case (int)Object_Type.INPUT:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.PointInputReport + ";" +
                                _Text.EmergencyEditor + ";" +
                                _Text.OPCOperationData,
                                Selected_Point_Menustrip_ItemClicked);
                        }
                        break;
                    // 포인트중 출력을 선택하는 경우
                    case (int)Object_Type.OUTPUT:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.PointOutputReport,
                                Selected_Point_Menustrip_ItemClicked);
                        }
                        break;
                    // 연동의 그룹을 선택하는 경우
                    case (int)Object_Type.OPER_GROUP:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.ExcelImport + ";" +
                                _Text.OperGroupReport,
                                Selected_OperGroup_Menustrip_ItemClicked);
                        }
                        break;
                    // 연동의 설정을 선택하는 경우
                    case (int)Object_Type.OPER_SET:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.ExcelImport + ";" +
                                _Text.OperSetReport + ";" +
                                _Text.MapProcessFile,
                                Selected_OperSet_Menustrip_ItemClicked);
                        }
                        break;
                    // 그래픽을 선택하는 경우 
                    case (int)Object_Type.IMAGE:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.PageAdd + ";" +
                                _Text.PageSave + ";" +
                                _Text.PageSync + ";" +
                                _Text.ContextStripSeparator + ";" +
                                _Text.PageAllDel + ";" +
                                _Text.ContextStripSeparator + ";" +
                                _Text.PageReport,
                                Selected_Image_Menustrip_ItemClicked);
                        }
                        break;
                    // 페이지를 선택하는 경우 
                    case (int)Object_Type.PAGE:
                        {
                            // 팝업 메뉴 생성
                            _Contextmenustrip.Create(this.treeView_SystemTree, e.Location,
                                _Text.PageEdit + ";" +
                                _Text.PageRename + ";" +
                                _Text.ContextStripSeparator + ";" +
                                _Text.PageDel,
                                Selected_Page_Menustrip_ItemClicked);
                        }
                        break;
                }
            }
        }

        ///
        /// 팝업 메뉴 선택
        /// 

        // Root 
        public void Selected_Project_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 수신기 전체 삭제
            if (e.ClickedItem.Text == _Text.ReceiverAllDel)
            {
                // 수신기가 존재하는 경우에만 
                if (_Data.LIST_RECEIVER_ID.Count == 0)
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 250, 150, _Text.NotReceiver, 0);
                }
                else
                {
                    Popup_ReceiverAllDelInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 350, 150, _Text.AllDelete_Continue, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_ReceiverAllDel_PopupClose_SendMessage_Event);
                }
            }
            // 수신기 추가
            else if (e.ClickedItem.Text == _Text.ReceiverAdd)
            {
                // 수신기 추가를 시도하는 경우 수신기 아이디의 값은 1이다
                Form_Receiver_Add Receiver_Add = new Form_Receiver_Add(_Data.CREATE_RECEIVER_ID());
                _Form.Create(Receiver_Add, null);
            }
            // 트리축소
            else if (e.ClickedItem.Text == _Text.TreeCollapse)
            {
                this.treeView_SystemTree.CollapseAll();
                this.treeView_SystemTree.Nodes[0].Expand();
            }
            // 트리확대
            else if (e.ClickedItem.Text == _Text.TreeExpand)
            {
                this.treeView_SystemTree.ExpandAll();
            }
            // EVENT TYPE 생성
            else if (e.ClickedItem.Text == _Text.EventTypeCreate)
            {
                Create_TB_EVENT_TYPE();
            }
            // 사용자관리 [모바일앱전용] // cyim 2016.12.15 : 모바일앱용 사용자 관리
            else if (e.ClickedItem.Text == _Text.UserEdit)
            {
                Form_System_UserEdit System_UserEdit = new Form_System_UserEdit();
                _Form.Create(System_UserEdit, null);
            }
        }

        // 수신기 노드를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_Receiver_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 수신기 삭제
            if (e.ClickedItem.Text == _Text.ReceiverDel)
            {
                // 수신기가 존재하는 경우에만 
                if (_Data.LIST_RECEIVER_ID.Count == 0)
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 250, 150, _Text.NotReceiver, 0);
                }
                else
                {
                    Popup_ReceiverDelInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 350, 150, _Text.Delete_Continue, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_ReceiverDel_PopupClose_SendMessage_Event);
                }
            }
            // 수신기 수정
            else if (e.ClickedItem.Text == _Text.ReceiverEdit)
            {
                // 장치검색 폼생성 (수정 모드)
                Form_Receiver_Add Config_Device = new Form_Receiver_Add(Int32.Parse(SystemTree_SelectedNode.Name)); // 수신기 노드의 키값 
                _Form.Create(Config_Device, null);
            }
        }

        // 포인트 노드를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_Point_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 엑셀연동
            if (e.ClickedItem.Text == _Text.ExcelImport)
            {
                // 엑셀 연동 폼					
                Form_PointConfig PointConfig = new Form_PointConfig(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]), SystemTree_SelectedNode.Text);
                _Form.Create(PointConfig, null);
            }
            // 비상방송 편집
            else if (e.ClickedItem.Text == _Text.EmergencyEditor)
            {
                // 비상방송 편집 폼 (기존 UI 는 그대로 두고 여기 폼에서 일괄적으로 삭제를 진행할 수 있도록 한다) 
                _Data.MenuActivedForm = new Form_AddDevice_Emergency(SystemTree_SelectedNode.Parent.Parent.Name, "Emergency", "I");
                _Form.Create(_Data.MenuActivedForm, null);
            }
            // 입력포인트 OPC 연동데이타 생성
            else if (e.ClickedItem.Text == _Text.OPCOperationData)
            {
                // OPC 연동 데이터 생성 폼					
                Form_PointOpcData PointOpcData = new Form_PointOpcData(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]));
                _Form.Create(PointOpcData, null);
            }
            // 입력포인트 보고서
            else if (e.ClickedItem.Text == _Text.PointInputReport)
            {
                // 레포트 폼생성 
                if (_Data.ActiveReportViewer_Enable == false)
                {
                    // 테이블 생성
                    DataSet DataSet_Point_Input = new DataSet();
                    _Dataset.Create_Table(DataSet_Point_Input);
                    _Dataset.Add_DataColumn(DataSet_Point_Input, ColumnNames_Point_Input, ColumnNames_Point_Input); // 키 정보와 UI 표시부는 동일하다

                    // 매개변수 순서 => COMM_ID, INOUT_TYPE, BOARD_ID, LOOP_NO, REPEATER_ID, POSITION_CODE, DEVICE_TYPE_NAME, DEVICE_NAME               
                    DataRowCollection DB_TABLE_DEVICE = ((_ImportPoint)_Data.Hash_ImportPoint[SystemTree_SelectedNode.Parent.Parent.Name]).IN_Points;

                    // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                    ArrayList SortSupport = new ArrayList();

                    // DataSet  내용을 수정한다
                    for (int i = 0; i < DB_TABLE_DEVICE.Count; i++)
                    {
                        // 레코드 정보
                        DataRow dr = DB_TABLE_DEVICE[i];
                        if (_Convert.Exception_Into_object(dr[3], dr[4], dr[5], dr[6], dr[7]) == true)
                        {
                            // 매개변수 순서 => COMM_ID, BOARD_ID, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE
                            MskDeviceIDString dev_s = new MskDeviceIDString(
                                _Convert.Null_to_IntZero(dr[3].ToString()),
                                _Convert.Null_to_IntZero(dr[4].ToString()),
                                _Convert.Null_to_IntZero(dr[5].ToString()),
                                _Convert.Null_to_IntZero(dr[6].ToString()),
                                _Convert.Null_to_IntZero(dr[7].ToString()),
                                dr[8].ToString(), SystemTree_SelectedNode.Parent.Parent.Name); // cyim 2016.12.05 : 수신기 모델별 내부 로직 변경

                            // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                            _OrderByCircuitNo OrderByCircuitNo = new _OrderByCircuitNo();
                            OrderByCircuitNo.CircuitNo = dev_s.MskId;
                            OrderByCircuitNo.Type = dr[0].ToString();
                            OrderByCircuitNo.Location = dr[1].ToString();
                            OrderByCircuitNo.DeviceNickName = dr[2].ToString();
                            OrderByCircuitNo.EmergencyCode = dr[10].ToString() + "-" + dr[11].ToString() + "-" + dr[12].ToString();
                            OrderByCircuitNo.XML = string.Format("MI{0:00}{1:00}{2:0}{3:000}{4}",
                                Int32.Parse(SystemTree_SelectedNode.Parent.Parent.Name),
                                _Convert.Null_to_IntZero(dr[4].ToString()),
                                _Convert.Null_to_IntZero(dr[5].ToString()),
                                _Convert.Null_to_IntZero(dr[6].ToString()),
                                _Convert.Null_to_IntZero(dr[7].ToString()));

                            SortSupport.Add(OrderByCircuitNo);
                            //DataSet_Point_Input.Tables[0].Rows.Add(
                            //    // No
                            //    (i + 1).ToString(),
                            //    // 회로번호
                            //    dev_s.MskId,
                            //    // 설비종류
                            //    dr[0].ToString(),
                            //    // 위치
                            //    dr[1].ToString(),
                            //    // 디바이스명칭
                            //    dr[2].ToString(),
                            //    // 비상방송
                            //    dr[10].ToString() + "-" + dr[11].ToString() + "-" + dr[12].ToString()
                            //    );
                        }
                    }
                    // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                    SortSupport.Sort(_Data.Sort_CircuitNo);
                    for (int i = 0; i < SortSupport.Count; i++)
                    {
                        _OrderByCircuitNo OrderByCircuitNo = (_OrderByCircuitNo)SortSupport[i];
                        DataSet_Point_Input.Tables[0].Rows.Add(
                            // No
                            //string.Format("{0:d5}", (i + 1)),
                            (i + 1),
                            // 회로번호
                            OrderByCircuitNo.CircuitNo,
                            // 설비종류
                            OrderByCircuitNo.Type,
                            // 위치
                            OrderByCircuitNo.Location,
                            // 디바이스명칭
                            OrderByCircuitNo.DeviceNickName,
                            // 비상방송
                            OrderByCircuitNo.EmergencyCode,
                            // XML
                            OrderByCircuitNo.XML
                            );
                    }

                    // 레포트 생성
                    Form_ActiveReport_Viewer Report = new Form_ActiveReport_Viewer(
                        // 레포트 타입
                        ACTIVE_REPORT_DATA.VARIABLE_HEIGHT,
                        // 실제데이타
                        DataSet_Point_Input.Tables[0].Rows,
                        // 컬럼데이타
                        Point_Input_ColumnHeader,
                        // 제목
                        "입력 포인트 보고서",
                        // 개요
                        string.Format(" 수신기아이디 [ {0} ]  전체 [ {1}건 ]", SystemTree_SelectedNode.Parent.Parent.Name, DataSet_Point_Input.Tables[0].Rows.Count),
                        // 컬럼높이
                        0.21F,
                        // 폰트사이즈
                        8);
                    _Form.Create(Report, null);
                }
                else
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.UsingReportViewer, 0);
            }
            // 출력포인트 보고서
            else if (e.ClickedItem.Text == _Text.PointOutputReport)
            {
                // 레포트 폼생성 
                if (_Data.ActiveReportViewer_Enable == false)
                {
                    // 테이블 생성
                    DataSet DataSet_Point_Output = new DataSet();
                    _Dataset.Create_Table(DataSet_Point_Output);
                    _Dataset.Add_DataColumn(DataSet_Point_Output, ColumnNames_Point_Output, ColumnNames_Point_Output); // 키 정보와 UI 표시부는 동일하다

                    // 매개변수 순서 => COMM_ID, INOUT_TYPE, BOARD_ID, LOOP_NO, REPEATER_ID, POSITION_CODE, DEVICE_TYPE_NAME, DEVICE_NAME               
                    DataRowCollection DB_TABLE_DEVICE = ((_ImportPoint)_Data.Hash_ImportPoint[SystemTree_SelectedNode.Parent.Parent.Name]).OUT_Points;

                    // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                    ArrayList SortSupport = new ArrayList();

                    // DataSet  내용을 수정한다
                    for (int i = 0; i < DB_TABLE_DEVICE.Count; i++)
                    {
                        // 레코드 정보
                        DataRow dr = DB_TABLE_DEVICE[i];

                        if (_Convert.Exception_Into_object(dr[3], dr[4], dr[5], dr[6], dr[7]) == true)
                        {
                            // 매개변수 순서 => COMM_ID, BOARD_ID, LOOP_NO, REPEATER_ID, DEVICE_ID, INOUT_TYPE
                            MskDeviceIDString dev_s = new MskDeviceIDString(
                                _Convert.Null_to_IntZero(dr[3].ToString()),
                                _Convert.Null_to_IntZero(dr[4].ToString()),
                                _Convert.Null_to_IntZero(dr[5].ToString()),
                                _Convert.Null_to_IntZero(dr[6].ToString()),
                                _Convert.Null_to_IntZero(dr[7].ToString()),
                                dr[8].ToString(), SystemTree_SelectedNode.Parent.Parent.Name); // cyim 2016.12.05 : 수신기 모델별 내부 로직 변경

                            // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                            _OrderByCircuitNo OrderByCircuitNo = new _OrderByCircuitNo();
                            OrderByCircuitNo.CircuitNo = dev_s.MskId;
                            OrderByCircuitNo.Type = dr[0].ToString();
                            OrderByCircuitNo.Location = dr[1].ToString();
                            OrderByCircuitNo.DeviceNickName = dr[2].ToString();
                            //_OrderByCircuitNo.EmergencyCode = dr[10].ToString() + "-" + dr[11].ToString() + "-" + dr[12].ToString();

                            SortSupport.Add(OrderByCircuitNo);
                            //DataSet_Point_Output.Tables[0].Rows.Add(
                            //    // No
                            //    (i + 1).ToString(),
                            //    // 회로번호
                            //    dev_s.MskId,
                            //    // 설비종류
                            //    dr[0].ToString(),
                            //    // 위치
                            //    dr[1].ToString(),
                            //    // 디바이스명칭
                            //    dr[2].ToString());
                        }
                    }
                    // cyim 2016.04.01 : 입력 및 출력회로 정렬 기능
                    SortSupport.Sort(_Data.Sort_CircuitNo);
                    for (int i = 0; i < SortSupport.Count; i++)
                    {
                        _OrderByCircuitNo OrderByCircuitNo = (_OrderByCircuitNo)SortSupport[i];
                        DataSet_Point_Output.Tables[0].Rows.Add(
                            // No
                            //string.Format("{0:d5}", (i + 1)),
                            (i + 1),
                            // 회로번호
                            OrderByCircuitNo.CircuitNo,
                            // 설비종류
                            OrderByCircuitNo.Type,
                            // 위치
                            OrderByCircuitNo.Location,
                            // 디바이스명칭
                            OrderByCircuitNo.DeviceNickName
                            // 비상방송
                            //_OrderByCircuitNo.EmergencyCode
                            );
                    }

                    // 레포트 생성
                    Form_ActiveReport_Viewer Report = new Form_ActiveReport_Viewer(
                        // 레포트 타입
                        ACTIVE_REPORT_DATA.VARIABLE_HEIGHT,
                        // 실제데이타
                        DataSet_Point_Output.Tables[0].Rows,
                        // 컬럼데이타
                        Point_Output_ColumnHeader,
                        // 제목
                        "출력 포인트 보고서",
                        // 개요
                        string.Format(" 수신기아이디 [ {0} ]  전체 [ {1}건 ]", SystemTree_SelectedNode.Parent.Parent.Name, DataSet_Point_Output.Tables[0].Rows.Count),
                        // 컬럼높이
                        0.21F,
                        // 폰트사이즈
                        8);
                    _Form.Create(Report, null);
                }
                else
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.UsingReportViewer, 0);
            }
        }

        // 입출력 노드를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_InOut_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 입출력 수정
            if (e.ClickedItem.Text == _Text.INOUTEdit)
            {
                // cyim 2016.12.05 : 수신기 모델별 내부 로직 변경
                if (((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]).MODEL == "IFC3300")
                {
                    // 입출력 설정
                    Form_Receiver_Port_BigReceiver Config_InOut_BigReceiver = new Form_Receiver_Port_BigReceiver(Int32.Parse(SystemTree_SelectedNode.Parent.Name)); // 입출력 노드의 부모 키값 
                    _Form.Create(Config_InOut_BigReceiver, null);
                }
                else
                {
                    // 입출력 설정
                    Form_Receiver_Port Config_InOut = new Form_Receiver_Port(Int32.Parse(SystemTree_SelectedNode.Parent.Name)); // 입출력 노드의 부모 키값 
                    _Form.Create(Config_InOut, null);
                }
            }
        }

        // 그룹 노드를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_OperGroup_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == _Text.ExcelImport) // 엑셀 Import
            {
                // 엑셀 연동 폼					
                Form_PointConfig PointConfig = new Form_PointConfig(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]), SystemTree_SelectedNode.Text);
                _Form.Create(PointConfig, null);
            }
            else if (e.ClickedItem.Text == _Text.OperGroupReport) // 그룹 보고서
            {
                // 레포트 폼생성 
                if (_Data.ActiveReportViewer_Enable == false)
                {
                    //Form_ActiveReport_Viewer Report = new Form_ActiveReport_Viewer(SystemTree_SelectedNode.Parent.Parent.Name, ACTIVE_REPORT_DATA.OPER_GROUP);
                    //_Form.Create(Report, null);

                    // 용량이 크면 화면이 멈춘것처럼 보이므로 팝업창을 출력함
                    Form Temp = _Popup.Create(Popup_Type.ConfirmNoBtn, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.ReportReady, 0);
                    this.Update();
                    _ActiveReport.Create_ReportViewer_OperGroup(SystemTree_SelectedNode.Parent.Parent.Name);
                    Temp.Close();
                }
                else
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.UsingReportViewer, 0);
            }
        }

        // 연동설정 노드를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_OperSet_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem.Text == _Text.ExcelImport) // 엑셀 Import
            {
                // 엑셀 연동 폼					
                Form_PointConfig PointConfig = new Form_PointConfig(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]), SystemTree_SelectedNode.Text);
                _Form.Create(PointConfig, null);
            }
            else if (e.ClickedItem.Text == _Text.OperSetReport) // 연동설정 보고서
            {
                // 레포트 폼생성                           
                if (_Data.ActiveReportViewer_Enable == false)
                {
                    //Form_ActiveReport_Viewer ActiveReportViewer = new Form_ActiveReport_Viewer(SystemTree_SelectedNode.Parent.Parent.Name, ACTIVE_REPORT_DATA.OPER_SET);
                    //_Form.Create(ActiveReportViewer, null);

                    // 용량이 크면 화면이 멈춘것처럼 보이므로 팝업창을 출력함
                    Form Temp = _Popup.Create(Popup_Type.ConfirmNoBtn, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.ReportReady, 0);
                    this.Update();
                    _ActiveReport.Create_ReportViewer_OperSet(SystemTree_SelectedNode.Parent.Parent.Name);
                    Temp.Close();
                }
                else
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.UsingReportViewer, 0);
            }
            else if (e.ClickedItem.Text == _Text.MapProcessFile) // 연동 맵 파일 생성
            {
                //  연동 맵 파일 생성 폼					
                Form_OperSetMapProcessFile OperSetMapProcessFile = new Form_OperSetMapProcessFile(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]));
                _Form.Create(OperSetMapProcessFile, null);
            }
        }

        // 이미지 노드 를 선택한 후 팝업창 출력후 메뉴 선택
        public void Selected_Image_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 이미지 추가
            if (e.ClickedItem.Text == _Text.PageAdd)
            {
                ///
                /// 맵디자이너
                ///

                // 신규 이미지 추가하는 경우에는 오로지 한개의 화면만 존재하면 된다
                // 하지만 기존의 이미지를 편집하는 화면은 여러개의 화면이 존재할수 있다.
                // 주의할점은 기존의 화면을 닫지않는 상태에서 화면으로 돌릴때 폼의 이름으로 포커스를 맞추므로 수동으로 폼 이름을 조절한다
                string Form_MapDesigner_Name = "Form_MapDesigner_New";

                // 신규 이미지 추가용 맵디자이너 화면이 켜져 있는 경우
                if (_Form.CreatedForm.Contains(Form_MapDesigner_Name) == true)
                {
                    // 이벤트 알림
                    _Event.PictrueEdit_NodeSeleted_SendMessage_Write(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]), null);
                }
                // 신규 이미지 추가용 맵디자이너 화면이 켜져 있지 않은 경우
                else
                {
                    // 신규 생성 : 맵디자이너 폼생성 , 수신기 노드 및 그래픽 노드의 정보를 전달 
                    Form_MapDesigner MapDesigner = new Form_MapDesigner(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]).ID, null, null);
                    MapDesigner.Name = Form_MapDesigner_Name;
                    _Form.Create(MapDesigner, null);
                }
            }
            // 모두 삭제
            else if (e.ClickedItem.Text == _Text.PageAllDel)
            {
                string Form_MapDesigner_Name = "Form_MapDesigner_" + SystemTree_SelectedNode.Name;

                // 맵디자이너 화면이 켜져 있는 경우
                if (_Form.CreatedForm.Contains(Form_MapDesigner_Name) == true)
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.MapDesignerActive, 0);
                }
                else
                {
                    Popup_PageAllDelInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 350, 150, _Text.AllDelete_Continue, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_PageAllDel_PopupClose_SendMessage_Event);
                }
            }
            // 동기화
            // 삭제할지도 모름 -> 우선 적용해봄
            else if (e.ClickedItem.Text == _Text.PageSync)
            {
                // 작업중인 페이지가 하나라도 있다면 경고창 팝업 생성

                if (((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]).HASH_PAGE.Count != 0)
                {
                    Popup_XmlSyncStartInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 450, 150, _Text.XmlSyncStartInform, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_XmlSyncStart_PopupClose_SendMessage_Event);
                }
                else
                {
                    // 스레드 시작
                    FieldSettingXml_Sync(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]));
                }
            }
            // 페이지 저장
            else if (e.ClickedItem.Text == _Text.PageSave)
            {
                if (((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]).HASH_PAGE.Count != 0)
                {
                    Popup_PageSaveInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 450, 150, _Text.PageSaveXmlDB, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_PageSaveXmlDB_PopupClose_SendMessage_Event);
                }
                else
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 250, 150, _Text.PageNotInform, 0);
                }
            }
            // 화면 설정 보고서
            else if (e.ClickedItem.Text == _Text.PageReport)
            {
                if (_Data.Enable_Capture == false)
                {
                    _Data.Enable_Capture = true;

                    // 화면 최대화
                    _Event.Windows_MaxSize_SendMessage_Write();

                    // 캡쳐 경고 팝업
                    Capture_Warning = _Popup.Create(Popup_Type.ConfirmNoBtn, Popup_Style.Normal, _Text.Warnning, 250, 150, _Text.CaptureReady, 0);
                    Capture_Warning.Location = new Point(this.Location.X, this.Location.Y); // 위치는 가장자리로 배치

                    // 트리 누르지 못하도록 방지
                    this.treeView_SystemTree.Enabled = false;

                    // 타이머 동작하면서 화면캡쳐 시도
                    Capure_Receiver_ID = SystemTree_SelectedNode.Parent.Name;
                    Caputure_Process_Cnt = 0;
                    Capture_Page_Index = 0;
                    _Timer_WindowBase.Delete("CAPTURE_IMAGE");
                    _Timer_WindowBase.Create("CAPTURE_IMAGE", 1000, CAPTURE_IMAGE_Tick, true);
                }
                else
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 250, 150, _Text.CapturingNotAccess, 0);
            }
        }

        // 특별처리
        // 화면 캡쳐를 위해 타이머를 동작시킨다. 1초마다 번갈아가면서 화면을 선택한후, 캡쳐하는 방식이므로 조작은 금지하도록 유도한다
        private void CAPTURE_IMAGE_Tick(object sender, EventArgs e)
        {
            // 카운터 증가
            Caputure_Process_Cnt++;

            // 페이지 정보 추출
            _RECEIVER RECEIVER = (_RECEIVER)_Data.HASH_RECEIVER[Capure_Receiver_ID];
            if (RECEIVER.LIST_PAGE_ID.Count == 0)
            {
                Capture_Warning.Close();
                _Data.Enable_Capture = false;
                _Timer_WindowBase.Delete("CAPTURE_IMAGE");
                this.treeView_SystemTree.Enabled = true;
                _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 250, 150, "캡쳐할 페이지가 없습니다.", 0);
                return;
            }
            // 1초마다 번갈아가면서 페이지를 선택하고 캡쳐하는 것처럼 동작하게 한다
            if (Caputure_Process_Cnt % 2 == 0)
            {
                // 화면 캡쳐
                _Event.Capture_Save_SendMessage_Write(Capure_Receiver_ID, (string)RECEIVER.LIST_PAGE_ID[Capture_Page_Index]);

                // 페이지 인덱스 증가 (화면 캡쳐 이후에야 인덱스가 증가된다)
                Capture_Page_Index++;
            }
            else
            {
                // 자식노드 검색                
                TreeNode temp_treenode = _Tree.GetNode_By_Name(this.treeView_SystemTree, (string)RECEIVER.LIST_PAGE_ID[Capture_Page_Index]);

                // 화면 전환
                _Event.WorkViewPageName_SendMessage_Write(Capure_Receiver_ID, Object_Type.PAGE, temp_treenode.Name, temp_treenode.Text);
            }

            // 만약 모든 페이지를 돌았다면
            if (((_RECEIVER)_Data.HASH_RECEIVER[Capure_Receiver_ID]).LIST_PAGE_ID.Count * 2 <= Caputure_Process_Cnt)
            {
                // 초기화
                Capture_Warning.Close();
                _Data.Enable_Capture = false;
                _Timer_WindowBase.Delete("CAPTURE_IMAGE");

                // 트리 누르지 못하도록 방지 해제
                this.treeView_SystemTree.Enabled = true;

                Form Temp = _Popup.Create(Popup_Type.ConfirmNoBtn, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.ReportReady, 0);
                this.Update();
                _ActiveReport.Create_ReportViewer_Page(SystemTree_SelectedNode.Parent.Name);
                Temp.Close();
            }
        }

        // 디바이스 정보를 DB에 저장        
        private void DeviceIcon_Save(string RECEIVER_ID)
        {
            // 데이타베이스에 접속하지 못하면 사용못한다

            if (_Db.OpenTest() == true)
            {
                // 작업량 예상
                Popup_DeviceIconSave_Progress_Count_End = 0;
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).LIST_PAGE_ID)
                    foreach (string ICON_ID in ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[PAGE_ID]).LIST_ICON_ID)
                        if (((_PictureBoxItem)((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[PAGE_ID]).HASH_ICON[ICON_ID]).ItemType == Item_Type.Device)
                            Popup_DeviceIconSave_Progress_Count_End++;

                // 카운터 초기화
                Popup_DeviceIconSave_Progress_Count = 0;

                // 진행 팝업창 생성 
                _Data.Result_Text = _Text.CompleteInform; // 진행 결과 메세지
                if (Popup_DeviceIconSave_Progress != null) Popup_DeviceIconSave_Progress.Close();

                // 맵디자이너에서 페이지 저장시에 디바이스 아이콘이 없어도 완료 팝업창이 출력하도록 수정 ( +1 로 수정)
                Popup_DeviceIconSave_Progress = _Popup.Create(Popup_Type.Progress, Popup_Style.Normal, _Text.OK, 250, 200, _Text.DataBaseSaveProgress, Popup_DeviceIconSave_Progress_Count_End + 1);

                // 스레드 생성
                WorkingThread = new Thread(new ParameterizedThreadStart(DeviceIcon_Save_Thread));

                // 스레드시작
                WorkingThread.Start(RECEIVER_ID);
            }
        }

        // 디바이스 정보를 DB에 저장 스레드
        private void DeviceIcon_Save_Thread(object pReceiver_ID)
        {
            string RECEIVER_ID = pReceiver_ID.ToString();

            string Debug_Device_Ope_ID = null;
            try
            {
                // 페이지별로 루틴이 실행된다
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).LIST_PAGE_ID)
                {
                    // 페이지 번호
                    string JumpFiledID = ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[PAGE_ID]).ID;

                    // 점프필드에는 널값이 들어가면 수신기UI 가 에러처리됨 - 2013.6.18
                    JumpFiledID = _Data.Get_Verify_ID(JumpFiledID);

                    _Page Page = ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[PAGE_ID]);

                    // 디바이스 아이콘을 추출해서 아이디를 가져온다
                    foreach (string ICON_ID in Page.LIST_ICON_ID)
                    {
                        if (((_PictureBoxItem)Page.HASH_ICON[ICON_ID]).ItemType == Item_Type.Device)
                        {
                            _PictureBoxItem PictureBoxItem = ((_PictureBoxItem)Page.HASH_ICON[ICON_ID]);

                            // 단, 디바이스 아이콘중 연동아이디가 없는 것은 무시
                            if (PictureBoxItem != null
                                && PictureBoxItem.Device_Oper_ID != null
                                && PictureBoxItem.Device_Oper_ID.ToString().Length != 0)
                            {
                                // 디버깅 용도
                                Debug_Device_Ope_ID = PictureBoxItem.Device_Oper_ID;
                                // 아이디 예시 :MI-01-0-002-1 
                                // 입출력 
                                string InOut = PictureBoxItem.Device_Oper_ID[1].ToString(); // I 혹은 O
                                // 수신기 ID : 1자리로 만들자
                                string Receiver_ID = Page.Receiver_ID;
                                // 통신보드 ID : 1자리로 만들자
                                string ComBoard_ID = Int32.Parse(PictureBoxItem.Device_Oper_ID[3].ToString() + PictureBoxItem.Device_Oper_ID[4].ToString()).ToString();
                                // 계통
                                string Loop_No = PictureBoxItem.Device_Oper_ID[6].ToString();
                                // 중계기 ID 
                                string Repeater_ID = Int32.Parse(PictureBoxItem.Device_Oper_ID[8].ToString() + PictureBoxItem.Device_Oper_ID[9].ToString() + PictureBoxItem.Device_Oper_ID[10].ToString()).ToString();
                                // 중계기 포트번호
                                string Device_ID = PictureBoxItem.Device_Oper_ID[12].ToString();

                                _Db.UPDATE("TB_DEVICE",
                                    // Target Data
                                    "RECEIVER_ID=" + Receiver_ID +
                                    ";BOARD_ID=" + ComBoard_ID +
                                    ";LOOP_NO=" + Loop_No +
                                    ";REPEATER_ID=" + Repeater_ID +
                                    ";DEVICE_ID=" + Device_ID +
                                    ";INOUT_TYPE=" + InOut,
                                    // Updata Data
                                    "JUMP_FIELD_ID=" + JumpFiledID);
                            }

                            // 진행바 카운터가 증가한다                      
                            _Event.ProgressPopupCount_SendMessage(Popup_DeviceIconSave_Progress, ++Popup_DeviceIconSave_Progress_Count);
                        }
                    }
                }

                // 저장하면 리스트에서 삭제
                if (_Data.LIST_XmlDBNotSave_Receiver.Contains(RECEIVER_ID) == true)
                    _Data.LIST_XmlDBNotSave_Receiver.Remove(RECEIVER_ID);

                // 맵디자이너에서 페이지 저장시에 디바이스 아이콘이 없어도 완료 팝업창이 출력하도록 수정
                // 즉, 완료후 마지막 카운터 증가 (스레드 시작전에 1개를 플러스 하였음)
                _Event.ProgressPopupCount_SendMessage(Popup_DeviceIconSave_Progress, ++Popup_DeviceIconSave_Progress_Count);

                // 저장하면 이벤트 발생
                _Event.Receiver_PageSaveComplete_SendMessage_Write(RECEIVER_ID);
            }
            catch (Exception ex)
            {
                // LOG                
                _Event.DebugView_SendMessage_Write(Debug_Device_Ope_ID + _Text.Blank + ex.ToString());

                // 진행바 팝업창 종료                                  
                _Data.Result_Text = _Text.FailInform;
                _Event.ProgressPopupCount_SendMessage(Popup_DeviceIconSave_Progress, Popup_DeviceIconSave_Progress_Count_End);

                // 스레드 중지
                if (WorkingThread != null) WorkingThread.Abort();
            }
        }

        // 수신기 전부 삭제 여부 팝업창 이벤트
        public void _Event_ReceiverAllDel_PopupClose_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;
            if (Popup_ReceiverAllDelInform.Name == popup.Name && etc.ToString() == _Text.OK)
            {
                ReceiverAllDel();
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_ReceiverAllDel_PopupClose_SendMessage_Event);
        }

        public void ReceiverAllDel()
        {
            //// 프로젝트명 임시 저장
            //string temp = this.treeView_SystemTree.Nodes[0].Text;
            //// 트리 삭제
            //this.treeView_SystemTree.Nodes.Clear();
            //// 트리에 기존의 프로젝트명은 그대로 표시한다
            //_Tree.NodeAdd_Root(this.treeView_SystemTree, _Text.UI_TREE_ROOT_KEY, temp, Object_Type.PROJECT);

            // 해쉬 및 리스트 초기화
            _Data.HASH_RECEIVER.Clear();
            _Data.LIST_RECEIVER_ID.Clear();
            _Data.HASH_XMLDEVTYPE.Clear();
            _Data.LIST_XMLDEVTYPE_ID.Clear();
            //_Data.HASH_PAGE.Clear();
            //_Data.LIST_PAGE_ID.Clear();
            // _Receiver.xml 제거 : cyim 2012.8.29 -> 복구 2013.5.27
            //_Data.HASH_XMLRECEIVER.Clear();
            _Data.LIST_XMLRECEIVER_ID.Clear();
            _Data.List_ExcelPoint.Clear();
            _Data.HASH_CodePosition.Clear();
            _Data.LIST_CodePosition_NAME.Clear();
            _Data.LIST_XmlDBNotSave_Receiver.Clear();
            _Data.Hash_ImportPoint.Clear();

            // 수신기 아이디 초기화
            _Data.INIT_RECEIVER_ID = 1;

            // 데이타베이스 경로 초기화
            _Data.DB_FullPath = null;

            // 프로세스 삭제

            System.Diagnostics.Process[] mProcess = System.Diagnostics.Process.GetProcessesByName("fbserver");
            foreach (System.Diagnostics.Process p in mProcess)
                p.Kill();
            System.Threading.Thread.Sleep(1000);

            //
            // 수신기 폴더 삭제
            //

            // 지정된 경로에 폴더 조회
            string result = _File.Get_FolderNameList(_Data.Project_Path + "\\" + _Data.Project_Name);
            if (result != null)
            {
                // 폴더리스트 생성
                string[] FolderNames = _Convert.String_to_ArrayString(result);
                // 폴더 삭제
                foreach (string FolderName in FolderNames)
                    if (FolderName != _Text.DEFALUT_FOLDER_TEMP) // 전체삭제시 Temp 폴더는 삭제하지 않는다
                        _File.Delete_Folder(_Data.Project_Path, _Data.Project_Name + "\\" + FolderName);
            }

            // 수신기 파일 갱신
            _File.Write_Receiver_XML(_Data.Project_Path + "\\" + _Data.Project_Name);

            // 경로 재지정 (temp를 지운다)
            _Data.DataBaseFilePath_Set(null);

            // 데이타베이스에서 삭제
            _Sql.Delete_Table("TB_BOARD", null);
            _Sql.Delete_Table("TB_COMM", null);
            _Sql.Delete_Table("TB_CONFIG", null);
            _Sql.Delete_Table("TB_DEVICE", null);
            _Sql.Delete_Table("TB_ANALOG_DEVICE_2", null);
            _Sql.Delete_Table("TB_EMERGENCY_BROADCASTION", null);
            _Sql.Delete_Table("TB_GROUP_DEVICE", null);
            _Sql.Delete_Table("TB_MAP", null);
            _Sql.Delete_Table("TB_MAP_PROCESS", null);
            _Sql.Delete_Table("TB_GROUP", null);
            _Sql.Delete_Table("TB_GROUP_DEVICE", null);
            _Sql.Delete_Table("TB_RECEIVER", null);
            _Sql.Delete_Table("TB_REPEATER", null);
            _Sql.Delete_Table("TB_POSITION_CODE", null);// 전체 삭제의 경우 삭제해도 상관없음
            //_Sql.Delete_Table("TB_DEVICE_TYPE", null);// -> RECEIVER_ID 없음 // 삭제하면 안됨 (어차피 기본값)

            // 워크뷰에 알림
            _Event.WorkView_Clear_SendMessage_Write();
            _Event.TreeView_Clear_SendMessage_Write(_Data.Project_Name);
        }

        // 수신기 삭제 여부 팝업창 이벤트
        public void _Event_ReceiverDel_PopupClose_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;
            if (Popup_ReceiverAllDelInform.Name == popup.Name && etc.ToString() == _Text.OK)
            {
                // 리스트 및 해쉬에 반영
                foreach (string RECEIVER_ID in _Data.LIST_RECEIVER_ID)
                {
                    if (SystemTree_SelectedNode.Name == RECEIVER_ID)
                    {
                        _Data.HASH_RECEIVER.Remove(SystemTree_SelectedNode.Name);
                        _Data.LIST_RECEIVER_ID.Remove(SystemTree_SelectedNode.Name);
                        _Data.LIST_XMLRECEIVER_ID.Remove(SystemTree_SelectedNode.Name);
                        _Data.Hash_ImportPoint.Remove(SystemTree_SelectedNode.Name);

                        // 경로 재지정 (temp를 지운다)
                        _Data.DataBaseFilePath_Set(null);

                        // 데이타베이스에서 삭제
                        _Sql.Delete_Table("TB_BOARD", RECEIVER_ID);
                        _Sql.Delete_Table("TB_COMM", RECEIVER_ID);
                        _Sql.Delete_Table("TB_CONFIG", RECEIVER_ID);
                        _Sql.Delete_Table("TB_DEVICE", RECEIVER_ID);
                        _Sql.Delete_Table("TB_ANALOG_DEVICE_2", RECEIVER_ID);
                        _Sql.Delete_Table("TB_EMERGENCY_BROADCASTION", RECEIVER_ID);
                        _Sql.Delete_Table("TB_GROUP_DEVICE", RECEIVER_ID);
                        _Sql.Delete_Table("TB_MAP", RECEIVER_ID);
                        _Sql.Delete_Table("TB_MAP_PROCESS", RECEIVER_ID);
                        _Sql.Delete_Table("TB_GROUP", RECEIVER_ID);
                        _Sql.Delete_Table("TB_GROUP_DEVICE", RECEIVER_ID);
                        _Sql.Delete_Table("TB_RECEIVER", RECEIVER_ID);
                        _Sql.Delete_Table("TB_REPEATER", RECEIVER_ID);
                        //_Sql.Delete_Table("TB_POSITION_CODE", RECEIVER_ID);// -> RECEIVER_ID 없음 // 삭제하면 안됨 
                        //_Sql.Delete_Table("TB_DEVICE_TYPE", RECEIVER_ID);// -> RECEIVER_ID 없음 // 삭제하면 안됨
                        break;
                    }
                }

                // 데이타베이스 경로 초기화
                _Data.DB_FullPath = null;

                // 프로세스 삭제
                System.Diagnostics.Process[] mProcess = System.Diagnostics.Process.GetProcessesByName("fbserver");
                foreach (System.Diagnostics.Process p in mProcess)
                    p.Kill();
                System.Threading.Thread.Sleep(1000);

                // 수신기 폴더 삭제
                string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + SystemTree_SelectedNode.Name;
                _File.Delete_Folder(_Data.Project_Path, _Data.Project_Name + "\\" + ReiceiverFolderName);

                // 수신기 파일 갱신
                _File.Write_Receiver_XML(_Data.Project_Path + "\\" + _Data.Project_Name);

                // 화면 전환
                _Event.WorkViewPageName_SendMessage_Write(null, Object_Type.PROJECT, null, null);

                // 트리에 반영
                _Tree.DelNodeName_By_Name(this.treeView_SystemTree, SystemTree_SelectedNode.Name);
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_ReceiverDel_PopupClose_SendMessage_Event);
        }


        // 페이지 전부 삭제 여부 팝업창 이벤트
        public void _Event_PageAllDel_PopupClose_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;
            if (Popup_PageAllDelInform.Name == popup.Name && etc.ToString() == _Text.OK)
            {
                // 반드시 한단계 위에 수신기 노드가 있다
                string Temp_Receiver_ID = SystemTree_SelectedNode.Parent.Name;

                // 무조건 편집 혹은 새로만들기의 경우 차후 저장을 위해 셋팅
                if (_Data.LIST_XmlDBNotSave_Receiver.Contains(Temp_Receiver_ID) == false)
                    _Data.LIST_XmlDBNotSave_Receiver.Add(Temp_Receiver_ID);

                // 트리에서 전부 삭제
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).LIST_PAGE_ID)
                    _Tree.DelNodeName_By_Name_Check_ReceiverID(this.treeView_SystemTree, ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).HASH_PAGE[PAGE_ID]).NodeKey, Temp_Receiver_ID);

                // 리스트 및 해쉬 삭제
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).LIST_PAGE_ID.Clear();
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).HASH_PAGE.Clear();

                // FieldSetting.xml 초기화

                // 수신기 폴더명
                string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + Temp_Receiver_ID;

                // 경로 지정
                string Default_Xml_FullPath = _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_XML;

                // 기본 내용으로 변경 (FieldSetting_XML)
                _File.Write_FieldSetting_XML(Temp_Receiver_ID, Default_Xml_FullPath);

                // 화면 전환
                _Event.WorkViewPageName_SendMessage_Write(Temp_Receiver_ID, Object_Type.IMAGE, null, null);
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_PageAllDel_PopupClose_SendMessage_Event);
        }

        // 동기화를 진행하려는 경우 작업중인 페이지가 있다고 경고창을 생성하고 난후에 확인 버튼을 누를때 발생하는 이벤트
        public void _Event_XmlSyncStart_PopupClose_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;
            if (Popup_XmlSyncStartInform.Name == popup.Name && etc.ToString() == _Text.OK)
            {
                ///
                /// 페이지 노드를 삭제한다
                ///

                // 트리에서 전부 삭제
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).LIST_PAGE_ID)
                    _Tree.DelNodeName_By_Name_Check_ReceiverID(this.treeView_SystemTree, ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE[PAGE_ID]).NodeKey, Temp_RECEIVER.ID);

                // 리스트 및 해쉬 삭제
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).LIST_PAGE_ID.Clear();
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE.Clear();

                // 스레드 시작
                FieldSettingXml_Sync(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]));
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_XmlSyncStart_PopupClose_SendMessage_Event);
        }

        // 페이지저장 (XML 및 DB 저장) 이벤트
        public void _Event_PageSaveXmlDB_PopupClose_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;

            if (Popup_PageSaveInform.Name == popup.Name && etc.ToString() == _Text.OK)
            {
                // 밑에 코드 삭제 - cyim 무조건 저장루틴을 타도록 만듬 2013.7.4
                //// 컬렉션 개체의 복사본으로 돌린다
                //ArrayList Temp_LIST_XmlDBNotSave_Receiver = new ArrayList();
                //object Temp=_Data.LIST_XmlDBNotSave_Receiver.Clone();
                //Temp_LIST_XmlDBNotSave_Receiver = (ArrayList)Temp; 

                //foreach (string RECEIVER_ID in Temp_LIST_XmlDBNotSave_Receiver)
                _Event_Page_Save_SendMessage_Event(SystemTree_SelectedNode.Parent.Name);
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_PageSaveXmlDB_PopupClose_SendMessage_Event);
        }

        public void _Event_Page_Save_SendMessage_Event(string RECEIVER_ID)
        {
            ///
            /// FieldSetting.xml 쓰기
            ///

            // 맵디자이너 XML 데이터 저장
            // 현재 DevType.xml 데이터는 오로지 읽기 전용이며
            // FieldSetting.xml 데이터는 쓰기 전용이다

            // 수신기 폴더명
            //string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + ((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Name]).ID;
            string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + ((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).ID;

            _File.Write_FieldSetting_XML(RECEIVER_ID, _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_XML);

            ///
            /// Receiver.xml 쓰기 (임시-오후 2:25 2012-08-23) 
            ///

            //_File.Write_Receiver_XML(_Data.Project_Path + "\\" + _Data.Project_Name);

            ///
            /// TB_DEVICE -> 디바이스 아이콘이 속해져있는 페이지 번호 아이디를 JumpFieldID 로 치환하여 수정함
            ///

            DeviceIcon_Save(RECEIVER_ID);


            // LOG
            _Event.DebugView_SendMessage_Write(_Text.SaveFieldSettingInform);
        }

        /// 
        /// 초기화
        /// 

        public void _Event_TreeView_Clear_SendMessage_Event(string ProjectName)
        {
            // 트리 초기화
            this.treeView_SystemTree.Nodes.Clear();

            // 프로젝트명이 없다면 프로젝트 삭제
            if (ProjectName != null)
                _Tree.NodeAdd_Root(this.treeView_SystemTree, _Text.UI_TREE_ROOT_KEY, ProjectName, Object_Type.PROJECT);
        }

        public void _Event_Receiver_Clear_SendMessage_Event()
        {
            ReceiverAllDel();
        }

        //
        // 수신기 모델명 변경
        //

        // cyim 2016.12.05 : 트리뷰에 수신기 모델 표시 
        delegate void CallBack_DataApplytoGridex_Receiver_Set(string RECEIVER_ID);
        public void _Event_WorkViewPageName_Receiver_SendMessage_Event(string RECEIVER_ID)
        {
            if (this.InvokeRequired)
            {
                CallBack_DataApplytoGridex_Receiver_Set d = new CallBack_DataApplytoGridex_Receiver_Set(_Event_WorkViewPageName_Receiver_SendMessage_Event);
                this.Invoke(d, new object[] { RECEIVER_ID });
            }
            else
            {
                _RECEIVER RECEIVER = (_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID];
                _Tree.SetNodeText_By_Name(this.treeView_SystemTree, RECEIVER.ID, RECEIVER.KEY_NAME);
            }
        }

        /// 
        /// 동기화
        /// 

        // 파일을 읽는 스레드
        public void FieldSettingXml_Sync(_RECEIVER RECEIVER)
        {
            try
            {
                // 수신기 폴더명
                string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + RECEIVER.ID;

                // 경로
                string Default_Xml_FullPath = _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_XML;

                // 파일 읽기
                ArrayList Result = _File.Read_FieldSetting_XML(Default_Xml_FullPath);

                // 임시로 현재 추가하는 수신기 정보를 저장하고 스레드를 실행시킨다
                Temp_RECEIVER = RECEIVER;

                // 파일이 없거나 페이지 정보가 없다면 사용못한다
                if (Result != null && Result.Count != 0)
                {
                    // 현재 생성중인 맵디자이너 창을 닫는다
                    _Event.MapDesigner_Close_SendMessage_Write();

                    // 트리에서 전부 삭제
                    foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER.ID]).LIST_PAGE_ID)
                        _Tree.DelNodeName_By_Name_Check_ReceiverID(this.treeView_SystemTree, ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER.ID]).HASH_PAGE[PAGE_ID]).NodeKey, RECEIVER.ID);

                    // 작업량 예상
                    Popup_XmlSyncStartProgress_Count_End = 0;
                    foreach (_FieldSetting FieldSetting in Result)
                    {
                        // 페이지수
                        Popup_XmlSyncStartProgress_Count_End++;
                        // 버튼 아이콘
                        foreach (_FieldSetting_Button FieldSetting_Button in FieldSetting.Button)
                            Popup_XmlSyncStartProgress_Count_End++;
                        // 디바이스 아이콘
                        foreach (_FieldSetting_Device FieldSetting_Device in FieldSetting.Device)
                            Popup_XmlSyncStartProgress_Count_End++;
                    }

                    // 카운터 초기화
                    Popup_XmlSyncStartProgress_Count = 0;

                    // 진행 팝업창 생성 
                    _Data.Result_Text = _Text.CompleteInform; // 진행 결과 메세지
                    if (Popup_XmlSyncStartProgress != null) Popup_XmlSyncStartProgress.Close();
                    Popup_XmlSyncStartProgress = _Popup.Create(Popup_Type.Progress, Popup_Style.Normal, _Text.OK, 250, 200, _Text.XmlSyncProgress, Popup_XmlSyncStartProgress_Count_End);

                    // 스레드 생성
                    Thread WorkingThread = new Thread(new ParameterizedThreadStart(FieldSettingXml_Sync_Thread));

                    // 스레드시작
                    WorkingThread.Start(Result);
                }
                else
                {
                    // 수신기 추가를 완료하였습니다!
                    _Event.Receiver_NodeAddComplete_SendMessage_Write(RECEIVER.ID);
                }
            }
            catch (Exception ex)
            {
                // LOG                
                _Event.DebugView_SendMessage_Write(ex.ToString());
                // 스레드 중지
                if (WorkingThread != null) WorkingThread.Abort();

                _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 450, 150, _Text.XmlSyncFileNotInform, 0);
            }
        }

        // 동기화 진행 스레드
        public void FieldSettingXml_Sync_Thread(object result)
        {
            Form_MapDesigner Temp_MapDesigner = null;

            try
            {

                // 수신기 폴더명
                string ReiceiverFolderName = _Text.DEFAULT_FOLDER_RECEIVER_PREFIX + Temp_RECEIVER.ID;

                // 경로 지정
                string Default_Xml_FullPath = _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_XML;
                string Default_Field_FullPath = _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_FIELD;
                string Default_Symbol_FullPath = _Data.Project_Path + "\\" + _Data.Project_Name + "\\" + ReiceiverFolderName + "\\" + _Text.DEFAULT_FOLDER_MAPVIEW + "\\" + _Text.DEFAULT_FOLDER_SYMBOL;


                // 파일 읽기
                //ArrayList Result = _File.Read_FieldSetting_XML(Default_Xml_FullPath);
                ArrayList Result = (ArrayList)result;

                // 리스트 및 해쉬 삭제
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE.Clear();
                ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).LIST_PAGE_ID.Clear();

                // 리스트 및 해쉬에 반영
                foreach (_FieldSetting FieldSetting in Result)
                {
                    _Page Page = new _Page();

                    // 페이지 아이디
                    Page.ID = FieldSetting.ID;
                    // 페이지 이름
                    Page.NodeKey = _Data.CREATE_PAGE_ID(Temp_RECEIVER.ID, FieldSetting.Name);// Temp_RECEIVER.ID + _Text.Minus + FieldSetting.Name;
                    Page.NodeText = FieldSetting.Name;
                    // 관할 수신기 아이디
                    Page.Receiver_ID = FieldSetting.Receiver_ID;

                    // 배경그림을 저장하기 위해서 임시 맵디자이너 클래스 생성
                    Temp_MapDesigner = new Form_MapDesigner(Page.Receiver_ID, null, null);

                    // 배경그림
                    Page.PictureBoxItem_BackGround = Temp_MapDesigner.UI_Create_PictureBoxItem(
                        null,
                        Item_Type.BackGround,
                        Default_Field_FullPath + "\\" + FieldSetting.IMAGE,
                        FieldSetting.IMAGE,
                        Page.NodeKey,
                        0, 0);

                    // 진행바 카운터가 증가한다                      
                    _Event.ProgressPopupCount_SendMessage(Popup_XmlSyncStartProgress, ++Popup_XmlSyncStartProgress_Count);

                    if (Page.PictureBoxItem_BackGround != null)
                    {
                        // 아이콘 번호
                        int ICON_ID_Order = 0;

                        // 버튼 아이콘
                        foreach (_FieldSetting_Button FieldSetting_Button in FieldSetting.Button)
                        {
                            _PictureBoxItem PictureBoxItem = new _PictureBoxItem();

                            // 버튼의 경우 순번이 B자가 붙어서 시작한다. 제거한다
                            //string Icon_ID = FieldSetting_Button.ID.Remove(0,1);// 특별히 XML 문서에서 버튼 아이디를 그대로 사용하지않고 순번으로 치환해서 사용해야함
                            string Icon_ID = ICON_ID_Order++.ToString();

                            // 픽쳐박스 생성
                            PictureBoxItem = Temp_MapDesigner.UI_Create_PictureBoxItem(
                                Page.PictureBoxItem_BackGround,
                                Item_Type.Button,
                                Default_Field_FullPath + "\\" + FieldSetting_Button.Image,
                                FieldSetting_Button.Image,
                                Icon_ID,
                                Int32.Parse(FieldSetting_Button.Xposition),
                                Int32.Parse(FieldSetting_Button.Yposition));

                            if (PictureBoxItem != null)
                            {
                                /// 
                                /// 동적 할당 변수 처리
                                /// 

                                // 버튼의 경우 일단 사이즈가 XML 우선시 한다
                                //PictureBoxItem.Width = Int32.Parse(FieldSetting_Button.Width);
                                //PictureBoxItem.Height = Int32.Parse(FieldSetting_Button.Height);

                                // 점프페이지 (페이지 아이디를 이름으로 대체한다)                    
                                PictureBoxItem.Button_JumpPageName = _File.Read_Page_ID_Order(Result, FieldSetting_Button.JumpField);

                                // 리스트 추가
                                Page.LIST_ICON_ID.Add(Icon_ID);
                                // 해쉬 추가
                                Page.HASH_ICON.Add(Icon_ID, PictureBoxItem);
                            }
                            else
                            {
                                // LOG                
                                _Event.DebugView_SendMessage_Write(_Text.FieldSettingXmlFailInform + _Text.LeftBracket + FieldSetting.IMAGE + ":" + FieldSetting_Button.Image + ":" + FieldSetting_Button.ID + ":" + FieldSetting_Button.NAME + _Text.RightBracket);
                            }

                            // 진행바 카운터가 증가한다                      
                            _Event.ProgressPopupCount_SendMessage(Popup_XmlSyncStartProgress, ++Popup_XmlSyncStartProgress_Count);
                        }


                        // 디바이스 아이콘
                        foreach (_FieldSetting_Device FieldSetting_Device in FieldSetting.Device)
                        {
                            _PictureBoxItem PictureBoxItem = new _PictureBoxItem();

                            // 실제 디바이스 아이콘의 파일이름
                            string TempFileName = ((_DevTypeXML)_File.Read_DevType_FileName_by_IconID(FieldSetting_Device.DevIconID)).FILENAME;

                            if (TempFileName != null)
                            {
                                string Icon_ID = ICON_ID_Order++.ToString();

                                // 픽쳐박스 생성
                                PictureBoxItem = Temp_MapDesigner.UI_Create_PictureBoxItem(
                                    Page.PictureBoxItem_BackGround,
                                    Item_Type.Device,
                                    Default_Symbol_FullPath + "\\" + TempFileName,
                                    TempFileName,
                                    Icon_ID,
                                    Int32.Parse(FieldSetting_Device.Xposition),
                                    Int32.Parse(FieldSetting_Device.Yposition));

                                if (PictureBoxItem != null)
                                {
                                    /// 
                                    /// 동적 할당 변수 처리
                                    /// 

                                    // 디바이스 연동 회로 번호 (포맷에 맞게 변환한다)                        
                                    PictureBoxItem.Device_Oper_ID = _File.Read_Device_Oper_ID(FieldSetting_Device.ID);

                                    // 데이타베이스로 부터 디바이스 명칭을 불러온다
                                    MskDeviceIDString device_id = new MskDeviceIDString(PictureBoxItem.Device_Oper_ID, Page.Receiver_ID); // cyim 2016.12.05 : 수신기 모델별 내부 로직 변경

                                    DataRowCollection DB_TABLE_DEVICE =
                                        _Db.ExecuteRead_SqlDataAdapter(_Sql.SearchDeviceName_Table_Value("TB_DEVICE",
                                            "RECEIVER_ID", Page.Receiver_ID,
                                            "COMM_ID", device_id.Comm_id,
                                            "BOARD_ID", device_id.Board_id,
                                            "LOOP_NO", device_id.Loop_no,
                                            "REPEATER_ID", device_id.Repeater_id,
                                            "DEVICE_ID", device_id.Device_id,
                                            "INOUT_TYPE", device_id.Inout_type,
                                            Page.Receiver_ID));

                                    if (DB_TABLE_DEVICE != null)
                                    {
                                        foreach (DataRow dr in DB_TABLE_DEVICE)
                                        {
                                            PictureBoxItem.Device_DB_Name = dr[0].ToString();
                                        }
                                    }

                                    // 리스트 추가
                                    Page.LIST_ICON_ID.Add(Icon_ID);
                                    // 해쉬 추가
                                    Page.HASH_ICON.Add(Icon_ID, PictureBoxItem);
                                }
                            }
                            else
                            {
                                // LOG                
                                _Event.DebugView_SendMessage_Write(_Text.FieldSettingXmlFailInform + _Text.LeftBracket + FieldSetting.IMAGE + ":" + FieldSetting_Device.DevIconID + ":" + FieldSetting_Device.ID + _Text.RightBracket);
                            }

                            // 진행바 카운터가 증가한다                      
                            _Event.ProgressPopupCount_SendMessage(Popup_XmlSyncStartProgress, ++Popup_XmlSyncStartProgress_Count);
                        }

                        // 해쉬 추가
                        if (_Hash.Add(((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE, Page.NodeKey, Page) == true)
                        {
                            ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).LIST_PAGE_ID.Add(Page.NodeKey);
                        }

                        // 임시로 사용한 맵디자이너는 삭제
                        Temp_MapDesigner.Close();
                    }
                    else
                    {
                        // LOG                
                        _Event.DebugView_SendMessage_Write(_Text.FieldSettingXmlFailInform + _Text.LeftBracket + FieldSetting.IMAGE + _Text.RightBracket);

                        // 임시로 사용한 맵디자이너는 삭제
                        if (Temp_MapDesigner != null) Temp_MapDesigner.Close();

                        // 진행바 팝업창 종료                                  
                        _Data.Result_Text = _Text.FailInform;
                        _Event.ProgressPopupCount_SendMessage(Popup_XmlSyncStartProgress, Popup_XmlSyncStartProgress_Count_End);

                        // 스레드 중지
                        if (WorkingThread != null) WorkingThread.Abort();
                    }
                }

                // 스레드 완료후 최종 함수
                FieldSettingXml_Sync_Thread_Complete();
            }
            catch (Exception ex)
            {
                // LOG                
                _Event.DebugView_SendMessage_Write(ex.ToString());

                // 임시로 사용한 맵디자이너는 삭제
                if (Temp_MapDesigner != null) Temp_MapDesigner.Close();

                // 진행바 팝업창 종료                                  
                _Data.Result_Text = _Text.FailInform;
                _Event.ProgressPopupCount_SendMessage(Popup_XmlSyncStartProgress, Popup_XmlSyncStartProgress_Count_End);

                // 스레드 중지
                if (WorkingThread != null) WorkingThread.Abort();
            }
        }

        // 스레드 종료직전 호출되는 함수
        private void FieldSettingXml_Sync_Thread_Complete()
        {
            if (this.treeView_SystemTree.InvokeRequired)
            {
                TreeView_SyncXmlDataNodeCallback d = new TreeView_SyncXmlDataNodeCallback(FieldSettingXml_Sync_Thread_Complete);
                this.treeView_SystemTree.Invoke(d, new object[] { });
            }
            else
            {
                // 생성된 리스트와 해쉬테이블을 토대로 트리에 반영
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).LIST_PAGE_ID)
                {
                    // 해당 수신기 노드 정보
                    TreeNode ReceiverNode = _Tree.GetNode_By_Name(this.treeView_SystemTree, Temp_RECEIVER.ID);

                    // 해당 그래픽 노드 키정보 가져옴
                    string temp_key = Temp_RECEIVER.Set_SubKey(Temp_RECEIVER, _Text.UI_TREE_IMAGE);
                    TreeNode ImageNode = _Tree.GetNode_By_Name(this.treeView_SystemTree, temp_key);

                    string Temp_NodeKey = ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE[PAGE_ID]).NodeKey;
                    string Temp_NodeText = ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[Temp_RECEIVER.ID]).HASH_PAGE[PAGE_ID]).NodeText;

                    // 그래픽 노드 밑에 페이지 노드를 추가한다 
                    _Tree.NodeAdd_Root_Node_Node_Node(this.treeView_SystemTree, 0, ReceiverNode.Index, ImageNode.Index, Temp_NodeKey, Temp_NodeText, Object_Type.PAGE);

                    // 그래픽 노드 모두 펼침
                    ImageNode.Expand();
                }

                // 수신기 추가를 완료하였습니다!
                _Event.Receiver_NodeAddComplete_SendMessage_Write(Temp_RECEIVER.ID);
            }
        }

        // 페이지 노드를 선택한 후 팝업창 출력후 메뉴선택
        public void Selected_Page_Menustrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            // 페이지 삭제
            if (e.ClickedItem.Text == _Text.PageDel)
            {
                string Form_MapDesigner_Name = "Form_MapDesigner_" + SystemTree_SelectedNode.Name;

                // 맵디자이너 화면이 켜져 있는 경우
                if (_Form.CreatedForm.Contains(Form_MapDesigner_Name) == true)
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.MapDesignerActive, 0);
                }
                else
                {
                    Popup_PageDelInform = _Popup.Create(Popup_Type.Dialog, Popup_Style.Normal, _Text.OK, 350, 150, _Text.PageDelDataInform, 0);

                    // 대화 팝업은 특별처리
                    _Event.PopupClose_SendMessage_Event += new _Event.PopupClose_SendMessage_Handler(_Event_Popup_PageDelInform_SendMessage_Event);
                }
            }
            // 페이지 수정
            else if (e.ClickedItem.Text == _Text.PageEdit)
            {
                // 신규 이미지 추가하는 경우에는 오로지 한개의 화면만 존재하면 된다
                // 하지만 기존의 이미지를 편집하는 화면은 여러개의 화면이 존재할수 있다.
                // 주의할점은 기존의 화면을 닫지않는 상태에서 화면으로 돌릴때 폼의 이름으로 포커스를 맞추므로 수동으로 폼 이름을 조절한다
                string Form_MapDesigner_Name = "Form_MapDesigner_" + SystemTree_SelectedNode.Name;

                // 맵디자이너 화면이 켜져 있는 경우
                if (_Form.CreatedForm.Contains(Form_MapDesigner_Name) == true)
                {
                    // 이벤트 알림
                    _Event.PictrueEdit_NodeSeleted_SendMessage_Write(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]), SystemTree_SelectedNode.Name);
                }
                else
                {
                    // 신규 생성 : 맵디자이너 폼생성 , 수신기 노드 및 그래픽 노드의 정보를 전달 
                    Form_MapDesigner MapDesigner = new Form_MapDesigner(((_RECEIVER)_Data.HASH_RECEIVER[SystemTree_SelectedNode.Parent.Parent.Name]).ID, SystemTree_SelectedNode.Name, SystemTree_SelectedNode.Text);
                    MapDesigner.Name = Form_MapDesigner_Name;
                    _Form.Create(MapDesigner, null);
                }
            }
            // 이름 변경
            else if (e.ClickedItem.Text == _Text.PageRename)
            {
                string Form_MapDesigner_Name = "Form_MapDesigner_" + SystemTree_SelectedNode.Name;

                // 맵디자이너 화면이 켜져 있는 경우
                if (_Form.CreatedForm.Contains(Form_MapDesigner_Name) == true)
                {
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.MapDesignerActive, 0);
                }
                else
                {
                    Form Page_Rename = new Form_MapDesigner_Rename(SystemTree_SelectedNode.Parent.Parent.Name, SystemTree_SelectedNode.Name, SystemTree_SelectedNode.Text);
                    _Form.Create(Page_Rename, null);
                }
            }
        }

        // 페이지 삭제 여부 팝업창 이벤트
        public void _Event_Popup_PageDelInform_SendMessage_Event(object sender, object etc)
        {
            // 대화 팝업 주체
            Form popup = (Form)sender;
            if (Popup_PageDelInform == popup && etc.ToString() == _Text.OK)
            {
                // 페이지 삭제는 반드시 두단계 위에 수신기 노드가 있다
                string Temp_Receiver_ID = SystemTree_SelectedNode.Parent.Parent.Name;

                // 트리에 반영
                _Tree.DelNodeName_By_Name_Check_ReceiverID(this.treeView_SystemTree, SystemTree_SelectedNode.Name, SystemTree_SelectedNode.Parent.Parent.Name);

                // 리스트 및 해쉬에 반영
                foreach (string PAGE_ID in ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).LIST_PAGE_ID)
                {
                    if (SystemTree_SelectedNode.Name == PAGE_ID)
                    {
                        ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).HASH_PAGE.Remove(SystemTree_SelectedNode.Name);
                        ((_RECEIVER)_Data.HASH_RECEIVER[Temp_Receiver_ID]).LIST_PAGE_ID.Remove(SystemTree_SelectedNode.Name);

                        // 무조건 편집 혹은 새로만들기의 경우 차후 저장을 위해 셋팅
                        if (_Data.LIST_XmlDBNotSave_Receiver.Contains(Temp_Receiver_ID) == false)
                            _Data.LIST_XmlDBNotSave_Receiver.Add(Temp_Receiver_ID);

                        // 화면 전환
                        _Event.WorkViewPageName_SendMessage_Write(Temp_Receiver_ID, Object_Type.IMAGE, null, null);
                        break;
                    }
                }
            }

            // 대화 팝업은 특별처리
            _Event.PopupClose_SendMessage_Event -= new _Event.PopupClose_SendMessage_Handler(_Event_Popup_PageDelInform_SendMessage_Event);
        }


        ///
        /// EVENT 처리부
        ///

        // 폼닫기 이벤트를 등록 (이벤트 핸들러 해제용)
        public void CreateForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 트리뷰에 페이지 노드를 생성 및 편집하기 위한 이벤트 해제
            _Event.TreeView_PageNodeSet_SendMessage_Event -= new _Event.TreeView_PageNodeSet_SendMessage_Handler(_Event_TreeView_PageNodeSet_SendMessage_Event);

            // 트리 추가 이벤트 핸들러 해제            
            _Event.TreeView_ReceiverNodeSet_SendMessage_Event -= new _Event.TreeView_ReceiverNodeSet_SendMessage_Handler(_Event_TreeView_ReceiverNodeSet_SendMessage_Event);

            // 다른이름으로 페이지 명을 변경하여 저장하는 이벤트 핸들러 해제
            _Event.Page_Rename_SendMessage_Event -= new _Event.Page_Rename_SendMessage_Handler(_Event_Page_Rename_SendMessage_Event);

            // 페이지 저장 (XML 및 DB 저장) 이벤트 핸들러 해제
            _Event.Page_Save_SendMessage_Event -= new _Event.Page_Save_SendMessage_Handler(_Event_Page_Save_SendMessage_Event);

            // 트리뷰 초기화 이벤트 및 프로젝트 열기 혹은 새로만들기 겸용 핸들러 등록 
            _Event.TreeView_Clear_SendMessage_Event -= new _Event.TreeView_Clear_SendMessage_Handler(_Event_TreeView_Clear_SendMessage_Event);

            // 수신기 초기화 이벤트 핸들러 해제
            _Event.Receiver_Clear_SendMessage_Event -= new _Event.Receiver_Clear_SendMessage_Handler(_Event_Receiver_Clear_SendMessage_Event);

            // 수신기 추가 및 편집 폼에서 작업 완료 이벤트 핸들러 해제
            _Event.WorkViewPageName_Receiver_SendMessage_Event -= new _Event.WorkViewPageName_Receiver_SendMessage_Handler(_Event_WorkViewPageName_Receiver_SendMessage_Event);
        }

        //// 프로젝트 새로 만들기 이벤트 핸들러 등록
        //public void _Event_Project_New_SendMessage_Event(string ProjectName)
        //{
        //    // 트리 초기화
        //    this.treeView_SystemTree.Nodes.Clear();

        //    // 노드 추가
        //    _Tree.NodeAdd_Root(this.treeView_SystemTree, _Text.UI_TREE_ROOT_KEY, ProjectName, Object_Type.PROJECT); 
        //}

        //// 프로젝트 열기 이벤트
        //public void _Event_Project_Open_SendMessage_Event(string ProjectName)
        //{
        //    // 트리 초기화
        //    this.treeView_SystemTree.Nodes.Clear();

        //    // 프로젝트명 표시
        //    _Tree.NodeAdd_Root(this.treeView_SystemTree, _Text.UI_TREE_ROOT_KEY, ProjectName, Object_Type.PROJECT);

        //    // _Receiver.xml 제거 : cyim 2012.8.29
        //    //// 트리에 표시
        //    //treeView_Read_Receiver_XML();

        //}

        // 다른이름으로 페이지 명을 변경하여 저장하는 이벤트
        public void _Event_Page_Rename_SendMessage_Event(string RECEIVER_ID, string PageNodeKey, string PageNodeText)
        {
            // 트리에 반영
            TreeNode PageReame = _Tree.GetNode_By_Name(this.treeView_SystemTree, PageNodeKey);

            // 임시 저장 
            string temp_BeforePageName = PageReame.Text;

            // 노드 키와 텍스트 정보는 페이지 이름으로 통일한다
            PageReame.Name = PageNodeKey;
            PageReame.Text = PageNodeText;

            // 리스트에 반영
            //((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).LIST_PAGE_ID.Remove(OriginalName);
            //((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).LIST_PAGE_ID.Add(PageName);

            //// 페이지 값 복사
            //_Page Page = ((_Page)((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[OriginalName]);
            //Page.Name=PageName;

            // 해쉬에 반영
            //((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE.Remove(OriginalName);
            //((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE.Add(Page.Name, Page);

            // 페이지명 변경
            ((_Page)(((_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID]).HASH_PAGE[PageNodeKey])).NodeText = PageNodeText;

            // 기존의 버튼의 점프페이지명은 해당 페이지명으로 변경해야한다
            _RECEIVER RECEIVER = (_RECEIVER)_Data.HASH_RECEIVER[RECEIVER_ID];

            // 수신기에 해당하는 페이지 정보 추출
            foreach (string PAGE_ID in RECEIVER.LIST_PAGE_ID)
            {
                _Page Page = ((_Page)RECEIVER.HASH_PAGE[PAGE_ID]);

                // 페이지에 해당하는 아이콘 정보 추출
                foreach (string ICON_ID in Page.LIST_ICON_ID)
                {
                    _PictureBoxItem PictureBoxItem = ((_PictureBoxItem)Page.HASH_ICON[ICON_ID]);

                    // 버튼 아이콘만 추출 (기존의 페이지명이 있는 경우에만)
                    if (PictureBoxItem.ItemType == Item_Type.Button && PictureBoxItem.Button_JumpPageName == temp_BeforePageName)
                    {
                        // 모든 점프페이지명을 변경시켜준다
                        PictureBoxItem.Button_JumpPageName = PageReame.Text;
                    }
                }
            }

            // 무조건 편집 혹은 새로만들기의 경우 차후 저장을 위해 셋팅
            if (_Data.LIST_XmlDBNotSave_Receiver.Contains(RECEIVER_ID) == false)
                _Data.LIST_XmlDBNotSave_Receiver.Add(RECEIVER_ID);

            // 화면 전환
            _Event.WorkViewPageName_SendMessage_Write(RECEIVER_ID, Object_Type.IMAGE, null, null);
        }

        // 트리 노드 생성 및 편집 이벤트 처리
        public void _Event_TreeView_ReceiverNodeSet_SendMessage_Event(_RECEIVER RECEIVER)
        {
            Delegate_New_SystemTree(treeView_SystemTree.Nodes[0], RECEIVER);
        }

        // 트리에 새로운 노드 추가 
        private void Delegate_New_SystemTree(TreeNode pNode, _RECEIVER RECEIVER) // 시스템 트리에 추가하기
        {
            if (this.treeView_SystemTree.InvokeRequired)
            {
                TreeView_SetTextCallback d = new TreeView_SetTextCallback(Delegate_New_SystemTree);
                this.Invoke(d, new object[] { pNode, RECEIVER });
            }
            else
            {
                string temp_key = null;
                string temp_name = null;

                ///
                /// 수신기
                ///

                // 수신기 노드 추가
                temp_key = RECEIVER.ID;
                temp_name = RECEIVER.KEY_NAME;
                _Tree.NodeAdd_Root_Node(treeView_SystemTree, 0, temp_key, temp_name, Object_Type.RECEIVER);
                // 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                TreeNode Added_RECEIVER = _Tree.GetNode_By_Name(treeView_SystemTree, RECEIVER.ID);

                ///
                /// 입출력
                ///

                // 입출력 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_INOUTPUT);
                temp_name = _Text.UI_TREE_INOUTPUT;
                _Tree.NodeAdd_Root_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, temp_key, temp_name, Object_Type.INOUT);
                // 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                TreeNode Added_INOUTPUT = _Tree.GetNode_By_Name(treeView_SystemTree, temp_key);

                // 통신 보드 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_COM_BOARD);
                temp_name = _Text.UI_TREE_COM_BOARD;
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, temp_key, temp_name, Object_Type.COM_BOARD);
                //// 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                //TreeNode Added_COM_BOARD = _Tree.GetNode_By_Name(treeView_SystemTree, temp_key);
                //for (int i = 1; i <= RECEIVER.COM_BOARD_MAX_NUM; i++)
                //{
                //    temp_key = RECEIVER.Set_SubKey(RECEIVER, string.Format(_Text.UI_TREE_COM_BOARD_KEY, i));
                //    temp_name = _Text.UI_TREE_COM_BOARD + i.ToString();
                //    _Tree.NodeAdd_Root_Node_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, Added_COM_BOARD.Index, temp_key, temp_name, Object_Type.COM_BOARDS);
                //}

                // IO 보드 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_IO_BOARD);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, temp_key, _Text.UI_TREE_IO_BOARD, Object_Type.IO_BOARD);
                //// 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                //TreeNode Added_IO_BOARD = _Tree.GetNode_By_Name(treeView_SystemTree, temp_key);
                //for (int i = 1; i <= RECEIVER.IO_BOARD_MAX_NUM; i++)
                //{
                //    temp_key = RECEIVER.Set_SubKey(RECEIVER, string.Format(_Text.UI_TREE_IO_BOARD_KEY, i));
                //    temp_name = _Text.UI_TREE_IO_BOARD + i.ToString();
                //    _Tree.NodeAdd_Root_Node_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, Added_IO_BOARD.Index, temp_key, temp_name, Object_Type.IO_BOARD);
                //}

                // 키패드 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_KEYPAD);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, temp_key, _Text.UI_TREE_KEYPAD, Object_Type.KEYPAD);

                // 비상방송 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_EMERGENCY_BROADCAST);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_INOUTPUT.Index, temp_key, _Text.UI_TREE_EMERGENCY_BROADCAST, Object_Type.EMERGENCY_BROADCAST);

                ///
                /// 포인트
                ///

                // 포인트 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_POINT);
                _Tree.NodeAdd_Root_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, temp_key, _Text.UI_TREE_POINT, Object_Type.POINT);
                // 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                TreeNode Added_POINT = _Tree.GetNode_By_Name(treeView_SystemTree, temp_key);

                // 입력 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_POINT_INPUT);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_POINT.Index, temp_key, _Text.UI_TREE_POINT_INPUT, Object_Type.INPUT);
                // 출력 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_POINT_OUTPUT);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_POINT.Index, temp_key, _Text.UI_TREE_POINT_OUTPUT, Object_Type.OUTPUT);

                ///
                /// 연동
                ///

                // 연동 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_OPER);
                _Tree.NodeAdd_Root_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, temp_key, _Text.UI_TREE_OPER, Object_Type.OPER);
                // 추가한 노드의 정보를 알아야 하위 트리에 추가할수 있다
                TreeNode Added_OPER = _Tree.GetNode_By_Name(treeView_SystemTree, temp_key);

                // 그룹 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_OPER_GROUP);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_OPER.Index, temp_key, _Text.UI_TREE_OPER_GROUP, Object_Type.OPER_GROUP);
                // 연동설정 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_OPER_SET);
                _Tree.NodeAdd_Root_Node_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, Added_OPER.Index, temp_key, _Text.UI_TREE_OPER_SET, Object_Type.OPER_SET);

                ///
                /// 그래픽
                ///

                // 그래픽 노드 추가
                temp_key = RECEIVER.Set_SubKey(RECEIVER, _Text.UI_TREE_IMAGE);
                _Tree.NodeAdd_Root_Node_Node(treeView_SystemTree, 0, Added_RECEIVER.Index, temp_key, _Text.UI_TREE_IMAGE, Object_Type.IMAGE);


                // 트리 전체 확대 
                treeView_SystemTree.ExpandAll();
                //// 트리는 ACU 노드만 표시할수있도록 한다
                //treeView_SystemTree.Nodes[0].Expand();
                //// 추가한 수신기 노드 개수 만큼 열수 있도록 카운트
                //int temp = 0;
                //foreach (string RECEIVER_ID in _Data.LIST_RECEIVER_ID)
                //{
                //    treeView_SystemTree.Nodes[0].Nodes[temp++].Expand();
                //}


                // 트리정보 저장
                _Tree.Save_SystemTreeInfo(this.treeView_SystemTree);

                // 수신기 노드가 추가되면 워크뷰에 리스트를 보여주도록 함 (프로젝트를 클릭한 것처럼 화면 전환)
                _Event.WorkViewPageName_SendMessage_Write(RECEIVER.ID, Object_Type.PROJECT, null, null);

                // 수신기 추가는 무조건
                this.treeView_SystemTree.SelectedNode = _Tree.GetNode_By_Name(treeView_SystemTree, _Text.UI_TREE_ROOT_KEY);

                ///
                /// 강제 페이지 동기화
                ///

                // 페이지 동기화 루틴 추가
                FieldSettingXml_Sync(RECEIVER);

            }

        }

        // 트리뷰에 페이지 노드를 생성 및 편집하기 위한 이벤트 (예시 : 맵디자이너에서 페이지 추가)        
        private void _Event_TreeView_PageNodeSet_SendMessage_Event(string RECEIVER_ID, _Page Page)
        {
            // 해당 수신기 노드 정보
            TreeNode ReceiverNode = _Tree.GetNode_By_Name(this.treeView_SystemTree, RECEIVER_ID);

            // 그래픽 노드 밑에 페이지 노드를 추가한다 (그래픽 노드의 키값 형태 : RECEIVER.ID + _Text.Minus + PORT_NUM)
            TreeNode ImageNode = _Tree.GetNode_By_Name(this.treeView_SystemTree, RECEIVER_ID + _Text.Minus + _Text.UI_TREE_IMAGE);

            // 노드 키와 텍스트 정보는 페이지 이름으로 통일한다
            _Tree.NodeAdd_Root_Node_Node_Node(this.treeView_SystemTree, 0, ReceiverNode.Index, ImageNode.Index, Page.NodeKey, Page.NodeText, Object_Type.PAGE);

            // 그래픽 노드 모두 펼침
            ImageNode.Expand();
        }

        // 이벤트 테이블 (TB_EVENT_TYPE) 생성 
        private void Create_TB_EVENT_TYPE()
        {
            try
            {
                OpenFileDialog openFileDialog = new OpenFileDialog();

                // 파일을 읽는 경로는 우선 프로그램에서 배포하는 파일을 따라간다
                openFileDialog.InitialDirectory = _File.ProgramPath; //_Data.Project_Path + "\\" + _Data.Project_Name;

                //openFileDialog.Filter = "(*.xls)|*.xls|(*.xlsx)|*.xlsx";
                openFileDialog.Filter = "(*.csv*)|*.csv";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    string[] EventTypeString = System.IO.File.ReadAllLines(openFileDialog.FileName, Encoding.Default);

                    if (EventTypeString.Length == 0)
                    {
                        // 데이타가 잘못되었습니다
                        _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.FailDataInform, 0);
                        return;
                    }

                    // 임시저장소
                    ArrayList Type = new ArrayList();
                    ArrayList TypeName = new ArrayList();


                    foreach (string EventType in EventTypeString)
                    {
                        string[] Temps = EventType.Split(',');

                        if (Temps.Length < 2)
                        {
                            // 데이타가 잘못되었습니다
                            _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.FailDataInform, 0);
                            return;
                        }

                        // 첫째줄은 제외
                        if (Temps[0] != "EVENT_TYPE")
                        {
                            Type.Add(Temps[0]);
                            TypeName.Add(Temps[1]);
                        }
                    }

                    // TB_EVENT_TYPE 모든 데이타 삭제
                    _Db.Execute(_Sql.Delete_Table("TB_EVENT_TYPE", null));

                    foreach (string Data in Type)
                    {
                        _Db.ADD("TB_EVENT_TYPE",
                            "EVENT_TYPE=" + Data +
                            ";EVENT_TYPE_NAME=" + TypeName[Type.IndexOf(Data)].ToString() +
                            ";UPDATE_USER_ID=" + "FireManager" +
                            ";UPDATE_TIME=" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                    }

                    // 저장하였습니다
                    _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.OK, 250, 150, _Text.SaveInform, 0);
                }
            }
            catch (Exception e)
            {
                // 데이타가 잘못되었습니다
                _Popup.Create(Popup_Type.Confirm, Popup_Style.Normal, _Text.Warnning, 350, 150, _Text.FailDataInform, 0);

                _Event.DebugView_SendMessage_Write(e.ToString());
            }
        }

    }
}