using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskBand;
using System.Linq;
using System.Data.SqlTypes;
using System.Diagnostics;
using vmsnet.Attributes;
using vmsnet.Configures;
using AR;
using ScottPlot.TickGenerators.TimeUnits;
namespace vmsnet.HMI
{
    public enum RelayControl
    {
        [Coil(address: 10)]
        mKA
    }
    public enum ESTATUS
    {
        가동,
        이상,
        대기,
        기타,
        미사용
    }
    public enum EDRAGTYPE
    {
        GROUP
    }
    public enum EBUTTONTYPE
    {
        CELL,
        GROUP,
        NBZERO,
        NBRESET,
        PRINT,
        SELGROUP,
    }
    public partial class DispCtrl : UserControl
    {
        public bool MonitorOn { get; set; }
        public CMouseinfo Mouseinfo;    //마우스위치정보
        //그룹데이터
        public CGROUP[] GROUPS = new CGROUP[0];
        public CWINDOW WINDOW = new CWINDOW();
        object grplock = new object();
        public void ResizeGroup(int newsize)
        {
            lock (grplock)
            {
                if (newsize > this.GROUPS.Length)
                {
                    Array.Resize(ref GROUPS, newsize);
                }
            }
        }
        public void SetItemDisable()
        {
            lock (grplock)
            {
                foreach (var g in GROUPS)
                {
                    foreach (var gi in g.Items)
                    {
                        gi.활성화 = false;
                        gi._onalamh = false;
                        gi._onalaml = false;
                        gi._onalamover = false;
                        gi._p_onalamh = false;
                        gi._p_onalaml = false;
                        gi._p_onalamover = false;
                        gi.mtime = "";
                    }
                }
            }
        }
        public int GroupCount
        {
            get
            {
                if (GROUPS == null) return 0;
                if (GROUPS.Any() == false) return 0;
                return GROUPS.Length;
            }
        }
        public int GroupItemCount
        {
            get
            {
                if (GROUPS == null) return 0;
                if (GROUPS.Any() == false) return 0;
                return GROUPS[0].Items.Length;
            }
        }
        //public void SetGroupItem(CGROUP[] grp)
        //{
        //    lock (grplock)
        //    {
        //        GROUPS = grp;
        //    }
        //}
        //public void SetGroupItem(int idx, CGROUP item)
        //{
        //    lock (grplock)
        //    {
        //        GROUPS[idx] = item;
        //    }
        //}
        //public CGROUP[] GetGroupItem()
        //{
        //    lock (grplock)
        //    {
        //        return this.GROUPS;
        //    }
        //}
        private bool[,,] received;
        private int[,,] _values;
        private String[,,] times;
        private Boolean _init = false;    //그리드초기화완료여부
        private String _initmsg = "initializing...";
        public int initpercent = 0;
        //미정리
        public int ZoneMarginX = 0;
        public int ZoneMarginY = 50;
        public Font Font_Nav = new Font("arial", 9);
        private Font FONT_NANUM_20_BOLD = new Font("나눔고딕", 20, FontStyle.Bold);
        private Font FONT_TAHOMA_80_BOLD = new Font("tahoma", 80, FontStyle.Bold);
        /// 
        /// 데이터가 지정된 시간이 넘어가면 이벤트를 이용해서 알림을함(외부의 트렌드뷰에서 사용하려고함)
        ///  
        public int NotifyDataSecond = 2;
        private DateTime LastNotifyTime = DateTime.Now.AddSeconds(-60);
        //alam1 blick
        private short blink1 = 0;
        private short blink2 = 0;
        private Boolean A1 = false;
        private Boolean A2 = false;
        public int SmallSize = 300;
        //140829 데이터분주 추가 (arin)
        public int datadiv = 1;
        public Font FONT_NB = new Font("Tahoma", 30, FontStyle.Bold);
        public Font FONT_CN = new Font("Tahoma", 8, FontStyle.Bold);
        public Font FONT_CV = new Font("Tahoma", 9, FontStyle.Bold);
        public Font FONT_CT = new Font("Tahoma", 8, FontStyle.Bold);
        public Font FONT_AV = new Font("Tahoma", 7, FontStyle.Bold);
        public Font FONT_KA = new Font("Arial", 40, FontStyle.Bold);    //ka-value 
        public Font FONT_KU = new Font("Arial", 10, FontStyle.Bold);    //ka-unit
        public bool EnableKA { get; set; } = false;
        /// 
        /// 개별보기일때 현재 표시해야할 아이템의 값이 변한경우
        ///  
        public event OnChangedShowIndexHandler OnChangedShowIndex;
        public delegate void OnChangedShowIndexHandler(int index);
        public event OnNotifyDataHandler OnNotifyData;
        public delegate void OnNotifyDataHandler(DateTime datetCurrenttime);
        //MY EVENT
        public event OnClickPrintHandler OnClickPrint;  //click print
        public delegate void OnClickPrintHandler(CGROUP idx);
        public event OnClickProbeSensorHandler OnClickCell; //셀클릭
        public delegate void OnClickProbeSensorHandler(CITEM idx, MouseEventArgs e);
        public event OnClickGroupHandler OnClickGroup;  //그룹클릭
        public delegate void OnClickGroupHandler(CGROUP idx, MouseEventArgs e);
        public event OnSetNBHandler OnSetNullbalance;  //그룹클릭
        public delegate void OnSetNBHandler(CGROUP grp, Single value);
        public event OnAlamChangeHHandler OnAlamChange;  //알람이 변경되었을경우(활성/비활성)
        public delegate void OnAlamChangeHHandler(int ch, COMM.EALAMRAISETYPE raisetype, COMM.EALAMTYPE atype, String AM, Single value, Single maxvalue, Single minvalue, string remark);
        public event OnRaiseAlamChangeHHandler RaiseAlarm;  //알람이 변경되었을경우(활성/비활성)
        public delegate void OnRaiseAlamChangeHHandler(Boolean On);
        public Boolean _raise_alarm = false;         //알람발생여부
        public Boolean _raise_alarm_pre = false;     //알람발생여부(이전)
        private short _raise_alarm_count = 0;           //셀알람발생카운트(모든그룹의합)
        private short _raise_alarm_nbcount = 0;         //셀알람발생카운트(모든그룹의합)
        private short _pre_raise_alarm_count = 0;       //이전알람발생시 만들어진 카운터
        private short _pre_raise_alarm_nbcount = 0;     //이전알람발생시 만들어진 널밸런트 카운터
        public Boolean NullbalanceRealValue = true;
        public Boolean Sumab = false; //150320 
        //private CTrendData TrendData = new CTrendData();            
        //화면디자인관련
        private Color bordercolor;  //테두리 색상
        private Cursor cursor = Cursors.Default;    //현재커서의모양
        private SolidBrush SB_White_200 = new SolidBrush(Color.FromArgb(200, Color.White));
        private SolidBrush SB_WhiteSmoke_200 = new SolidBrush(Color.FromArgb(200, Color.WhiteSmoke));
        private SolidBrush SB_Black_150 = new SolidBrush(Color.FromArgb(200, Color.Black));
        public Color design_backcolor_start;
        public Color design_backcolor_normal;
        private string Warn_msg = "";   //경고메세지(화면 최상단중앙에 표시됨)
        private Font Warn_Font;
        private Font alamfont = new Font("Arial", 8, FontStyle.Bold); //ALAMICON_01
        //기타설정'
        // public Rectangle[] GroupRect; //그룹머릿글
        //  public Rectangle headRect;  //머릿부분
        //  public Rectangle ItemRect;  //아이템표시영역(전체)
        //  public Rectangle[] ItemsRect; //세부아이템표시영역(MATRIX 값에따라서 갯수가 변경된다)
        //  public Rectangle[] NBRects; //nullbalance Area (그룹갯수별로 잇기때문에 여러개가된다)
        public RectangleF WindowRect;   //윈도우데이터가표시되는 영역
                                        // public RectangleF BarRect;      //바그래프가 표시되는 영역
                                        // public RectangleF TrendRect;    //트렌드뷰가 표시되는 영역
                                        //  public RectangleF NavRect;      //네비게이션이 표시되는 영역
        private Font font_grouptitle = new Font("나눔고딕", 20, FontStyle.Bold);
        private Font font_header = new Font("나눔고딕", 10, FontStyle.Bold);
        private Color font_grouptitle_color = Color.Red;
        private Color font_header_color = Color.Yellow;
        //private List Buttons = new List(0);
        //private List Buttonstag = new List(0);
        //private List Buttonstype = new List(0);
        private List Buttons = new List();
        public Boolean bMakeRect = true;
        /// 
        /// 개별보기? 전체보기?
        ///  
        private Boolean _FullScreen;
        public Boolean FullScreen
        {
            get
            {
                return _FullScreen;
            }
            set
            {
                _FullScreen = value;
                if (!_FullScreen)
                {
                    ShowIndex = 0;
                }
                else ShowIndex = -1;
            }
        }
        private int _showindex = -1;
        /// 
        /// 개별보기 모드일때 현재 화면에 표시할 그룹의 인덱스
        ///              
        public int ShowIndex
        {
            get
            {
                return _showindex;
            }
            set
            {
                if (FullScreen)
                {
                    //전체홤녀일경우에는 사용하지 않는다.
                    _showindex = -1;
                }
                else
                {
                    if (value != -1 && value != _showindex)
                    {
                        _showindex = value;
                        if (OnChangedShowIndex != null) OnChangedShowIndex(_showindex);
                    }
                }
            }
        }
        #region *** Constructors ***
        /// 
        /// 데이터를 수신했는지
        ///  
        public bool[,,] Received
        {
            get { return this.received; }
            set { this.received = value; }
        }
        public int[,,] _Values
        {
            get { return this._values; }
            set { this._values = value; }
        }
        public String[,,] Times
        {
            get { return this.times; }
            set { this.times = value; }
        }
        public Color Font_Grouptitle_Color
        {
            get { return this.font_grouptitle_color; }
            set { this.font_grouptitle_color = value; }
        }
        public Color Font_Header_Color
        {
            get { return this.font_header_color; }
            set { this.font_header_color = value; }
        }
        public Font Font_Grouptitle
        {
            get { return this.font_grouptitle; }
            set { this.font_grouptitle = value; }
        }
        public Font Font_Header
        {
            get { return this.font_header; }
            set { this.font_header = value; }
        }
        public DispCtrl()
        {
            InitializeComponent();
            // Initialize Variables
            // Set Optimized Double Buffer to reduce flickering
            this.SetStyle(ControlStyles.UserPaint, true);
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            // Redraw when resized
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.Font = SystemInformation.MenuFont;
            this.Warn_Font = new Font("나눔고딕", 20, FontStyle.Bold);
            this.Font_Grouptitle = new Font("나눔고딕", 25, FontStyle.Bold);
            this.Font_Header = new Font("나눔고딕", 20, FontStyle.Bold);
            this.bordercolor = Color.LightGray;
            this.Warn_msg += ("메세지가 없습니다");
            this.design_backcolor_normal = Color.DarkBlue;
            this.design_backcolor_start = Color.Black;
            this.FullScreen = false;
        }
        private void InitializeComponent()
        {
            this.Name = "DispCtrl";
            this.Size = new System.Drawing.Size(287, 321);
            this.Load += new System.EventHandler(this.DispCtrl_Load);
            this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.DispCtrl_MouseDown);
            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.DispCtrl_MouseMove);
            this.Resize += arLabel_Resize;
        }
        void arLabel_Resize(object sender, EventArgs e)
        {
            Invalidate();
        }
        public Boolean init
        {
            get { return this._init; }
            set { this._init = value; }
        }
        private void DispCtrl_Load(object sender, EventArgs e)
        {
        }
        #endregion
        #region *** Properties ***
        /// 
        /// 경고메세지를 반환합니다.
        ///  
        public string Message_Warning
        {
            get { return this.Warn_msg.ToString(); }
            set
            {
                if (value == null || string.IsNullOrEmpty(value)) Warn_msg = "";
                else Warn_msg += (value) + "\r\n";
            }
        }
        /// 
        /// 테두리색상
        ///  
        public Color BorderColor
        {
            get { return this.bordercolor; }
            set
            {
                bordercolor = value;
                Update();
            }
        }
        #endregion
        private RectangleF[] GetRectangleTitle(Graphics g, RectangleF ItemRect, CGROUP grp, Boolean isprint)
        {
            Font applyfont = this.FONT_CT;// grp.셀글꼴;
            if (isprint) applyfont = new Font(applyfont.FontFamily, 6, FontStyle.Bold);
            String Cellno = grp.maxcellname;
            SizeF CellNoSize = g.MeasureString(Cellno, applyfont);
            SizeF CellAlSize = g.MeasureString("88/88", applyfont);
            //-------------  | -----------  |  ------------
            //    cell             pv              alarm
            //-------------  | -----------  |  ------------
            Single H = (Single)(CellNoSize.Height * 2.5);   //높이값
            Single NameSize = (Single)(CellNoSize.Width * 1.05); //살짝더크게
            Single PvSize = ItemRect.Width - (Single)(CellNoSize.Width * 1.05) - (Single)(CellAlSize.Width);
            Single AlamSize = ItemRect.Width - NameSize - PvSize;
            RectangleF CellNoRect = new RectangleF(ItemRect.Left, ItemRect.Top, NameSize, H);
            RectangleF CellPvRect = new RectangleF(CellNoRect.Left + CellNoRect.Width, ItemRect.Top, PvSize, H);
            RectangleF CellALRect = new RectangleF(CellPvRect.Left + CellPvRect.Width, ItemRect.Top, AlamSize, H);
            return new RectangleF[3] { CellNoRect, CellPvRect, CellALRect };
        }
        private void DrawItem(Graphics g, CGROUP grp, RectangleF R, short CellGroupidx, Boolean isprint, Boolean isVisible)
        {
            RectangleF[] CellTitleRect = DrawCellTitle(g, R, grp, isprint);   //0번은 title label ,1 번은 value label
            grp._cell_title_width = CellTitleRect[0].Width;  //셀의 제목표시줄(번호)의 너비값
            grp._cell_value_width = CellTitleRect[1].Width;  //셀의 제목표시줄(값)의 너비값
            grp._cell_alam_width = CellTitleRect[2].Width;   //셀의 알람표시줄의 너비값
            Single height = R.Height - CellTitleRect[0].Height; //채널표시영역의 옾이값
            //실제채널이 표시되는 데이터 표시
            RectangleF channelarea = new RectangleF(R.Left, R.Top + CellTitleRect[0].Height, R.Width, height);
            if (isVisible) DrawCellMatrix(g, channelarea, grp, CellGroupidx, isprint);
            //vertical line
            Single lx = R.Left + grp._cell_title_width;
            if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top, lx, R.Top + R.Height);
            lx += grp._cell_value_width;
            if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top, lx, R.Top + R.Height);
            if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top + (CellTitleRect[2].Height / 2), lx + grp._cell_alam_width, R.Top + (CellTitleRect[2].Height / 2));
            //lx += grp._cell_alam_width / 2;
            //if (isVisible) g.DrawLine(Pens.Silver, lx, R.Top + (CellTitleRect[2].Height / 2), lx, R.Top + R.Height);
        }
        private RectangleF[] DrawCellTitle(Graphics g, RectangleF ItemRect, CGROUP grp, Boolean isprint)
        {
            Font applyfont = this.FONT_CT;// grp.셀글꼴;
            if (isprint) applyfont = new Font(applyfont.FontFamily, 6, FontStyle.Bold);
            String Cellno = grp.maxcellname;
            SizeF CellNoSize = g.MeasureString(Cellno, applyfont);
            SizeF CellAlSize = g.MeasureString("88/88", applyfont);
            //-------------  | -----------  |  ------------
            //    cell             pv              alarm
            //-------------  | -----------  |  ------------
            Single H = (Single)(CellNoSize.Height * 2.5);   //높이값
            Single NameSize = (Single)(CellNoSize.Width * 1.05); //살짝더크게
            Single PvSize = ItemRect.Width - (Single)(CellNoSize.Width * 1.05) - (Single)(CellAlSize.Width);
            Single AlamSize = ItemRect.Width - NameSize - PvSize;
            RectangleF CellNoRect = new RectangleF(ItemRect.Left, ItemRect.Top, NameSize, H);
            RectangleF CellPvRect = new RectangleF(CellNoRect.Left + CellNoRect.Width, ItemRect.Top, PvSize, H);
            RectangleF CellALRect = new RectangleF(CellPvRect.Left + CellPvRect.Width, ItemRect.Top, AlamSize, H);
            Color gbclor;
            if (grp.AlarmType == "AUTO") gbclor = Color.SkyBlue;
            else if (grp.AlarmType == "MANUAL") gbclor = Color.LightGray;
            else gbclor = Color.Pink;   //stop
            RectangleF TITLERECT = new RectangleF(ItemRect.Left, ItemRect.Top, ItemRect.Width, H - 2);
            g.FillRectangle(new SolidBrush(gbclor), TITLERECT);
            //DRAW UNDERLINE
            g.DrawLine(Pens.DimGray, TITLERECT.Left, TITLERECT.Top + TITLERECT.Height, TITLERECT.Left + TITLERECT.Width, TITLERECT.Top + TITLERECT.Height);
            //g.DrawRectangle(Pens.Red, TITLERECT.Left, TITLERECT.Top, TITLERECT.Width, TITLERECT.Height);
            g.DrawString("Cell", applyfont, Brushes.Black, CellNoRect.Left + CellNoRect.Width / 2 - CellNoSize.Width / 2, CellNoRect.Top + CellNoRect.Height / 2 - CellNoSize.Height / 2);
            Cellno = "PV";
            CellNoSize = g.MeasureString(Cellno, applyfont);
            g.DrawString(Cellno, applyfont, Brushes.Black, CellPvRect.Left + CellPvRect.Width / 2 - CellNoSize.Width / 2, CellPvRect.Top + CellPvRect.Height / 2 - CellNoSize.Height / 2);
            Cellno = "Alarm";
            CellNoSize = g.MeasureString(Cellno, applyfont);
            String SH = "H", SL = "L";
            if (grp.AlarmType == "AUTO")
            {
                SH = "+";
                SL = "-";
            }
            SizeF a, h, l;
            a = g.MeasureString("ALM", applyfont);
            h = g.MeasureString(SH, applyfont);
            l = g.MeasureString(SL, applyfont);
            //Single y = 0, x = 0;
            g.DrawString("ALM", applyfont, Brushes.Black, CellALRect.Left + CellALRect.Width / 2 - a.Width / 2, CellALRect.Top + CellALRect.Height / 4 - a.Height / 2);
            var alrecthl = new RectangleF(CellALRect.X, CellALRect.Y + CellALRect.Height / 2f, CellALRect.Width, CellALRect.Height / 2f);
            g.DrawString($"{SH}/{SL}", applyfont, Brushes.Black, alrecthl, new StringFormat
            {
                LineAlignment = StringAlignment.Center,
                Alignment = StringAlignment.Center
            });
            return new RectangleF[3] { CellNoRect, CellPvRect, CellALRect };
        }
        public String initmsg
        {
            get { return this._initmsg; }
            set
            {
                this._initmsg = value;
                this.Refresh();
            }
        }
        /// 
        /// 화면에 표시되는 내용중 실제 셀의 내용이다. 세부내역은 이곳에서 작성됨
        ///  
        /// (0);
                //Buttonstag = new List(0);
                //Buttonstype = new List(0);
                Boolean isnull = false;
                if (!init) isnull = true;
                else
                {
                    if (this.WINDOW == null || this.GROUPS == null) isnull = true;
                    if (isnull && this.GROUPS.Length == 0) isnull = true;
                }
                //표시아이템이없다면 오류를 낸다.
                if (isnull)
                {
                    //progress
                    int bw = (int)(this.Width * 0.8);
                    int bh = 30;
                    Rectangle rr = new Rectangle((this.Width - bw) / 2, (this.Height - bh) / 2, bw, bh);
                    Rectangle FullRect = new Rectangle(0, 0, this.Width, this.Height);
                    using (var gradientBrush = new LinearGradientBrush(FullRect, Color.White, Color.White, LinearGradientMode.Vertical))
                    {
                        e.Graphics.FillRectangle(gradientBrush, FullRect);
                        SizeF initsize = e.Graphics.MeasureString(initmsg, FONT_NANUM_20_BOLD);
                        e.Graphics.DrawString(initmsg, FONT_NANUM_20_BOLD, Brushes.Black, this.Width / 2 - initsize.Width / 2, this.Height / 2 - initsize.Height / 2 - bh - 20);
                    }
                    using (var lb = new LinearGradientBrush(rr, Color.LightBlue, Color.SkyBlue, LinearGradientMode.Vertical))
                    {
                        if (initpercent > 100) initpercent = 100;
                        int perc = (int)(rr.Width * initpercent / 100);
                        e.Graphics.FillRectangle(lb, new Rectangle(rr.Left, rr.Top, perc, rr.Height));
                        e.Graphics.DrawRectangle(Pens.DarkGray, rr);
                        e.Graphics.DrawRectangle(Pens.DarkGoldenrod, FullRect.Left, FullRect.Top, FullRect.Width - 1, FullRect.Height - 1);
                    }
                    this.ResumeLayout();
                    return;
                }
                // AntiAliasing
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                //그룹목록
                DrawGroups(e.Graphics);     /* GROUPS 화면 Display !!! */
                //monitor off display
                if (MonitorOn == false)
                {
                    e.Graphics.FillRectangle(SB_WhiteSmoke_200, DisplayRectangle);
                    e.Graphics.DrawString("MONITOR PAUSE", FONT_TAHOMA_80_BOLD, Brushes.Gray, DisplayRectangle, new StringFormat
                    {
                        Alignment = StringAlignment.Center,
                        LineAlignment = StringAlignment.Center,
                    });
                }
                //if (!FullScreen && ShowIndex >= 0)
                {
                    //트렌드뷰용채널데이터를 새로 만드는경우
                    //if (bMakeTrendViewChData) MakeTrendViewChData();
                    //마지막데이터와 2초의 차이가 있다면 데이터를 생성해준다.
                    DateTime NOwdate = DateTime.Now;
                    TimeSpan ts = NOwdate - LastNotifyTime;
                    if (ts.TotalSeconds >= NotifyDataSecond)
                    {
                        //알림
                        if (OnNotifyData != null) OnNotifyData(NOwdate);
                        LastNotifyTime = NOwdate;
                    }
                }
            }
            catch (NullReferenceException ex1)
            {
                // 예외 메시지, 파일명, 행 번호를 로그에 기록
                var stackTrace = new System.Diagnostics.StackTrace(ex1, true);
                var frame = stackTrace.GetFrame(0);
                string fileName = frame.GetFileName();
                int lineNumber = frame.GetFileLineNumber();
                // UI 디스플레이 중, 예외발생 문제
                PUB.log.AddE($"NullReferenceException Message={ex1.Message}, 파일명={fileName}, 행번호={lineNumber}");
                return;
            }
            catch (Exception ex2)
            {
                // 예외 메시지, 파일명, 행 번호를 로그에 기록
                var stackTrace = new System.Diagnostics.StackTrace(ex2, true);
                var frame = stackTrace.GetFrame(0);
                string fileName = frame.GetFileName();
                int lineNumber = frame.GetFileLineNumber();
                // Else Error !!!
                PUB.log.AddE($"Exception Message={ex2.Message}, 파일명={fileName}, 행번호={lineNumber}");
                return;
            }
        }
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            bMakeRect = true;
            //bMakeBarRect = true;
            Invalidate();
        }
        private int Check_GroupHeader(MouseEventArgs e, Boolean resetshowinfo = false)
        {
            if (this.GROUPS == null) return -1;
            for (int i = 0; i < this.GROUPS.Length; i++)
            {
                RectangleF rect = this.GROUPS[i].Rect_Header;
                if (resetshowinfo) this.GROUPS[i].Showinfo = false;
                //현재위치가 해당 Rectagle 안이라면 속해있다.                    
                if (e.X > rect.X && e.X < rect.X + rect.Width)
                {
                    if (e.Y > rect.Y && e.Y < rect.Y + rect.Height)
                    {
                        //전체화면이 아닌경우에는 선택된 그룹번호를 반환
                        if (this.FullScreen == false)
                        {
                            if (this.ShowIndex < 0 || this.ShowIndex >= this.GroupCount) return -1;
                            else return this.ShowIndex;
                        }
                        else return i;
                    }
                }
            }
            return -1;
        }
        private int Check_Group(MouseEventArgs e)
        {
            if (this.GROUPS == null) return -1;
            for (int i = 0; i < this.GROUPS.Length; i++)
            {
                RectangleF rect = this.GROUPS[i].R;
                //현재위치가 해당 Rectagle 안이라면 속해있다.                    
                if (e.X > rect.X && e.X < rect.X + rect.Width)
                {
                    if (e.Y > rect.Y && e.Y < rect.Y + rect.Height) return i;
                }
            }
            return -1;
        }
        private int check_buttons(MouseEventArgs e)
        {
            if (this.Buttons == null) return -1;
            for (int i = 0; i < this.Buttons.Count; i++)
            {
                RectangleF rect = this.Buttons[i].Rect;
                //현재위치가 해당 Rectagle 안이라면 속해있다.                    
                if (e.X > rect.X && e.X < rect.X + rect.Width)
                {
                    if (e.Y > rect.Y && e.Y < rect.Y + rect.Height) return i;
                }
            }
            return -1;
        }
        private void DispCtrl_MouseDown(object sender, MouseEventArgs e)
        {
            //현재마우스위치의 아이템을 찾ㄴ은다.
            int idx = check_buttons(e);
            if (idx != -1)
            {
                CButton But = Buttons[idx];
                //Object tt = this.Buttonstag[idx];
                //EBUTTONTYPE BT = this.Buttonstype[idx];
                switch (But.ButtonType)
                {
                    case EBUTTONTYPE.SELGROUP:
                        ShowIndex = ((CGROUP)But.Tag).IDX - 1;
                        //bMakeTrendViewChData = true;
                        //bMakeBarRect = true;
                        // MakeTrendViewChData();
                        break;
                    case EBUTTONTYPE.CELL:
                        OnClickCell((CITEM)But.Tag, e);
                        break;
                    case EBUTTONTYPE.GROUP:
                        OnClickGroup((CGROUP)But.Tag, e);
                        break;
                    case EBUTTONTYPE.NBRESET:
                        //MessageBox.Show("NBRESET" + idx.ToString()  );
                        ((CGROUP)But.Tag).NullBalanceOffset = 0;
                        this.OnSetNullbalance((CGROUP)(But.Tag), 0f);
                        this.Refresh();
                        break;
                    case EBUTTONTYPE.NBZERO:
                        //MessageBox.Show("NBZERO" + idx.ToString());
                        Single Offset = ((CGROUP)But.Tag)._null_valueR - ((CGROUP)But.Tag)._null_valueL;
                        ((CGROUP)But.Tag).NullBalanceOffset = -1 * Offset;
                        this.OnSetNullbalance((CGROUP)(But.Tag), (Single)(-1 * Offset));
                        this.Refresh();
                        break;
                    case EBUTTONTYPE.PRINT:
                        OnClickPrint(((CGROUP)But.Tag));
                        break;
                }
            }
        }
        private void DispCtrl_MouseMove(object sender, MouseEventArgs e)
        {
            //마우스위치를 저장한다.
            if (this.Mouseinfo == null) this.Mouseinfo = new CMouseinfo(new PointF(e.X - WindowRect.Left, e.Y - WindowRect.Top));
            else this.Mouseinfo.Position = new PointF(e.X - WindowRect.Left, e.Y - WindowRect.Top);
            //스피드체크영역이라면 마우스를 핸드로 변경한다.
            Mouseinfo.Hand = false;
            Mouseinfo.Cross = false;
            Mouseinfo.Move = false;
            //이동중인데 마우스가 눌려있다면 DRAG다
            if (e.Button == MouseButtons.Left) Mouseinfo.Drag = true;
            else Mouseinfo.Drag = false;
            if (Mouseinfo.Drag) //드래그중이다
            {
                if (Mouseinfo.DragType != EDRAGTYPE.GROUP) Mouseinfo.Move = true; //화면이동으로
                else Mouseinfo.Hand = true;   //잡은형태
            }
            //if (this.FullScreen)
            //{ /* 작성자: 이재웅, 작성일: 2024-12-04, 작성내용: '전체보기' 상태일 때만 그룹헤더의 [Null Balance] 팝업 정보가 표시되도록 변경  */
            //마우스가 현재 그룹헤더에 존재하는지확인 (헤더에 올경우 특정 정보를 표시)
            if (!Mouseinfo.Hand && !Mouseinfo.Move)
            {
                int tpidx = Check_GroupHeader(e, true);
                if (tpidx != -1)
                {
                    Mouseinfo.Hand = true;
                    this.GROUPS[tpidx].Showinfo = true;
                    //this.showHeaderInfo = true;
                }
            }
            //마우스가 현재 그룹에 존재하는지?
            if (!Mouseinfo.Hand && !Mouseinfo.Move)
            {
                int tpidx = Check_Group(e);
                if (tpidx != -1)
                {
                    Mouseinfo.Hand = true;
                }
            }
            //}
            if (Mouseinfo.Hand) this.Cursor = Cursors.Hand;
            if (Mouseinfo.Cross) this.Cursor = Cursors.Cross;
            this.Refresh();
        }
    }       //end class
}   //end namespace