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

namespace FPER
{
    public partial class frmRepeaterGroup : Form
    {
        int savBoardID = -1;
        int savLoop = -1;
        bool BoardGroup_change;
        MDIParent mdi;
        //FormRepeater FormRepeater = null;
        delegate void deleFormInit();
        LogFileCreate LFC = new LogFileCreate();
        //중계기 읽기를 진행하기 위해
        private Thread tRepeaterReadThread;
        private int tRepeaterReadThreadStatus = 0;

        // cyim 2015.7.2 해쉬테이블로 아날로그 감지기 레벨을 아이디별로 저장해둔다
        // 화면에서 보이는 보드,루프번호에 해당하는 아날로그감지기 레벨값 정보를 미리 가져온다
        Hashtable AnalogDetecterRepeaterID_Hashtable = new Hashtable();

        //화면의 GRIDVIEW 각 셀관련 중계기내용
        GridRepeater[] GRIDCELL = new GridRepeater[127];

        // 생성자
        public frmRepeaterGroup()
        {
            InitializeComponent();

            // 이벤트 핸들러 (디자이너가 아닌 수동으로 등록)
            this.FormClosing += new FormClosingEventHandler(frmRepeaterGroup_FormClosing);
        }

        // cyim 2015.7.6 레벨값 갱신 이벤트 추가
        public void _Event_AnalogLevel_Update_SendMessage_Event(MDIParent mdi)
        {
            // Repeater_ SettingData 를 호출은 반드시 해당 보드아이디와 루프가 변경될때만 호출되므로,
            // 직접 해쉬테이블을 갱신하도록 한다
            AnalogDetecterRepeaterID_Hashtable = mdi.GetAnalogDetecterRepeaterID(mdi.myReceiverID, savBoardID, savLoop);
        }

        // 소멸자
        public void frmRepeaterGroup_FormClosing(object sender, FormClosingEventArgs e)
        {
            // cyim 2015.7.6 레벨값 갱신 이벤트 추가 : 해제
            mdi.Event.AnalogLevel_Update_SendMessage_Event -= new _Event.AnalogLevel_Update_SendMessage_Handler(_Event_AnalogLevel_Update_SendMessage_Event); // cyim 2015.8.4 수신반을 위한 static 클래스 정리
        }

