private void plMain_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMovingShape)
            {
                isMovingShape = false;
                selectedShape = null;
            }
            if (isResizingShape)
            {
                isResizingShape = false;
                ReSizeShape     = null;
                selectedShape   = null;
            }
            if (isMouseSelect)
            {
                isMouseSelect = false;
                for (int i = 0; i < lstObject.Count; i++)
                {
                    lstObject[i].IsSelected = false;
                    if (lstObject[i].p1.X >= selectedRegion.X && lstObject[i].p2.X <= selectedRegion.X + selectedRegion.Width && lstObject[i].p1.Y >= selectedRegion.Y && lstObject[i].p2.Y <= selectedRegion.Y + selectedRegion.Height)
                    {
                        lstObject[i].IsSelected = true;
                    }
                }
                for (int i = 0; i < LstCurve.Count; i++)
                {
                    LstCurve[i].IsSelected = false;
                    if (LstCurve[i].p1.X >= selectedRegion.X && LstCurve[i].p2.X <= selectedRegion.X + selectedRegion.Width && LstCurve[i].p1.Y >= selectedRegion.Y && LstCurve[i].p2.Y <= selectedRegion.Y + selectedRegion.Height)
                    {
                        LstCurve[i].IsSelected = true;
                    }
                }
                for (int i = 0; i < Polygons.Count; i++)
                {
                    Polygons[i].IsSelected = false;
                    if (Polygons[i].p1.X >= selectedRegion.X && Polygons[i].p2.X <= selectedRegion.X + selectedRegion.Width && Polygons[i].p1.Y >= selectedRegion.Y && Polygons[i].p2.Y <= selectedRegion.Y + selectedRegion.Height)
                    {
                        Polygons[i].IsSelected = true;
                    }
                }
                for (int i = 0; i < lstGroup.Count; i++)
                {
                    lstGroup[i].IsSelected = false;
                    if (lstGroup[i].p1.X >= selectedRegion.X && lstGroup[i].p2.X <= selectedRegion.X + selectedRegion.Width && lstGroup[i].p1.Y >= selectedRegion.Y && lstGroup[i].p2.Y <= selectedRegion.Y + selectedRegion.Height)
                    {
                        lstGroup[i].IsSelected = true;
                    }
                }

                plMain.Refresh();
            }
            if (bLine == true || bEcllipse == true || bRect == true || bCircle == true || bSquare == true)
            {
                this.lstObject[this.lstObject.Count - 1].p2 = e.Location;
                selectedShape = null;
                this.plMain.Refresh();
                isStartpoly = 0;
            }

            this.bLine     = false;
            this.bEcllipse = false;
            this.bRect     = false;
            this.bCircle   = false;
            this.bSquare   = false;
            this.isPress   = false;
            IsDrawNothing  = true;

            if (bPolygon == true)
            {
                this.Polygons[this.Polygons.Count - 1].PolygonPoints[this.Polygons[this.Polygons.Count - 1].PolygonPoints.Count - 1] = e.Location;
                this.plMain.Refresh();
                IsDrawNothing = false;
            }
            if (bCurve == true)
            {
                this.LstCurve[this.LstCurve.Count - 1].Points[this.LstCurve[this.LstCurve.Count - 1].Points.Count - 1] = e.Location;
                this.plMain.Refresh();
                IsDrawNothing = false;
            }
        }
        private void plMain_MouseDown(object sender, MouseEventArgs e)
        {
            this.isPress       = true;
            this.isStartpoly  += 1;
            this.isStartCurve += 1;
            #region Vẽ Hình

            if (this.bLine == true)
            {
                clsDrawObject myObj;
                myObj                 = new clsLine();
                myObj.myPen           = new Pen(myColor, thick);
                myObj.myPen.DashStyle = Dstyle;
                myObj.Filled          = Fill;
                myObj.p1              = e.Location;
                myObj.myOutLineColor  = myColor;
                myObj.width           = thick;
                myObj.DStyle          = Dstyle;
                this.lstObject.Add(myObj);
            }

            if (this.bCircle == true)
            {
                clsDrawObject myObj;
                myObj                = new clsCircle();
                myObj.Filled         = Fill;
                myObj.myOutLineColor = myColor;
                myObj.width          = thick;
                myObj.myFillColor    = myFillColor;
                myObj.DStyle         = Dstyle;
                myObj.BrushTypes     = Getbrush;
                myObj.p1             = e.Location;

                this.lstObject.Add(myObj);
            }
            if (this.bEcllipse == true)
            {
                clsDrawObject myObj;
                myObj                = new clsEllipse();
                myObj.DStyle         = Dstyle;
                myObj.Filled         = Fill;
                myObj.myOutLineColor = myColor;
                myObj.width          = thick;
                myObj.myFillColor    = myFillColor;
                myObj.BrushTypes     = Getbrush;
                myObj.p1             = e.Location;

                this.lstObject.Add(myObj);
            }
            if (this.bSquare == true)
            {
                clsDrawObject myObj;
                myObj = new clsSquare();

                myObj.myOutLineColor = myColor;
                myObj.width          = thick;
                myObj.myFillColor    = myFillColor;
                myObj.DStyle         = Dstyle;
                myObj.BrushTypes     = Getbrush;
                myObj.Filled         = Fill;
                myObj.p1             = e.Location;
                this.lstObject.Add(myObj);
            }
            if (this.bRect == true)
            {
                clsDrawObject myObj;
                myObj = new clsRectangle();

                myObj.myOutLineColor = myColor;
                myObj.width          = thick;
                myObj.myFillColor    = myFillColor;
                myObj.DStyle         = Dstyle;
                myObj.BrushTypes     = Getbrush;
                myObj.Filled         = Fill;
                myObj.p1             = e.Location;

                this.lstObject.Add(myObj);
            }
            if (this.bPolygon == true)
            {
                if (isStartpoly == 1)
                {
                    clsPolygon mypoly;
                    mypoly = new clsPolygon();

                    mypoly.Filled         = Fill;
                    mypoly.myOutLineColor = myColor;
                    mypoly.width          = thick;
                    mypoly.myFillColor    = myFillColor;
                    mypoly.DStyle         = Dstyle;
                    mypoly.BrushTypes     = Getbrush;
                    mypoly.PolygonPoints.Add(e.Location);

                    this.Polygons.Add(mypoly);
                }
                this.Polygons[this.Polygons.Count - 1].PolygonPoints.Add(e.Location);
            }
            if (this.bCurve == true)
            {
                if (isStartCurve == 1)
                {
                    clsCurve myCurve;
                    myCurve = new clsCurve();

                    myCurve.Filled         = Fill;
                    myCurve.myOutLineColor = myColor;
                    myCurve.width          = thick;
                    myCurve.myFillColor    = myFillColor;
                    myCurve.DStyle         = Dstyle;
                    myCurve.BrushTypes     = Getbrush;

                    myCurve.Points.Add(e.Location);
                    this.LstCurve.Add(myCurve);
                }
                this.LstCurve[this.LstCurve.Count - 1].Points.Add(e.Location);
            }
            #endregion ;

            #region Không vẽ hình
            if (IsDrawNothing == true)
            {
                if (isControlKeyPress == true)
                {
                    for (int i = 0; i < lstObject.Count; i++)
                    {
                        if (lstObject[i].IsHit(e.Location))
                        {
                            lstObject[i].IsSelected = true;
                            plMain.Refresh();
                        }
                    }
                    for (int i = 0; i < Polygons.Count; i++)
                    {
                        if (Polygons[i].IsHit(e.Location) && bPolygon != true)
                        {
                            Polygons[i].IsSelected = true;
                            plMain.Refresh();
                        }
                    }
                    for (int i = 0; i < LstCurve.Count; i++)
                    {
                        if (LstCurve[i].IsHit(e.Location) && bCurve != true)
                        {
                            LstCurve[i].IsSelected = true;
                            plMain.Refresh();
                        }
                    }
                    for (int i = 0; i < lstGroup.Count; i++)
                    {
                        if (lstGroup[i].IsHit(e.Location))
                        {
                            lstGroup[i].IsSelected = true;
                            plMain.Refresh();
                        }
                    }
                }
                else
                {
                    LstCurve.ForEach(shape => shape.IsSelected  = false);
                    lstObject.ForEach(shape => shape.IsSelected = false);
                    Polygons.ForEach(shape => shape.IsSelected  = false);
                    lstGroup.ForEach(shape => shape.IsSelected  = false);
                    plMain.Invalidate();
                    plMain.Refresh();


                    for (int i = 0; i < lstObject.Count; i++)
                    {
                        if (isHitPoint(e.Location, lstObject[i].p2) || isHitPoint(e.Location, lstObject[i].p1) ||
                            isHitPoint(e.Location, lstObject[i].p3) || isHitPoint(e.Location, lstObject[i].p4))
                        {
                            ReSizeShape             = lstObject[i];
                            lstObject[i].IsSelected = true;
                            lstObject[i].IsReSized  = true;
                            plMain.Refresh();
                            break;
                        }
                        if (lstObject[i].IsHit(e.Location))
                        {
                            selectedShape           = lstObject[i];
                            lstObject[i].IsSelected = true;
                            plMain.Refresh();
                            break;
                        }
                    }
                    for (int i = 0; i < Polygons.Count; i++)
                    {
                        FindPolygonRegion(Polygons[i]);
                        if (isHitPoint(e.Location, Polygons[i].p2) || isHitPoint(e.Location, Polygons[i].p1))
                        {
                            if (isHitPoint(e.Location, Polygons[i].p1))
                            {
                                position = 1;
                            }
                            if (isHitPoint(e.Location, Polygons[i].p2))
                            {
                                position = 2;
                            }
                            ReSizeShape            = Polygons[i];
                            Polygons[i].IsSelected = true;
                            Polygons[i].IsReSized  = true;
                            plMain.Refresh();
                            break;
                        }
                        if (Polygons[i].IsHit(e.Location))
                        {
                            selectedShape          = Polygons[i];
                            Polygons[i].IsSelected = true;
                            plMain.Refresh();
                            break;
                        }
                    }
                    for (int i = 0; i < LstCurve.Count; i++)
                    {
                        FindCurveRegion(LstCurve[i]);
                        if (isHitPoint(e.Location, LstCurve[i].p2) || isHitPoint(e.Location, LstCurve[i].p1))
                        {
                            if (isHitPoint(e.Location, LstCurve[i].p1))
                            {
                                position = 1;
                            }
                            if (isHitPoint(e.Location, LstCurve[i].p2))
                            {
                                position = 2;
                            }
                            ReSizeShape            = LstCurve[i];
                            LstCurve[i].IsSelected = true;
                            LstCurve[i].IsReSized  = true;
                            plMain.Refresh();
                            break;
                        }
                        if (LstCurve[i].IsHit(e.Location))
                        {
                            selectedShape          = LstCurve[i];
                            LstCurve[i].IsSelected = true;
                            plMain.Refresh();
                            break;
                        }
                    }
                    for (int i = 0; i < lstGroup.Count; i++)
                    {
                        FindGroupRegion(lstGroup[i]);
                        if (isHitPoint(e.Location, lstGroup[i].p2))
                        {
                            ReSizeShape            = lstGroup[i];
                            lstGroup[i].IsSelected = true;
                            lstGroup[i].IsReSized  = true;
                            plMain.Refresh();
                            break;
                        }
                        if (lstGroup[i].IsHit(e.Location))
                        {
                            selectedShape          = lstGroup[i];
                            lstGroup[i].IsSelected = true;
                            plMain.Refresh();
                            break;
                        }
                    }
                    if (selectedShape != null)
                    {
                        isMovingShape = true;

                        previousPoint = e.Location;
                    }
                    else
                    if (ReSizeShape != null)
                    {
                        isResizingShape = true;
                        previousPoint   = e.Location;
                        if (position == 2)
                        {
                            Polybegin = ReSizeShape.p1;
                            PolyEnd   = ReSizeShape.p2;
                        }
                        if (position == 1)
                        {
                            Polybegin = ReSizeShape.p2;
                            PolyEnd   = ReSizeShape.p1;
                        }
                    }
                    else
                    {
                        isMouseSelect  = true;
                        selectedRegion = new System.Drawing.Rectangle(e.Location, new Size(0, 0));
                    }
                }
            }
            #endregion
        }
        private void plMain_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMovingShape == true)
            {
                Point d = new Point(e.X - previousPoint.X, e.Y - previousPoint.Y);
                selectedShape.Move(d);
                previousPoint = e.Location;
                plMain.Invalidate();
            }
            if (isResizingShape == true)
            {
                if (ReSizeShape is clsPolygon polygon)
                {
                    if (position == 1)
                    {
                        PointF P = ReSizeShape.p1;
                        ReSizeShape.p1 = ReSizeShape.p2;
                        ReSizeShape.p2 = P;
                    }
                    PointF d = new PointF(e.X - previousPoint.X, e.Y - previousPoint.Y);
                    polygon.Resize(d, Polybegin, PolyEnd);
                    //FindPolygonRegion(polygon);
                    PolyEnd       = polygon.p2;
                    previousPoint = e.Location;
                    plMain.Invalidate();
                }
                else if (ReSizeShape is Group group)
                {
                    PointF d = new PointF(e.X - previousPoint.X, e.Y - previousPoint.Y);
                    group.Resize(d, Polybegin, PolyEnd);
                    FindGroupRegion(group);
                    PolyEnd       = group.p2;
                    previousPoint = e.Location;
                    plMain.Invalidate();
                }
                else if (ReSizeShape is clsCurve curve)
                {
                    if (position == 1)
                    {
                        PointF P = ReSizeShape.p1;
                        ReSizeShape.p1 = ReSizeShape.p2;
                        ReSizeShape.p2 = P;
                    }
                    PointF d = new PointF(e.X - previousPoint.X, e.Y - previousPoint.Y);
                    curve.Resize(d, Polybegin, PolyEnd);
                    // FindCurveRegion(curve);
                    PolyEnd       = curve.p2;
                    previousPoint = e.Location;
                    plMain.Invalidate();
                }
                else
                {
                    if (isHitPoint(e.Location, ReSizeShape.p1))
                    {
                        ReSizeShape.p1 = ReSizeShape.p2;
                    }
                    if (isHitPoint(e.Location, ReSizeShape.p3))
                    {
                        ReSizeShape.p1 = ReSizeShape.p4;
                    }
                    if (isHitPoint(e.Location, ReSizeShape.p4))
                    {
                        ReSizeShape.p1 = ReSizeShape.p3;
                    }

                    ReSizeShape.Resize(e.Location);
                }

                plMain.Refresh();
            }
            if (IsDrawNothing == true)
            {
                if (isMouseSelect)
                {
                    selectedRegion.Width  = e.Location.X - selectedRegion.X;
                    selectedRegion.Height = e.Location.Y - selectedRegion.Y;

                    plMain.Refresh();
                }
                else
                {
                    plMain.Cursor = Cursors.Default;
                    foreach (clsDrawObject shape in lstObject)
                    {
                        if (isHitPoint(e.Location, shape.p2) || isHitPoint(e.Location, shape.p1) ||
                            isHitPoint(e.Location, shape.p3) || isHitPoint(e.Location, shape.p4))
                        {
                            plMain.Cursor = Cursors.Hand;
                        }
                        if (shape.IsHit(e.Location))
                        {
                            plMain.Cursor = Cursors.SizeAll;
                        }
                    }
                    foreach (clsPolygon shape in Polygons)
                    {
                        FindPolygonRegion(shape);
                        if (isHitPoint(e.Location, shape.p2) || isHitPoint(e.Location, shape.p1))
                        {
                            plMain.Cursor = Cursors.Hand;
                        }
                        if (shape.IsHit(e.Location))
                        {
                            plMain.Cursor = Cursors.SizeAll;
                        }
                    }
                    foreach (Group shape in lstGroup)
                    {
                        FindGroupRegion(shape);
                        if (isHitPoint(e.Location, shape.p2))
                        {
                            plMain.Cursor = Cursors.Hand;
                        }
                        if (shape.IsHit(e.Location))
                        {
                            plMain.Cursor = Cursors.SizeAll;
                        }
                    }
                    foreach (clsCurve shape in LstCurve)
                    {
                        FindCurveRegion(shape);
                        if (isHitPoint(e.Location, shape.p2) || isHitPoint(e.Location, shape.p1))
                        {
                            plMain.Cursor = Cursors.Hand;
                        }
                        if (shape.IsHit(e.Location))
                        {
                            plMain.Cursor = Cursors.SizeAll;
                        }
                    }
                    if (Polygons.Exists(shape => shape.IsHit(e.Location)) || LstCurve.Exists(shape => shape.IsHit(e.Location)) || lstGroup.Exists(shape => shape.IsHit(e.Location)))
                    {
                        plMain.Cursor = Cursors.SizeAll;
                    }
                }
            }
            if (this.isPress == true)
            {
                if (bLine == true || bEcllipse == true || bRect == true || bSquare == true)
                {
                    this.lstObject[this.lstObject.Count - 1].p2 = e.Location;

                    this.plMain.Refresh();
                }
                if (bCircle == true)
                {
                    if (this.lstObject[this.lstObject.Count - 1] is clsCircle)
                    {
                        this.lstObject[this.lstObject.Count - 1].p2 = e.Location;
                        clsDrawObject X = this.lstObject[this.lstObject.Count - 1];

                        plMain.Refresh();
                    }
                }
                if (isStartpoly > 1)
                {
                    if (bPolygon == true)
                    {
                        this.Polygons[this.Polygons.Count - 1].PolygonPoints[this.Polygons[this.Polygons.Count - 1].PolygonPoints.Count - 1] = e.Location;
                        this.plMain.Refresh();
                    }
                }
                if (isStartCurve > 1)
                {
                    if (bCurve == true)
                    {
                        this.LstCurve[this.LstCurve.Count - 1].Points[this.LstCurve[this.LstCurve.Count - 1].Points.Count - 1] = e.Location;
                        this.plMain.Refresh();
                    }
                }
            }
        }
        /// <summary>
        /// Tìm cái khung chứa group này
        /// </summary>
        private void FindGroupRegion(Group group)
        {
            float minX = float.MaxValue, minY = float.MaxValue, maxX = float.MinValue, maxY = float.MinValue;

            for (int i = 0; i < group.Count; i++)
            {
                clsDrawObject shape = group[i];

                if (shape is clsCurve curve)
                {
                    FindCurveRegion(curve);
                }
                else if (shape is clsPolygon polygon)
                {
                    FindPolygonRegion(polygon);
                }
                else if (shape is Group group1)
                {
                    FindGroupRegion(group1);
                }

                if (shape.p1.X < minX)
                {
                    minX = shape.p1.X;
                }
                if (shape.p2.X < minX)
                {
                    minX = shape.p2.X;
                }

                if (shape.p1.Y < minY)
                {
                    minY = shape.p1.Y;
                }
                if (shape.p2.Y < minY)
                {
                    minY = shape.p2.Y;
                }

                if (shape.p1.X > maxX)
                {
                    maxX = shape.p1.X;
                }
                if (shape.p2.X > maxX)
                {
                    maxX = shape.p2.X;
                }

                if (shape.p1.Y > maxY)
                {
                    maxY = shape.p1.Y;
                }
                if (shape.p2.Y > maxY)
                {
                    maxY = shape.p2.Y;
                }
            }
            group.p1 = new PointF(minX - 5, minY - 5);
            group.p2 = new PointF(maxX + 5, maxY + 5);
            group.p3 = new PointF(group.p1.X, group.p2.Y);
            group.p4 = new PointF(group.p2.X, group.p1.Y);
        }