        // 초기화
        public void Form_Init()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    deleFormInit d = new deleFormInit(Form_Init);
                    this.Invoke(d, new object[] { });
                }
                else
                {
                    Repeater_SettingData();
                    btnRepeaterAllInfo_Click(btnRepeaterAllInfo, EventArgs.Empty);
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.Source), Application.ProductName);
            }
        }
        bool load = false;
        // 초기화
        private void frmRepeaterGroup_Load(object sender, EventArgs e)
        {
            // cyim 2013.8.1 : 더블버퍼링 적용
            SetStyle(ControlStyles.UserPaint, true);
            //this.UpdateStyles();
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            //this.UpdateStyles();
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.UpdateStyles();

            try
            {
                this.Cursor = Cursors.WaitCursor;

                mdi = (MDIParent)this.MdiParent;
                txtThisReceiverID.Text = string.Format("{0:00}", mdi.myReceiverID);
                if (BoardGroup_change)
                {
                    mdi.temptxtBoardID = txtBoardID.Text;
                    mdi.temptxtLoopNo = txtLoopNo.Text;
                    BoardGroup_change = false;
                }
                //DacBoardConfig dacBoardConfig = new DacBoardConfig();
                //ArrayList ary = dacBoardConfig.Board_List(mdi.myReceiverID);
                //Util.ComboSetting(cboBoardList, ary, null);
                load = true;
                Repeater_SettingData();
                btnRepeaterAllInfo_Click(btnRepeaterAllInfo, EventArgs.Empty);
                this.timer_RepeaterAllInfo_BlockRead.Start();

                // cyim 2015.7.6 레벨값 갱신 이벤트 추가
                mdi.Event.AnalogLevel_Update_SendMessage_Event += new _Event.AnalogLevel_Update_SendMessage_Handler(_Event_AnalogLevel_Update_SendMessage_Event); // cyim 2015.8.4 수신반을 위한 static 클래스 정리

                // cyim 2015.7.23 NACK 응답이 최대 7.2초가 딜레이됨, 단 기본값은 4초 
                timer_RepeaterAllInfo_BlockRead_ChangeStart(4000);
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.Source), Application.ProductName);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void frmRepeaterGroup_Activated(object sender, EventArgs e)
        {
            this.mdi.SelectMenuIndex = 3;
        }

        private void frmRepeaterGroup_Disposed(object sender, EventArgs e)
        {
            this.mdi.SelectMenuIndex = 0;
        }

        // 중계기 상태를 조회하기 위한 통신보드, 루프번호를 조회한다 (UI 기준)
        public void setBoardId(int boardId, int loopNo)
        {
            try
            {
                txtBoardID.Text = String.Format("{0:00}", boardId);
                txtLoopNo.Text = String.Format("{0}", loopNo);
                BoardGroup_change = true;
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        //GRID에 중계기 설정 표시
        private void Repeater_init()
        {
            // 중계기 이미지 
            //imgListRepeaterBack.Images[0];
            //0 : 중계기 빈것
            //1 : 중계기 차단
            //2 : 중계기 에러
            //3 : 중계기 없음

            try
            {
                this.dataGridView_Repeater_Main.Columns.Clear();

                DataGridViewCellStyle sty = new DataGridViewCellStyle();
                sty.Alignment = DataGridViewContentAlignment.MiddleCenter;
                for (int col = 0; col < 10; col++)
                {
                    DataGridViewImageColumn imageColumn = new DataGridViewImageColumn();
                    imageColumn.ImageLayout = DataGridViewImageCellLayout.Normal;
                    // 처음 기본 바탕이미지는 중계기 빈것으로 대체 (흰색)
                    imageColumn.Image = imgListRepeaterBack.Images[0];
                    dataGridView_Repeater_Main.Columns.Add(imageColumn);

                    dataGridView_Repeater_Main.Columns[col].ReadOnly = true;
                    dataGridView_Repeater_Main.Columns[col].Resizable = DataGridViewTriState.False;
                    dataGridView_Repeater_Main.Columns[col].Width = 76;
                    dataGridView_Repeater_Main.Columns[col].DefaultCellStyle = sty;
                }

                // 10개의 셀 바탕이미지는 중계기 없음으로 대체 (회색)
                Image[] rowData12 = new Image[10] {
                    imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3] , imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3],
                    imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3] , imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3], imgListRepeaterBack.Images[3]};
                try
                {
                    this.dataGridView_Repeater_Main.Rows.Clear();
                    DataGridViewRowCollection rows = dataGridView_Repeater_Main.Rows;
                    for (int row = 0; row <= 12; row++)
                    {
                        rows.Add(rowData12);
                    }
                }
                catch (Exception ex)
                {
                    Util.UErrorMessage(ex, 0, 0);
                }

                // 셀 단위로 이미지를 셋팅한다
                for (int row = 0; row <= 12; row++)
                {
                    for (int col = 1; col <= 10; col++)
                    {
                        // no 는 중계기 아이디
                        int no = row * 10 + col;
                        if (no <= 127)
                        {
                            GRIDCELL[no - 1] = new GridRepeater(dataGridView_Repeater_Main.Rows[row].Cells[col - 1], imgListRepeaterBack, no);
                        }
                    }
                    dataGridView_Repeater_Main.Rows[row].Height = 45;

                    //REP[no] = new RepeaterDeviceTypeInfo(no);
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                throw ex;
            }
        }
        bool ex = false;

        //중계기 설정데이터 가져오기
        private void Repeater_SettingData()
        {
            try
            {
                if (this.InvokeRequired)
                {
                    deleFormInit d = new deleFormInit(Repeater_SettingData);
                    this.Invoke(d, new object[] { });
                }
                else
                {
                    //if (cboBoardList.Items.Count < 1 || cboLoopList.Items.Count < 1) { Repeater_init(); return; }
                    //if (cboBoardList.SelectedItem == null || cboLoopList.SelectedItem == null) { Repeater_init(); return; }

                    //String BoardID = cboBoardList.SelectedItem.ToString();
                    //String Loop = cboLoopList.SelectedItem.ToString();
                    ReceiverTypeInfo Receiverinfo = mdi.ui.MyReceiverTypeInfo;

                    if (load)
                    {
                        if (mdi.temptxtBoardID != null && mdi.temptxtLoopNo != null)
                        {
                            int boardid = Convert.ToInt32(mdi.temptxtBoardID);
                            int tempboard = boardid - 1;
                            int loopid = Convert.ToInt32(mdi.temptxtLoopNo);
                            if (Receiverinfo.MyBoardType[tempboard] != null)
                            {
                                if (Receiverinfo.MyBoardType[tempboard].UseFlag == true)
                                {
                                    switch (loopid)
                                    {
                                        case 0:
                                            {
                                                if (Receiverinfo.MyBoardType[tempboard].Loop0UseFlag == true)
                                                {
                                                    if (boardid > 9)
                                                    {
                                                        txtBoardID.Text = boardid.ToString();
                                                        mdi.temptxtBoardID = txtBoardID.Text;
                                                    }
                                                    else
                                                    {
                                                        txtBoardID.Text = "0" + boardid.ToString();
                                                        mdi.temptxtBoardID = boardid.ToString();
                                                    }
                                                    txtLoopNo.Text = "0";
                                                    mdi.temptxtLoopNo = txtLoopNo.Text;
                                                    ex = true;
                                                    break;
                                                }
                                                ex = false;
                                                break;
                                            }
                                        case 1:
                                            {
                                                if (Receiverinfo.MyBoardType[tempboard].Loop1UseFlag == true)
                                                {
                                                    if (boardid > 9)
                                                    {
                                                        txtBoardID.Text = boardid.ToString();
                                                        mdi.temptxtBoardID = txtBoardID.Text;
                                                    }
                                                    else
                                                    {
                                                        txtBoardID.Text = "0" + boardid.ToString();
                                                        mdi.temptxtBoardID = boardid.ToString();
                                                    }
                                                    txtLoopNo.Text = "1";
                                                    mdi.temptxtLoopNo = txtLoopNo.Text;
                                                    ex = true;
                                                    break;
                                                }
                                                ex = false;
                                                break;
                                            }
                                        case 2:
                                            {
                                                if (Receiverinfo.MyBoardType[tempboard].Loop2UseFlag == true)
                                                {
                                                    if (boardid > 9)
                                                    {
                                                        txtBoardID.Text = boardid.ToString();
                                                        mdi.temptxtBoardID = txtBoardID.Text;
                                                    }
                                                    else
                                                    {
                                                        txtBoardID.Text = "0" + boardid.ToString();
                                                        mdi.temptxtBoardID = boardid.ToString();
                                                    }
                                                    txtLoopNo.Text = "2";
                                                    mdi.temptxtLoopNo = txtLoopNo.Text;
                                                    ex = true;
                                                    break;
                                                }
                                                ex = false;
                                                break;
                                            }
                                        case 3:
                                            {
                                                if (Receiverinfo.MyBoardType[tempboard].Loop3UseFlag == true)
                                                {
                                                    if (boardid > 9)
                                                    {
                                                        txtBoardID.Text = boardid.ToString();
                                                        mdi.temptxtBoardID = txtBoardID.Text;
                                                    }
                                                    else
                                                    {
                                                        txtBoardID.Text = "0" + boardid.ToString();
                                                        mdi.temptxtBoardID = boardid.ToString();
                                                    }
                                                    txtLoopNo.Text = "3";
                                                    mdi.temptxtLoopNo = txtLoopNo.Text;
                                                    ex = true;
                                                    break;
                                                }
                                                ex = false;
                                                break;
                                            }
                                    }
                                }
                            }
                        }
                        if (!ex)
                        {
                            for (var i = 0; i < Receiverinfo.MyBoardType.Length; i++)
                            {
                                if (Receiverinfo.MyBoardType[i] != null)
                                {
                                    if (Receiverinfo.MyBoardType[i].UseFlag == true)
                                    {
                                        if (Receiverinfo.MyBoardType[i].Loop0UseFlag == true || Receiverinfo.MyBoardType[i].Loop1UseFlag == true || Receiverinfo.MyBoardType[i].Loop2UseFlag == true || Receiverinfo.MyBoardType[i].Loop3UseFlag == true)
                                        {
                                            int tempcnt = i + 1;
                                            if (tempcnt > 9)
                                            {
                                                txtBoardID.Text = tempcnt.ToString();
                                            }
                                            else
                                            {
                                                txtBoardID.Text = "0" + tempcnt.ToString();
                                            }

                                            if (Receiverinfo.MyBoardType[i].Loop0UseFlag == true)
                                            {
                                                txtLoopNo.Text = "0";
                                                break;
                                            }
                                            else if (Receiverinfo.MyBoardType[i].Loop1UseFlag == true)
                                            {
                                                txtLoopNo.Text = "1";
                                                break;
                                            }
                                            else if (Receiverinfo.MyBoardType[i].Loop2UseFlag == true)
                                            {
                                                txtLoopNo.Text = "2";
                                                break;
                                            }
                                            else
                                            {
                                                txtLoopNo.Text = "3";
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        load = false;
                    }

                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);
                    if (txtBoardID.Text.Substring(0, 1) == "0")
                    {
                        mdi.temptxtBoardID = txtBoardID.Text.Substring(1, 1);
                    }
                    else
                    {
                        mdi.temptxtBoardID = txtBoardID.Text;
                    }
                    mdi.temptxtLoopNo = txtLoopNo.Text;

                    if (BoardID == savBoardID && Loop == savLoop) return;

                    this.Cursor = Cursors.WaitCursor;

                    // 중계기 상태보기 이미지를 초기화
                    Repeater_init();
                    savBoardID = BoardID;
                    savLoop = Loop;
                    //수신기설정

                    //통신보드 savBoardID 의 loop 의 설정값
                    BoardTypeInfo brdinfo = Receiverinfo.Get_RepeaterType(savBoardID);

                    RepeaterDeviceTypeInfo[] repinfo;
                    RepeaterPointUnit[] repdata;
                    bool LoopCutFlag = false;

                    // cyim 2015.7.2 해쉬테이블로 아날로그 감지기 레벨을 아이디별로 저장해둔다
                    // 사전에 가져온 데이타베이스 정보를 토대로 해당 보드, 루프를 따져 아날로그 감지기 정보를 미리 알아낸다
                    // 이 때 아날로그 감지기라면 레벨값을 따져 현재 상태를 알아내야 한다
                    AnalogDetecterRepeaterID_Hashtable = mdi.GetAnalogDetecterRepeaterID(mdi.myReceiverID, savBoardID, savLoop);

                    // cyim 2016.10.31 : 계통정보는 0,1,2,3 으로 변경
                    // 통신보드의 Loop 정보
                    if (savLoop == 0)
                    {
                        LoopCutFlag = brdinfo.Loop0CutFlag;
                        repinfo = brdinfo.Loop0_RepeaterType;         //통신보드 + Loop0 + 127개 중계기 설정값
                        repdata = brdinfo.Loop0_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 1)
                    {
                        LoopCutFlag = brdinfo.Loop1CutFlag;
                        repinfo = brdinfo.Loop1_RepeaterType;         //통신보드 + Loop1 + 127개 중계기 설정값
                        repdata = brdinfo.Loop1_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 2)
                    {
                        LoopCutFlag = brdinfo.Loop2CutFlag;
                        repinfo = brdinfo.Loop2_RepeaterType;         //통신보드 + Loop2 + 127개 중계기 설정값
                        repdata = brdinfo.Loop2_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 3)
                    {
                        LoopCutFlag = brdinfo.Loop3CutFlag;
                        repinfo = brdinfo.Loop3_RepeaterType;         //통신보드 + Loop3 + 127개 중계기 설정값
                        repdata = brdinfo.Loop3_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else
                    {
                        LoopCutFlag = brdinfo.Loop0CutFlag;
                        repinfo = null;
                        repdata = null;
                    }

                    // 차단 정보 (계통)
                    if (LoopCutFlag)
                    {
                        btnRepeaterRecoverCmd.Enabled = false;
                        btnRepeaterSearchCmd.Enabled = false;
                        btnInWrite.Enabled = false;
                        btnOutWrite.Enabled = false;
                        this.btnRepeaterReset.Enabled = false; // cyim 2015.2.23 계통차단시에는 사용불가 
                    }
                    else
                    {
                        btnRepeaterRecoverCmd.Enabled = true;
                        btnRepeaterSearchCmd.Enabled = true;
                        btnInWrite.Enabled = true;
                        btnOutWrite.Enabled = true;
                        this.btnRepeaterReset.Enabled = true; // cyim 2015.2.23 계통차단시에는 사용불가 
                    }

                    // 각 중계기의 정보
                    for (int i = 0; i < repinfo.Length; i++)//2010.11.22, k.s.d , #127 repeater information don't display  bug fix. , for (int i = 0; i < repinfo.Length - 1;i++ )
                    {
                        RepeaterDeviceTypeInfo dev = repinfo[i];
                        GRIDCELL[i].LoopCutFlag = LoopCutFlag;
                        //if (dev != null)
                        //{
                        int RepeaterID = i + 1;
                        //개별중계기 설정값으로 Grid UI 생성
                        GRIDCELL[i].Set_DeviceInfo(dev);
                        //개별중계기 데이터값으로 Grid UI 생성  - 중계기 타입 결정
                        GRIDCELL[i].Set_DeviceUnit(repdata[RepeaterID - 1]);
                        //}
                    }

                    // 하단은 필요없음
                    //if (LoopCutFlag)
                    //{
                    //    //MessageBox.Show(string.Format("해당 계통은 차단설정 중입니다.. 통신보드[{0}] 계통[{1}] 차단설정 해제후 제어하십시요..", savBoardID, savLoop));
                    //}

                }
                this.Cursor = Cursors.Default;
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        void RepeaterInfoRead()
        {
            try
            {
                while (tRepeaterReadThreadStatus > 0)
                {

                    if (this.mdi.ui.Connected)
                    {

                        try
                        {
                            int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                            int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                            if (BoardID == 0)
                            {
                                tRepeaterReadThreadStatus = 0;
                            }

                            if (Loop != 0 && Loop != 1)
                            {
                                tRepeaterReadThreadStatus = 0;
                            }

                            tRepeaterReadThreadStatus++;


                            //중계기 전체 읽기 명령
                            dCommandResponse d = new dCommandResponse(RepeaterInfoAll);

                            //명령생성 및 실행
                            CmdInfo cmd = new CmdInfo(prt_cmd_define.read_repeater_all, mdi.myReceiverID, 1, Loop, BoardID, d);
                            this.mdi.ui.runCommand(cmd);

                            if (tRepeaterReadThreadStatus > 4) tRepeaterReadThreadStatus = 0;

                        }
                        catch (Exception ex)
                        {
                            Util.UErrorMessage(ex, 0, 0);
                            tRepeaterReadThreadStatus = 0;
                        }
                        Thread.Sleep(1000);
                    }
                    else
                    {
                        tRepeaterReadThreadStatus = 0;
                    }
                }

            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                tRepeaterReadThreadStatus = 0;
            }
        }

        //선택셀이 바뀔때마다 해당중계기 설정내용 및 데이터 표시
        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                    if (no > 127)
                    {
                        lblRepeaterID.Text = "";
                        DeviceStatus(null, null);
                        return;
                    }
                    else
                    {
                        lblRepeaterID.Text = String.Format("{0:000} 아이디", no);

                        if (GRIDCELL[no - 1] != null)
                        {
                            lblInfoMessage.Text = GRIDCELL[no - 1].InfoMessage;
                            //dataGridView2에 데이터 표시
                            RepeaterDeviceTypeInfo dev = GRIDCELL[no - 1].DeviceInfo;
                            RepeaterPointUnit unit = GRIDCELL[no - 1].DeviceUnit;
                            DeviceStatus(dev, unit);
                        }
                        else
                        {
                            lblRepeaterID.Text = "";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        // cyim 2015.2.23 계통차단시에는 사용불가 
        // 현재 라인이 차단되었는지 알아보는 함수
        private bool LoopCut()
        {
            int BoardID = Util.StrToInt(txtBoardID.Text, 0);

            ReceiverTypeInfo Receiverinfo = mdi.ui.MyReceiverTypeInfo;       //수신기설정
            BoardTypeInfo brdinfo = Receiverinfo.Get_RepeaterType(BoardID);     //통신보드savBoardID의 loop0의 설정값
            //RepeaterDeviceTypeInfo[] repinfo;
            //RepeaterPointUnit[] repdata;
            bool LoopCutFlag = false;

            // cyim 2016.10.31 : 계통정보는 0,1,2,3 으로 변경
            if (savLoop == 0)
            {
                LoopCutFlag = brdinfo.Loop0CutFlag;
                //repinfo = brdinfo.Loop0_RepeaterType;         //통신보드 + Loop0 + 127개 중계기 설정값
                //repdata = brdinfo.Loop0_RepeaterUnit_Data;   //127개 중계기 데이터
            }
            else if (savLoop == 1)
            {
                LoopCutFlag = brdinfo.Loop1CutFlag;
                //repinfo = brdinfo.Loop1_RepeaterType;         //통신보드 + Loop1 + 127개 중계기 설정값
                //repdata = brdinfo.Loop1_RepeaterUnit_Data;   //127개 중계기 데이터
            }
            else if (savLoop == 2)
            {
                LoopCutFlag = brdinfo.Loop2CutFlag;
                //repinfo = brdinfo.Loop1_RepeaterType;         //통신보드 + Loop2 + 127개 중계기 설정값
                //repdata = brdinfo.Loop1_RepeaterUnit_Data;   //127개 중계기 데이터
            }
            else if (savLoop == 3)
            {
                LoopCutFlag = brdinfo.Loop3CutFlag;
                //repinfo = brdinfo.Loop1_RepeaterType;         //통신보드 + Loop3 + 127개 중계기 설정값
                //repdata = brdinfo.Loop1_RepeaterUnit_Data;     //127개 중계기 데이터
            }
            return LoopCutFlag;
        }

        //dataGridView2에 중계기 회로정보 표시
        private void DeviceStatus(RepeaterDeviceTypeInfo dt, RepeaterPointUnit unit)
        {
            try
            {
                if (dt != null && dt.UseFlag == true)
                {
                    if (dt.RepeaterType.Equals("")
                        // cyim 2015.2.23 계통차단시에는 사용불가 
                        || LoopCut() == true
                        // cyim 2015.2.23 중계기차단시에는 사용불가
                        || dt.CutFlag == true
                        )
                    {
                        btnInWrite.Enabled = false;
                        btnOutWrite.Enabled = false;
                        btnRepeaterRecoverCmd.Enabled = false;
                        btnRepeaterSearchCmd.Enabled = false;
                        this.btnRepeaterReset.Enabled = false; // cyim 2015.2.23 계통차단시에는 사용불가 
                    }
                    //else if (dt.CutFlag
                    else
                    {
                        btnInWrite.Enabled = true;
                        btnOutWrite.Enabled = true;
                        btnRepeaterRecoverCmd.Enabled = true;
                        btnRepeaterSearchCmd.Enabled = true;
                        this.btnRepeaterReset.Enabled = true; // cyim 2015.2.23 계통차단시에는 사용불가 
                    }

                    // 사용하는 셀 (흰색)
                    DataGridViewCellStyle sty = new DataGridViewCellStyle();
                    sty.Alignment = DataGridViewContentAlignment.MiddleCenter;
                    sty.BackColor = System.Drawing.Color.White;

                    // 미사용하는 셀 (회색)
                    DataGridViewCellStyle styGray = new DataGridViewCellStyle();
                    styGray.Alignment = DataGridViewContentAlignment.MiddleCenter;
                    styGray.BackColor = System.Drawing.Color.Gray;
                    styGray.SelectionBackColor = System.Drawing.Color.Gray;

                    // cyim 2015.6.8 아날로그 감지기 연동 추가 : 타입에 관계없이 동일한 스타일이 적용된다
                    for (int col = 0; col < 4; col++)
                    {
                        dataGridView_Repeater_Sub.Columns[col].ReadOnly = true;
                        dataGridView_Repeater_Sub.Columns[col].Resizable = DataGridViewTriState.False;
                        dataGridView_Repeater_Sub.Columns[col].Width = 70;
                        dataGridView_Repeater_Sub.Columns[col].DefaultCellStyle = sty;
                    }

                    //if (dt.RepeaterType.Equals("A"))
                    //{
                    //    for (int col = 0; col < 4; col++)
                    //    {
                    //        //dataGridView2.Columns.Add(new DataGridViewTextBoxColumn());
                    //        dataGridView_Repeater_Sub.Columns[col].ReadOnly = true;
                    //        dataGridView_Repeater_Sub.Columns[col].Resizable = DataGridViewTriState.False;
                    //        dataGridView_Repeater_Sub.Columns[col].Width = 140;
                    //        dataGridView_Repeater_Sub.Columns[col].DefaultCellStyle = sty;
                    //    }
                    //    //dt.InType3 = "";
                    //    //dt.InType4 = "";
                    //    //dt.OutType3 = "";
                    //    //dt.OutType4 = "";

                    //    // cyim 2015.6.8 아날로그 감지기 연동 추가 : 아래 소스는 필요없음
                    //    //dataGridView_Repeater_Sub.Columns[2].ReadOnly = true;
                    //    //dataGridView_Repeater_Sub.Columns[2].Resizable = DataGridViewTriState.False;
                    //    //dataGridView_Repeater_Sub.Columns[2].Width = 140;
                    //    //dataGridView_Repeater_Sub.Columns[2].DefaultCellStyle = styGray;
                    //    //dataGridView_Repeater_Sub.Columns[3].ReadOnly = true;
                    //    //dataGridView_Repeater_Sub.Columns[3].Resizable = DataGridViewTriState.False;
                    //    //dataGridView_Repeater_Sub.Columns[3].Width = 140;
                    //    //dataGridView_Repeater_Sub.Columns[3].DefaultCellStyle = styGray;
                    //}
                    //else if (dt.RepeaterType.Equals("B"))
                    //{
                    //    for (int col = 0; col < 4; col++)
                    //    {
                    //        //dataGridView2.Columns.Add(new DataGridViewTextBoxColumn());
                    //        dataGridView_Repeater_Sub.Columns[col].ReadOnly = true;
                    //        dataGridView_Repeater_Sub.Columns[col].Resizable = DataGridViewTriState.False;
                    //        dataGridView_Repeater_Sub.Columns[col].Width = 70;
                    //        dataGridView_Repeater_Sub.Columns[col].DefaultCellStyle = sty;
                    //    }
                    //}

                    //else if (dt.RepeaterType.Equals("C") || dt.RepeaterType.Equals("D"))
                    //{
                    //    for (int col = 0; col < 1; col++)
                    //    {
                    //        //dataGridView2.Columns.Add(new DataGridViewTextBoxColumn());
                    //        dataGridView_Repeater_Sub.Columns[col].ReadOnly = true;
                    //        dataGridView_Repeater_Sub.Columns[col].Resizable = DataGridViewTriState.False;
                    //        dataGridView_Repeater_Sub.Columns[col].Width = 140;
                    //        dataGridView_Repeater_Sub.Columns[col].DefaultCellStyle = sty;
                    //    }
                    //}

                    //회로입력,출력값 표시
                    if (unit != null)
                    {
                        DataGridViewRowCollection rows2 = this.dataGridView_Repeater_Sub.Rows;
                        if (dt != null)
                        {
                            if (dt.RepeaterType.Equals("A"))
                            {
                                //sdkim , 2011.11.22.  bug fix , 2in2out type repeater - null point exception bug.
                                String[] inData = { DeviceStatusText.InputText(unit.Repeater_Input1,dt.inDeviceTypeInfos[0]),
                                                    DeviceStatusText.InputText(unit.Repeater_Input2,dt.inDeviceTypeInfos[1]),
                                                    "",
                                                    "" };
                                String[] outData = { DeviceStatusText.OutputText(unit.Repeater_Output1,dt.outDeviceTypeInfos[0]),
                                                     DeviceStatusText.OutputText(unit.Repeater_Output2,dt.outDeviceTypeInfos[1]),
                                                     "",
                                                     "" };
                                rows2.Clear();
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                            else if (dt.RepeaterType.Equals("B"))
                            {
                                String[] inData = { DeviceStatusText.InputText(unit.Repeater_Input1,dt.inDeviceTypeInfos[0]),
                                                    DeviceStatusText.InputText(unit.Repeater_Input2,dt.inDeviceTypeInfos[1]),
                                                    DeviceStatusText.InputText(unit.Repeater_Input3,dt.inDeviceTypeInfos[2]),
                                                    DeviceStatusText.InputText(unit.Repeater_Input4,dt.inDeviceTypeInfos[3]) };
                                String[] outData = { DeviceStatusText.OutputText(unit.Repeater_Output1,dt.outDeviceTypeInfos[0]),
                                                     DeviceStatusText.OutputText(unit.Repeater_Output2,dt.outDeviceTypeInfos[1]),
                                                     DeviceStatusText.OutputText(unit.Repeater_Output3,dt.outDeviceTypeInfos[2]),
                                                     DeviceStatusText.OutputText(unit.Repeater_Output4,dt.outDeviceTypeInfos[3])};
                                rows2.Clear();
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                            // cyim 2015.6.8 아날로그 감지기 연동 추가
                            else if (dt.RepeaterType.Equals("C") || dt.RepeaterType.Equals("D"))
                            {
                                String[] inData = { DeviceStatusText.InputText(unit.Repeater_Input1, dt.inDeviceTypeInfos[0]) };
                                String[] outData = { DeviceStatusText.OutputText(unit.Repeater_Output1, dt.outDeviceTypeInfos[0]) };
                                rows2.Clear();
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                        }
                    }
                    else
                    {
                        DataGridViewRowCollection rows2 = this.dataGridView_Repeater_Sub.Rows;
                        if (dt != null)
                        {
                            rows2.Clear();
                            // cyim 2014.4.3 : 초기값 수정 1,2,3,4 -> "-" 
                            if (dt.RepeaterType.Equals("A"))
                            {
                                String[] inData = { "-", "-", "", "" };
                                String[] outData = { "-", "-", "", "" };
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                            else if (dt.RepeaterType.Equals("B"))
                            {
                                String[] inData = { "-", "-", "-", "-" };
                                String[] outData = { "-", "-", "-", "-" };
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                            // cyim 2015.6.8 아날로그 감지기 연동 추가
                            else if (dt.RepeaterType.Equals("C") || dt.RepeaterType.Equals("D"))
                            {
                                String[] inData = { "-", "", "", "" };
                                String[] outData = { "-", "", "", "" };
                                rows2.Add(inData);
                                rows2.Add(outData);
                            }
                        }
                    }
                }
                else
                {
                    this.dataGridView_Repeater_Sub.Rows.Clear();
                    btnInWrite.Enabled = false;
                    btnOutWrite.Enabled = false;
                    btnRepeaterRecoverCmd.Enabled = false;
                    btnRepeaterSearchCmd.Enabled = false;
                    lblRepeaterID.Text = "";
                    this.btnRepeaterReset.Enabled = false; // cyim 2015.2.23 계통차단시에는 사용불가 
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        private Boolean dtCutFlag(DeviceTypeInfo dtInfo)
        {
            bool cutFlag = false;
            try
            {
                if (dtInfo != null) cutFlag = dtInfo.CutFlag;
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
            return cutFlag;
        }

        /*******************************************
         * 중계기정보를 가져오는 통신부분 ---시작
         ******************************************/

        private void btnRepeaterAllInfo_Click(object sender, EventArgs e)
        {
            try
            {
                SocketUI ui = this.mdi.ui;
                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                if (BoardID == 0)
                {
                    this.label_Warning.Text = string.Format("통신보드ID를 입력하여 주십시요.");
                    this.label_Warning.Visible = true;
                    txtBoardID.Focus();
                    return;
                }
                else
                    if (Loop != 0 && Loop != 1 && Loop != 2 && Loop != 3)
                {
                    this.label_Warning.Text = string.Format("Loop No를 올바르게 입력하여 주십시요.");
                    this.label_Warning.Visible = true;
                    txtLoopNo.Focus();
                    return;
                }
                else
                {
                    this.label_Warning.Visible = false;
                }
                button_end(false);//버튼 비활성 설정

                dCommandResponse d = new dCommandResponse(RepeaterInfoAll);//중계기 전체 읽기 명령
                CmdInfo cmd = new CmdInfo(prt_cmd_define.read_repeater_all, mdi.myReceiverID, 1, Loop, BoardID, d);//명령생성 및 실행

                ui.runCommand(cmd);
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        //화면 마우스 커서 및 버튼 다시 클릭 못하도록 설정 및 해제
        private void button_end(Boolean val)
        {
            try
            {
                if (val)
                {
                    this.btnRepeaterAllInfo.Enabled = true;
                    this.Cursor = Cursors.Default;
                }
                else
                {
                    this.btnRepeaterAllInfo.Enabled = false;
                    this.Cursor = Cursors.WaitCursor;
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        // cyim 2015.7.23 NACK 응답이 최대 7.2초가 딜레이됨, 단 기본값은 4초 
        public void timer_RepeaterAllInfo_BlockRead_ChangeStart(int interval)
        {
            if (timer_RepeaterAllInfo_BlockRead.Interval != interval) // 중간에 주기를 변경하는 경우에만 타이머를 재시작한다 
            {
                timer_RepeaterAllInfo_BlockRead.Stop();
                timer_RepeaterAllInfo_BlockRead.Interval = interval;
                timer_RepeaterAllInfo_BlockRead.Start();
            }
        }

        //*********************************************************************//
        //                         중계기 전체읽기 응답데이터 이벤트                          //
        //*********************************************************************//

        public void RepeaterInfoAll(CmdInfo cmd)
        {
            try
            {
                if (!Util.ComInfoErrProcess(cmd, mdi.ui.Connected, "RCVData_ReadRepeaterPointAll")) // cyim 2015.7.23 NACK 처리 부분 오류 
                {
                    //에러응답처리
                    button_end(true);

                    // cyim 2015.7.23 NACK 응답이 최대 7.2초가 딜레이됨, 단 기본값은 4초 
                    timer_RepeaterAllInfo_BlockRead_ChangeStart(7200);
                    return;
                }
                // cyim 2015.7.23 NACK 응답이 최대 7.2초가 딜레이됨, 단 기본값은 4초 
                timer_RepeaterAllInfo_BlockRead_ChangeStart(4000);

                RCVData_ReadRepeaterPointAll ResponseData = (RCVData_ReadRepeaterPointAll)cmd.ResponseData;
                RepeaterData[] data = ResponseData.Data;

                if (cmd.Command == prt_cmd_define.read_repeater_all || cmd.ResCommand == prt_res_define.read_repeater_all)
                {
                    if (savBoardID == cmd.boardNo && savLoop == cmd.loopNo)
                    {
                        ReceiverTypeInfo Receiverinfo = mdi.ui.MyReceiverTypeInfo;       //수신기설정
                        BoardTypeInfo brdinfo = Receiverinfo.Get_RepeaterType(savBoardID);     //통신보드savBoardID의 loop0의 설정값
                        RepeaterDeviceTypeInfo[] repinfo;
                        RepeaterPointUnit[] repdata;

                        // cyim 2016.10.31 : 계통정보는 0,1,2,3 으로 변경
                        if (savLoop == 0)
                        {
                            repinfo = brdinfo.Loop0_RepeaterType;         //통신보드 + Loop0 + 127개 중계기 설정값
                            repdata = brdinfo.Loop0_RepeaterUnit_Data;    //127개 중계기 데이터
                        }
                        else if (savLoop == 1)
                        {
                            repinfo = brdinfo.Loop1_RepeaterType;         //통신보드 + Loop1 + 127개 중계기 설정값
                            repdata = brdinfo.Loop1_RepeaterUnit_Data;    //127개 중계기 데이터
                        }
                        else if (savLoop == 2)
                        {
                            repinfo = brdinfo.Loop2_RepeaterType;         //통신보드 + Loop2 + 127개 중계기 설정값
                            repdata = brdinfo.Loop2_RepeaterUnit_Data;    //127개 중계기 데이터
                        }
                        else if (savLoop == 3)
                        {
                            repinfo = brdinfo.Loop3_RepeaterType;         //통신보드 + Loop3 + 127개 중계기 설정값
                            repdata = brdinfo.Loop3_RepeaterUnit_Data;    //127개 중계기 데이터
                        }
                        else
                        {
                            repinfo = null;
                            repdata = null;
                        }

                        bool dataChanged = false;

                        for (int repeaterNo = 0; repeaterNo < data.Length; repeaterNo++)
                        {
                            if (repinfo[repeaterNo] != null)
                            {
                                // cyim 2015.6.8 아날로그 감지기 연동 추가 : 해당 중계기 아이디가 아날로그 감지기 타입이다
                                if (repinfo[repeaterNo].RepeaterType.Equals("C") || repinfo[repeaterNo].RepeaterType.Equals("D"))
                                {
                                    // cyim 2015.7.2 해쉬테이블로 아날로그 감지기 레벨을 아이디별로 저장해둔다
                                    // 해당 중계기의 아날로그 레벨 값을 생성자로 전달한다
                                    AnalogLevel analoglevel = (AnalogLevel)AnalogDetecterRepeaterID_Hashtable[(repeaterNo + 1).ToString()];

                                    if (GRIDCELL[repeaterNo].Unit == null)
                                    {
                                        RepeaterPointUnit newdata = new RepeaterPointUnit(repeaterNo + 1, data[repeaterNo], analoglevel, mdi); // cyim 2015.8.4 수신반을 위한 static 클래스 정리
                                        repdata[repeaterNo] = newdata;
                                        GRIDCELL[repeaterNo].Set_DeviceUnit(newdata);
                                        dataChanged = true;
                                    }
                                    else if (GRIDCELL[repeaterNo].UpdateDeviceUnit(data[repeaterNo], analoglevel, mdi)) // cyim 2015.8.4 수신반을 위한 static 클래스 정리
                                    {
                                        dataChanged = true;
                                    }
                                }
                                // 일반 중계기 타입이다
                                else
                                {
                                    if (GRIDCELL[repeaterNo].Unit == null)
                                    {
                                        RepeaterPointUnit newdata = new RepeaterPointUnit(repeaterNo + 1, data[repeaterNo]);
                                        repdata[repeaterNo] = newdata;
                                        GRIDCELL[repeaterNo].Set_DeviceUnit(newdata);
                                        dataChanged = true;
                                    }
                                    else if (GRIDCELL[repeaterNo].UpdateDeviceUnit(data[repeaterNo]))
                                    {
                                        dataChanged = true;
                                    }
                                }
                            }
                        }
                        if (dataChanged)
                        {
                            dataGridView1_SelectionChanged(dataGridView_Repeater_Main, System.EventArgs.Empty);//선택된 셀의 데이터를 dataGridView2에 표시한다..
                        }
                    }
                }
                button_end(true);//버튼 비활성 해제
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }

            //finally
            //{
            //    button_end(true);//버튼 비활성 해제
            //}
        }

        private void btnInputOpen_Click(object sender, EventArgs e)
        {
            try
            {
                InputIDVo vo = new InputIDVo();
                vo.ReceiverID = int.Parse(txtThisReceiverID.Text);
                vo.CommID = 1;
                vo.BoardID = Util.StrToInt(txtBoardID.Text, 0);
                vo.LoopNo = Util.StrToInt(txtLoopNo.Text, 0);

                IWin32Window window = this;
                // cyim 2017.01.12 : 모델에 따라 선택할수 있는 통신보드가 틀리다
                frmModalLoopSelect frm = new frmModalLoopSelect(mdi);
                frm.InputVo = vo;
                frm.ShowDialog(window);
                vo = frm.InputVo;

                //입력한 코드가 있다면
                if (vo.InputOK)
                {
                    txtThisReceiverID.Text = String.Format("{0:00}", vo.ReceiverID);
                    txtBoardID.Text = String.Format("{0:00}", vo.BoardID);
                    txtLoopNo.Text = String.Format("{0}", vo.LoopNo);

                    Repeater_SettingData();
                    btnRepeaterAllInfo_Click(btnRepeaterAllInfo, System.EventArgs.Empty);   //중계기정보읽기
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            try
            {
                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                if (BoardID == 0)
                {
                    this.label_Warning.Text = string.Format("통신보드ID를 입력하여 주십시요.");
                    this.label_Warning.Visible = true;
                    //MessageBox.Show("통신보드ID를 입력하여 주십시요.", Application.ProductName);
                    txtBoardID.Focus();
                    return;
                }
                else
                    if (Loop != 0 && Loop != 1 && Loop != 2 && Loop != 3)
                {
                    this.label_Warning.Text = string.Format("Loop No를 올바르게 입력하여 주십시요.");
                    this.label_Warning.Visible = true;
                    //MessageBox.Show("Loop No를 올바르게 입력하여 주십시요.", Application.ProductName);
                    txtLoopNo.Focus();
                    return;
                }
                else
                {
                    this.label_Warning.Visible = false;
                }

                Repeater_SettingData();
                btnRepeaterAllInfo_Click(btnRepeaterAllInfo, System.EventArgs.Empty);
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        private void btnWinClose_Click(object sender, EventArgs e)
        {
            try
            {
                this.Close();
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        private void btnRepeaterRecoverCmd_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                    if (no <= 127)
                    {
                        SocketUI ui = this.mdi.ui;

                        //완료이벤트
                        dCommandResponse d = new dCommandResponse(RepeaterRecoverComplete);

                        //명령생성 및 실행
                        CmdInfo cmd = new CmdInfo(prt_cmd_define.reset_repeater_unit, mdi.myReceiverID, 1, Loop, BoardID, no, d);
                        ui.runCommand(cmd);

                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        public void RepeaterRecoverComplete(CmdInfo cmd)
        {
            try
            {
                //에러응답처리
                if (!Util.ComInfoErrProcess(cmd, mdi.ui.Connected, "RCVData_ACK")) // cyim 2015.7.23 NACK 처리 부분 오류 
                {
                    button_end(true);
                    return;
                }

                MessageBox.Show("중계기복구 완료");
                btnRepeaterAllInfo_Click(btnRepeaterAllInfo, System.EventArgs.Empty);   //중계기 읽기 명령
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        //선택셀이 바뀔때마다 해당중계기 설정내용 및 데이터 표시
        private void dataGridView2_SelectionChanged(object sender, EventArgs e)
        {
            try
            {
                txtDeviceTypeName.Text = "";
                txtPositionName.Text = "";
                txtDeviceMemo.Text = "";

                if (dataGridView_Repeater_Main.SelectedCells.Count > 0 && dataGridView_Repeater_Sub.SelectedCells.Count > 0)
                {
                    int CommID = 1;
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int LoopNo = Util.StrToInt(txtLoopNo.Text, 0);

                    DataGridViewCell repCell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int RepeaterID = (repCell.RowIndex * 10) + repCell.ColumnIndex + 1;

                    DataGridViewCell devCell = this.dataGridView_Repeater_Sub.SelectedCells[0];
                    string InOut_Type = "I";
                    if (devCell.RowIndex > 0) InOut_Type = "O";
                    int deviceId = devCell.ColumnIndex + 1;

                    //회로설정값 
                    DacUIProcess dacUIProcess = new DacUIProcess(mdi.myReceiverID); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
                    DataTable dt2 = dacUIProcess.Device_Select(mdi.myReceiverID, CommID, BoardID, LoopNo, RepeaterID, deviceId, InOut_Type);
                    foreach (DataRow dr2 in dt2.Rows)
                    {

                        txtDeviceTypeName.Text = Util.NullToStr(dr2["DEVICE_TYPE_NAME"]);
                        txtPositionName.Text = Util.NullToStr(dr2["POSITION_NAME"]);
                        txtDeviceMemo.Text = Util.NullToStr(dr2["DEVICE_NAME"]);
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        //중계기검색
        private void btnRepeaterSearchCmd_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                    if (no <= 127)
                    {
                        SocketUI ui = this.mdi.ui;

                        //완료이벤트
                        dCommandResponse d = new dCommandResponse(RepeaterSearchComplete);

                        //명령생성 및 실행
                        CmdInfo cmd = new CmdInfo(prt_cmd_define.search_repeater_unit, mdi.myReceiverID, 1, Loop, BoardID, no, d);
                        ui.runCommand(cmd);

                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.StackTrace), Application.ProductName);
            }
        }

        //중계기검색완료
        public void RepeaterSearchComplete(CmdInfo cmd)
        {
            //에러응답처리
            if (!Util.ComInfoErrProcess(cmd, mdi.ui.Connected, "RCVData_SearchRepeaterUNIT")) // cyim 2015.7.23 NACK 처리 부분 오류 
            {
                button_end(true);
                return;
            }

            try
            {
                RCVData_SearchRepeaterUNIT unit = (RCVData_SearchRepeaterUNIT)cmd.ResponseData;
                if (unit == null) throw new Exception("중계기 검색에 실패하였습니다. 통신상태 및 중계기 설정을 확인하십시요.");
                if (unit.Data == null) throw new Exception("중계기 검색에 실패하였습니다. 통신상태 및 중계기 설정을 확인하십시요.");

                RepeaterData dat = (RepeaterData)unit.Data;

                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                if (BoardID == cmd.boardNo && cmd.loopNo == Loop)
                {
                    int RepeaterID = cmd.repeaterNo;

                    RepeaterPointUnit rep = new RepeaterPointUnit(cmd.repeaterNo, dat);
                    GRIDCELL[RepeaterID - 1].Set_DeviceUnit(rep);   //개별중계기 데이터값으로 Grid UI 생성
                    //검색완료여부
                    if (rep.RepeaterS == false)
                    {
                        MessageBox.Show(string.Format("중계기검색 완료. 중계기번호:{0}", RepeaterID));
                    }
                    else
                    {
                        MessageBox.Show(string.Format("중계기검색 실패. 중계기번호:{0}", RepeaterID));
                    }

                    btnRepeaterAllInfo_Click(btnRepeaterAllInfo, System.EventArgs.Empty);   //중계기 읽기 명령
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.Source), Application.ProductName);
            }
            finally
            {
                //버튼 비활성 해제
                button_end(true);
            }
        }

        private void btnInWrite_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                    if (no <= 127)
                    {
                        SocketUI ui = this.mdi.ui;

                        //회로
                        RepeaterPointUnit unit = GRIDCELL[no - 1].DeviceUnit;
                        RepeaterDeviceTypeInfo Info = GRIDCELL[no - 1].DeviceInfo;
                        if (Info == null || unit == null)
                        {
                            MessageBox.Show("회로설정 및 데이터를 읽을수 없습니다..통신상태를 확인하십시요..", Application.ProductName);
                            return;
                        }

                        if (MessageBox.Show("TEST용 회로만 입력쓰기가 가능합니다..그래도 입력쓰기를 하시겠습니까?", Application.ProductName, MessageBoxButtons.OKCancel)
                            == DialogResult.OK)
                        {
                            //int deviceNo = cell2.ColumnIndex + 1;

                            InputIDVo vo = new InputIDVo();
                            vo.ReceiverID = int.Parse(txtThisReceiverID.Text);
                            vo.CommID = 1;
                            vo.BoardID = Util.StrToInt(txtBoardID.Text, 0);
                            vo.LoopNo = Util.StrToInt(txtLoopNo.Text, 0);
                            vo.RepeaterID = no;
                            vo.RepeaterType = Info.RepeaterType;
                            vo.InoutType = "I";

                            InputDeviceStatus[] devData = new InputDeviceStatus[4]{ unit.Repeater_Input1
                                ,unit.Repeater_Input2
                                ,unit.Repeater_Input3
                                ,unit.Repeater_Input4};
                            vo.InputUnitData = devData;

                            IWin32Window window = this;
                            frmModalUnitDataSelect frm = new frmModalUnitDataSelect(Info); // cyim 2015.2.23 회로차단시에는 사용불가
                            frm.InputVo = vo;
                            frm.ShowDialog(window);
                            vo = frm.InputVo;

                            //입력한 코드가 있다면
                            if (vo.InputOK)
                            {
                                devData = vo.InputUnitData;

                                //회로
                                RepeaterData inputdata = new RepeaterData((byte)vo.RepeaterID);
                                inputdata.Set_Input_Data((int)devData[3], (int)devData[2], (int)devData[1], (int)devData[0]);

                                //완료이벤트
                                dCommandResponse d = new dCommandResponse(RepeaterInputWriteComplete);

                                //명령생성 및 실행
                                CmdInfo cmd = new CmdInfo(prt_cmd_define.write_repeater_input_unit, mdi.myReceiverID, 1, vo.LoopNo, vo.BoardID, vo.RepeaterID, d);
                                cmd.CommandData = inputdata;
                                ui.runCommand(cmd);

                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.StackTrace), Application.ProductName);
            }
        }

        //중계기 입력쓰기 완료
        public void RepeaterInputWriteComplete(CmdInfo cmd)
        {
            //에러응답처리
            if (!Util.ComInfoErrProcess(cmd, mdi.ui.Connected, "RCVData_WriteRepeaterInputUNIT")) // cyim 2015.7.23 NACK 처리 부분 오류 
            {
                button_end(true);
                return;
            }

            try
            {

                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                if (BoardID == cmd.boardNo && cmd.loopNo == Loop)
                {
                    int RepeaterID = cmd.repeaterNo;

                    RCVData_WriteRepeaterInputUNIT ResponseData = (RCVData_WriteRepeaterInputUNIT)cmd.ResponseData;

                    RepeaterPointUnit newdata = new RepeaterPointUnit(BoardID, ResponseData.Data);
                    //데이터저장
                    ReceiverTypeInfo Receiverinfo = mdi.ui.MyReceiverTypeInfo;       //수신기설정
                    BoardTypeInfo brdinfo = Receiverinfo.Get_RepeaterType(BoardID);     //통신보드savBoardID의 loop0의 설정값
                    RepeaterPointUnit[] repdata;

                    if (savLoop == 0)
                    {
                        repdata = brdinfo.Loop0_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else
                    {
                        repdata = brdinfo.Loop1_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    repdata[RepeaterID - 1] = newdata;

                    //각 셀에 중계기 데이터 표시
                    GRIDCELL[RepeaterID - 1].Set_DeviceUnit(newdata);

                    //dataGridView2에 데이터 표시
                    RepeaterDeviceTypeInfo dev = GRIDCELL[RepeaterID - 1].DeviceInfo;
                    RepeaterPointUnit unit = GRIDCELL[RepeaterID - 1].DeviceUnit;
                    DeviceStatus(dev, unit);
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.Source), Application.ProductName);
            }
            finally
            {
                //버튼 비활성 해제
                button_end(true);
            }
        }

        // cyim 2016.10.31 : 계통정보는 0,1,2,3 으로 변경
        //중계기 출력쓰기 완료
        public void RepeaterOutputWriteComplete(CmdInfo cmd)
        {
            //에러응답처리
            if (!Util.ComInfoErrProcess(cmd, mdi.ui.Connected, "RCVData_WriteRepeaterOutputUNIT")) // cyim 2015.7.23 NACK 처리 부분 오류 
            {
                button_end(true);
                return;
            }

            try
            {
                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                if (BoardID == cmd.boardNo && cmd.loopNo == Loop)
                {
                    int RepeaterID = cmd.repeaterNo;

                    RCVData_WriteRepeaterOutputUNIT ResponseData = (RCVData_WriteRepeaterOutputUNIT)cmd.ResponseData;

                    RepeaterPointUnit newdata = new RepeaterPointUnit(BoardID, ResponseData.Data);
                    //데이터저장
                    ReceiverTypeInfo Receiverinfo = mdi.ui.MyReceiverTypeInfo;       //수신기설정
                    BoardTypeInfo brdinfo = Receiverinfo.Get_RepeaterType(BoardID);     //통신보드savBoardID의 loop0의 설정값
                    RepeaterPointUnit[] repdata;

                    if (savLoop == 0)
                    {
                        repdata = brdinfo.Loop0_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 1)
                    {
                        repdata = brdinfo.Loop1_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 2)
                    {
                        repdata = brdinfo.Loop2_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else if (savLoop == 3)
                    {
                        repdata = brdinfo.Loop3_RepeaterUnit_Data;   //127개 중계기 데이터
                    }
                    else
                    {
                        repdata = null;
                    }

                    repdata[RepeaterID - 1] = newdata;

                    //각 셀에 중계기 데이터 표시
                    GRIDCELL[RepeaterID - 1].Set_DeviceUnit(newdata);

                    //dataGridView2에 데이터 표시
                    RepeaterDeviceTypeInfo dev = GRIDCELL[RepeaterID - 1].DeviceInfo;
                    RepeaterPointUnit unit = GRIDCELL[RepeaterID - 1].DeviceUnit;
                    DeviceStatus(dev, unit);

                    if (this.tRepeaterReadThreadStatus == 1)
                    {
                        this.tRepeaterReadThread = new Thread(this.RepeaterInfoRead);
                        this.tRepeaterReadThreadStatus = 1;
                        this.tRepeaterReadThread.Start();
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
            finally
            {
                //버튼 비활성 해제
                button_end(true);
            }
        }

        // 쓰기버튼
        private void btnOutWrite_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    // 상위에 통신보드 아이디와 채널계통 정보를 가져온다                    
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);

                    // 중계기 인덱스
                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                    if (no <= 127)
                    {
                        SocketUI ui = this.mdi.ui;

                        //
                        // 회로 정보
                        //
                        RepeaterPointUnit unit = GRIDCELL[no - 1].DeviceUnit;
                        RepeaterDeviceTypeInfo Info = GRIDCELL[no - 1].DeviceInfo;
                        if (Info == null || unit == null)
                        {
                            MessageBox.Show("회로설정 및 데이터를 읽을수 없습니다", Application.ProductName);
                            return;
                        }

                        // cyim 2015.2.23 계통차단시에는 사용불가                             
                        if (LoopCut() == true
                            // cyim 2015.2.23 중계기차단시에는 사용불가 
                            || Info.CutFlag == true)
                        {
                            MessageBox.Show("차단중에는 사용할수 없습니다", Application.ProductName);
                            return;
                        }

                        // cyim 2015.2.24 통신에러는 쓰기 금지
                        if (unit.RepeaterErr == true)
                        {
                            MessageBox.Show("통신 에러중에는 사용할 수 없습니다", Application.ProductName);
                            return;
                        }

                        //
                        // 출력 회로 값 쓰기
                        //
                        if (MessageBox.Show("실제로 화재 및 설비 연동감지가 될수 있습니다. 그래도 출력쓰기를 하시겠습니까?", Application.ProductName, MessageBoxButtons.OKCancel)
                            == DialogResult.OK)
                        {
                            //
                            // 회로 정보를 담는 클래스
                            //
                            InputIDVo vo = new InputIDVo();
                            vo.ReceiverID = int.Parse(txtThisReceiverID.Text);
                            vo.CommID = 1;
                            vo.BoardID = Util.StrToInt(txtBoardID.Text, 0);
                            vo.LoopNo = Util.StrToInt(txtLoopNo.Text, 0);
                            vo.RepeaterID = no;
                            vo.RepeaterType = Info.RepeaterType;
                            vo.InoutType = "O";

                            //
                            // 출력디바이스 상태 (InputIDVo 전용)
                            //
                            //출력회로상태값 초기상태(-1),출력없음(0),출력있음(1),차단(3)
                            //public enum OutputDeviceStatus { Init = -1, NotWrite = 0, Write = 1, Blocking = 3 }
                            OutputDeviceStatus[] devData = new OutputDeviceStatus[4]{
                                unit.Repeater_Output1   // NotWrite
                                ,unit.Repeater_Output2  // NotWrite
                                ,unit.Repeater_Output3  // NotWrite
                                ,unit.Repeater_Output4};// NotWrite
                            // 출력디바이스 상태 추가
                            vo.OutputUnitData = devData;

                            //
                            // 모달대화상자를 출력
                            //
                            IWin32Window window = this;
                            frmModalUnitDataSelect frm = new frmModalUnitDataSelect(Info); // cyim 2015.2.23 회로차단시에는 사용불가 
                            frm.InputVo = vo;
                            frm.ShowDialog(window);
                            vo = frm.InputVo; // 다이얼로그 출력이후 원하는 회로값이 상이함

                            // 확인 버튼을 누름 (입력한 코드가 있다면)
                            if (vo.InputOK)
                            {
                                // cyim 2013.9.3 출력쓰기 시도시 테스트 모드로 진입
                                this.mdi.SetInputTestMode(true);

                                // cyim 2015.2.27 출력 쓰기 사용중
                                mdi.CommandLog(MappingStatus.Log, string.Format("출력테스트 실행 CommID:{0},LoopNo:{1},BoardID:{2},RepeaterID:{3},devID:{4}-{5}-{6}-{7}",
                                    vo.CommID, vo.LoopNo, vo.BoardID, vo.RepeaterID, vo.OutputUnitData[0], vo.OutputUnitData[1], vo.OutputUnitData[2], vo.OutputUnitData[3]));

                                // 중계기 데이타
                                RepeaterData outputdata = new RepeaterData((byte)vo.RepeaterID);

                                devData = vo.OutputUnitData;
                                outputdata.Set_Output_Data(
                                    devData[3] == OutputDeviceStatus.Blocking ? true : false
                                    , devData[2] == OutputDeviceStatus.Blocking ? true : false
                                    , devData[1] == OutputDeviceStatus.Blocking ? true : false
                                    , devData[0] == OutputDeviceStatus.Blocking ? true : false
                                    , devData[3] == OutputDeviceStatus.Write ? true : false
                                    , devData[2] == OutputDeviceStatus.Write ? true : false
                                    , devData[1] == OutputDeviceStatus.Write ? true : false
                                    , devData[0] == OutputDeviceStatus.Write ? true : false
                                    );

                                //완료이벤트
                                dCommandResponse d = new dCommandResponse(RepeaterOutputWriteComplete);

                                //명령생성 및 실행
                                CmdInfo cmd = new CmdInfo(
                                    prt_cmd_define.write_repeater_output_unit,
                                    mdi.myReceiverID, // 수신기 아이디
                                    1, // CommID (1-통신보드 3-IO보드 4-KEYPAD 5-비상방송)
                                    vo.LoopNo, //채널계통
                                    vo.BoardID,  // 통신보드
                                    vo.RepeaterID, // 중계기 아이디 
                                    d); // 완료이벤트
                                cmd.CommandData = outputdata;
                                ui.runCommand(cmd);

                                //연동으로 인해 출력값이 변경될 수 있으므로 계속 읽는다..
                                //this.tRepeaterReadThread = new Thread(this.RepeaterInfoRead);
                                this.tRepeaterReadThreadStatus = 1;
                                //this.tRepeaterReadThread.Start();
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.StackTrace), Application.ProductName);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.btnRepeaterAllInfo_Click(null, null);
        }

        // 더블 클릭시 입력 강제 테스트 실행
        private void dataGridView2_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // 입력신호 중 1개 선택시에만 동작                
                if (this.dataGridView_Repeater_Sub.SelectedCells.Count == 1)
                {
                    DataGridViewCell cell = this.dataGridView_Repeater_Sub.SelectedCells[0];

                    // 입력 회로 선택시
                    if (cell.RowIndex == 0)
                    {
                        // 상단의 계통검색 UI
                        int CommID = 1;
                        int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                        int LoopNo = Util.StrToInt(txtLoopNo.Text, 0);

                        // 상단의 중계기 UI
                        DataGridViewCell repCell = this.dataGridView_Repeater_Main.SelectedCells[0];
                        int RepeaterID = (repCell.RowIndex * 10) + repCell.ColumnIndex + 1;
                        int devID = cell.ColumnIndex + 1;

                        // cyim 2015.7.6 아날로그 감지기는 입력테스트 불가	
                        if (AnalogDetecterRepeaterID_Hashtable.ContainsKey(RepeaterID.ToString()) == true)
                        {
                            MessageBox.Show("중계기 타입 2*2 혹은 4*4 만 가능합니다", Application.ProductName);
                            return;
                        }

                        // cyim 2014.4.3 입력 강제 시험시에 회로정보가 없는지 확인
                        //
                        // 회로 정보
                        //

                        RepeaterPointUnit unit = GRIDCELL[RepeaterID - 1].DeviceUnit;
                        RepeaterDeviceTypeInfo Info = GRIDCELL[RepeaterID - 1].DeviceInfo;
                        if (Info == null || unit == null)
                        {
                            MessageBox.Show("회로설정 및 데이터를 읽을수 없습니다", Application.ProductName);
                            return;
                        }
                        // cyim 2015.2.23 회로차단시에는 사용불가 
                        if (Info.inDeviceTypeInfos[devID - 1].CutFlag == true
                            // cyim 2015.2.23 계통차단시에는 사용불가 
                            || LoopCut() == true
                            // cyim 2015.2.23 중계기차단시에는 사용불가 
                            || Info.CutFlag == true)
                        {
                            MessageBox.Show("차단중에는 사용할수 없습니다", Application.ProductName);
                            return;
                        }

                        //if (MessageBox.Show(string.Format("cell = {0} {1} {2} {3} {4}", CommID, BoardID, LoopNo, RepeaterID, devID), "", MessageBoxButtons.OKCancel) == DialogResult.OK) {
                        if (MessageBox.Show(string.Format("입력 강제 시험을 하겠습니까? 출력 연동이 될수 있습니다"), "입력 시험", MessageBoxButtons.OKCancel) == DialogResult.OK)
                        {
                            this.mdi.SetInputTestMode(true);

                            SocketUI ui = mdi.ui;

                            //명령생성 및 실행
                            //중계기 설정 데이터를 CmdInfo에 넣어준다..
                            CmdInfo cmd = new CmdInfo(
                                prt_cmd_define.write_repeater_input_unit,
                                mdi.myReceiverID,
                                CommID,
                                LoopNo,
                                BoardID,
                                RepeaterID,
                                null);

                            // cyim 2015.2.27 입력 쓰기 테스트 모드 사용중
                            mdi.CommandLog(MappingStatus.Log, string.Format("입력테스트 실행 CommID:{0},LoopNo:{1},BoardID:{2},RepeaterID:{3},devID:{4}", CommID, LoopNo, BoardID, RepeaterID, devID));

                            switch (devID)
                            {
                                case 1:
                                    {
                                        cmd.CommandData = (byte)0xFC;
                                        break;
                                    }
                                case 2:
                                    {
                                        cmd.CommandData = (byte)0xF3;
                                        break;
                                    }
                                case 3:
                                    {
                                        cmd.CommandData = (byte)0xCF;
                                        break;
                                    }
                                case 4:
                                    {
                                        cmd.CommandData = (byte)0x3F;
                                        break;
                                    }
                            }
                            ui.runCommand(cmd);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
            }
        }

        // cyim 2013.3.13
        // 입력쓰기 테스트 이후 복구 버튼을 눌러서 중계기 별로 복구하도록 명령한다 
        // 중계기 복구  
        private void btnRepeaterReset_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
                {
                    int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                    int Loop = Util.StrToInt(txtLoopNo.Text, -1);


                    DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                    int no = (cell.RowIndex * 10) + cell.ColumnIndex + 1;


                    if (no <= 127)
                    {
                        //2019-12-10 수정 QA파트 요청
                        //if (MessageBox.Show(string.Format("중계기 [" + no + "] 를 복구할까요?"), "중계기 복구", MessageBoxButtons.OKCancel) == DialogResult.OK)
                        if (MessageBox.Show(string.Format(Loop + "번 Loop를 복구할까요?"), "중계기 복구", MessageBoxButtons.OKCancel) == DialogResult.OK)
                        {
                            // MDIParent
                            LFC.Log("타입: 수신기 조작 로그, 메세지: 중계기 개별복구 실행");
                            SocketUI ui = this.mdi.ui;

                            //완료이벤트 (사용되어야 할지는 미지수)
                            dCommandResponse d = new dCommandResponse(RepeaterRecoverComplete);

                            //명령생성 및 실행
                            CmdInfo cmd = new CmdInfo(
                                prt_cmd_define.reset_repeater_all, // 중계기 Block 복구
                                mdi.myReceiverID,
                                1, // 컴포트 아이디
                                Loop, // 채널계통
                                BoardID, // 통신보드
                                no, // 중계기 아이디
                                null);
                            ui.runCommand(cmd);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Util.UErrorMessage(ex, 0, 0);
                //MessageBox.Show(ex.Message, Application.ProductName);
                //MessageBox.Show(string.Format("[{0}]\r\n{1}", ex.Message, ex.StackTrace), Application.ProductName);
            }
        }

        // cyim 2015.6.8 아날로그 감지기 연동 추가
        // 중계기 상태보기 메인 - 셀을 더블 클릭하는 경우
        private void dataGridView_Repeater_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (this.dataGridView_Repeater_Main.SelectedCells.Count > 0)
            {
                //int CommID = 1;
                // 보드 아이디
                int BoardID = Util.StrToInt(txtBoardID.Text, 0);
                // 루프 번호
                int Loop = Util.StrToInt(txtLoopNo.Text, -1);
                // 중계기 아이디
                DataGridViewCell cell = this.dataGridView_Repeater_Main.SelectedCells[0];
                int RepeaterID = (cell.RowIndex * 10) + cell.ColumnIndex + 1;

                RepeaterPointUnit unit = GRIDCELL[RepeaterID - 1].DeviceUnit;
                RepeaterDeviceTypeInfo Info = GRIDCELL[RepeaterID - 1].DeviceInfo;

                if (Info == null || unit == null)
                {
                    MessageBox.Show("회로설정 및 데이터를 읽을수 없습니다..", Application.ProductName);
                    return;
                }

                // 계통차단시에는 사용불가
                if (LoopCut() == true
                    // 중계기차단시에는 사용불가 
                    || Info.CutFlag == true)
                {
                    MessageBox.Show("차단중에는 사용할수 없습니다..", Application.ProductName);
                    return;
                }

                // 창은 하나만 띄우도록 함
                if (mdi.AnalogDetect.Form_Active_AnalogDetecter == true) // cyim 2015.8.4 수신반을 위한 static 클래스 정리
                {
                    MessageBox.Show("이미 실행중입니다...", Application.ProductName);
                    return;
                }

                /*
                if (FormRepeater != null)
                {
                    FormRepeater.Close();
                }

                FormRepeater = new FormRepeater(this.mdi);
                FormRepeater.Owner = this;
                FormRepeater.Visible = false;
                FormRepeater.Show();// 데이타를 아직 표시하지 않았으므로 표시는 하지 않는다.
                FormRepeater.Visible = false;

                string[] Input_locatin = new string[4];
                string[] output_locatin = new string[4];
                string[] Input_context = new string[4];
                string[] output_context = new string[4];
                string[] Input_circuit = new string[4];
                string[] output_circuit = new string[4];

                string InOut_Type = "I";

                //회로설정값 
                DacUIProcess dacUIProcess = new DacUIProcess(mdi.myReceiverID); // cyim 2015.7.30 데이타베이스 접속 루틴 변경
                for (var i = 0; i < 4; i++)
                {
                    DataTable dt2 = dacUIProcess.Device_Select(mdi.myReceiverID, CommID, BoardID, Loop, RepeaterID, i + 1, InOut_Type);
                    foreach (DataRow dr2 in dt2.Rows)
                    {
                        Input_context[i] = Util.NullToStr(dr2["DEVICE_TYPE_NAME"]);
                        Input_locatin[i] = Util.NullToStr(dr2["POSITION_NAME"]);
                        Input_circuit[i] = Util.NullToStr(dr2["DEVICE_NAME"]);
                    }
                    dt2.Clear();
                    dt2.Dispose();
                }

                InOut_Type = "O";
                for (var i = 0; i < 4; i++)
                {
                    DataTable dt2 = dacUIProcess.Device_Select(mdi.myReceiverID, CommID, BoardID, Loop, RepeaterID, i + 1, InOut_Type);
                    foreach (DataRow dr2 in dt2.Rows)
                    {
                        output_context[i] = Util.NullToStr(dr2["DEVICE_TYPE_NAME"]);
                        output_locatin[i] = Util.NullToStr(dr2["POSITION_NAME"]);
                        output_circuit[i] = Util.NullToStr(dr2["DEVICE_NAME"]);
                    }
                    dt2.Clear();
                    dt2.Dispose();
                }

                // 입력
                FormRepeater.SetInputContext1(string.Format(
                  "\r\n" + DeviceStatusText.InputText(unit.Repeater_Input1, Info.inDeviceTypeInfos[0]) +
                  "\r\n\r\n" + Input_context[0] +
                  "\r\n\r\n" + Input_locatin[0] +
                  "\r\n\r\n" + Input_circuit[0]));
                FormRepeater.SetInputContext2(string.Format(
                  "\r\n" + DeviceStatusText.InputText(unit.Repeater_Input2, Info.inDeviceTypeInfos[1]) +
                  "\r\n\r\n" + Input_context[1] +
                  "\r\n\r\n" + Input_locatin[1] +
                  "\r\n\r\n" + Input_circuit[1]));
                FormRepeater.SetInputContext3(string.Format(
                  "\r\n" + DeviceStatusText.InputText(unit.Repeater_Input3, Info.inDeviceTypeInfos[2]) +
                  "\r\n\r\n" + Input_context[2] +
                  "\r\n\r\n" + Input_locatin[2] +
                  "\r\n\r\n" + Input_circuit[2]));
                FormRepeater.SetInputContext4(string.Format(
                  "\r\n" + DeviceStatusText.InputText(unit.Repeater_Input4, Info.inDeviceTypeInfos[3]) +
                  "\r\n\r\n" + Input_context[3] +
                  "\r\n\r\n" + Input_locatin[3] +
                  "\r\n\r\n" + Input_circuit[3]));

                // 출력회로
                FormRepeater.SetOutPutText1(string.Format(
                  "\r\n" + DeviceStatusText.OutputText(unit.Repeater_Output1, Info.outDeviceTypeInfos[0]) +
                  "\r\n\r\n" + output_context[0] +
                  "\r\n\r\n" + output_locatin[0] +
                  "\r\n\r\n" + output_circuit[0]));
                FormRepeater.SetOutPutText2(string.Format(
                  "\r\n" + DeviceStatusText.OutputText(unit.Repeater_Output2, Info.outDeviceTypeInfos[1]) +
                  "\r\n\r\n" + output_context[1] +
                  "\r\n\r\n" + output_locatin[1] +
                  "\r\n\r\n" + output_circuit[1]));
                FormRepeater.SetOutPutText3(string.Format(
                  "\r\n" + DeviceStatusText.OutputText(unit.Repeater_Output3, Info.outDeviceTypeInfos[2]) +
                  "\r\n\r\n" + output_context[2] +
                  "\r\n\r\n" + output_locatin[2] +
                  "\r\n\r\n" + output_circuit[2]));
                FormRepeater.SetOutPutText4(string.Format(
                  "\r\n" + DeviceStatusText.OutputText(unit.Repeater_Output4, Info.outDeviceTypeInfos[3]) +
                  "\r\n\r\n" + output_context[3] +
                  "\r\n\r\n" + output_locatin[3] +
                  "\r\n\r\n" + output_circuit[3]));

                // 위치
                FormRepeater.Location = new Point(Control.MousePosition.X + 5, Control.MousePosition.Y + 5);
                //표시
                FormRepeater.Visible = true;
                */

                // 해당 셀이 중계기가 아닌 아날로그 감지기인 경우에 한하여 
                if (Info.RepeaterType.Equals("A") == true || Info.RepeaterType.Equals("B") == true)
                {
                    // 특별히 경고 팝업은 생성하지 않는다
                    return;
                }

                // cyim 2016.01.07 아날로그 감지기 통신이상, 존재하지않음의 경우에는 더블클릭을 못하도록 함
                if (unit.RepeaterNon == true     // 존재하지 않는 감지기
                    || unit.RepeaterErr == true  // 감지기 통신 에러
                    || unit.RepeaterErr == true  // 감지기 전원 이상
                    )
                {
                    // 특별히 경고 팝업은 생성하지 않는다
                    return;
                }

                mdi = (MDIParent)this.MdiParent;
                txtThisReceiverID.Text = string.Format("{0:00}", mdi.myReceiverID);

                Form_AnalogDetecter AnalogDetecter = new Form_AnalogDetecter(
                    string.Format("{0:00}", mdi.myReceiverID),
                    string.Format("{0:000}", BoardID),
                    string.Format("{0:000}", Loop),
                    string.Format("{0:000}", RepeaterID),
                    Info.RepeaterType.ToString(),
                    mdi);
                AnalogDetecter.Show();
            }
        }
    }
}