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

////namespace motion {
public partial class PaintForm : Form {
    public PaintForm() {
        InitializeComponent();
        //
        //HistoryList = new HistorySet();
        //HistoryList.Add(SLines = new SList());
        //HistoryList.Add(new SList());
    }
    //bool recDraw = false;
    bool LoadedForm = false;
    public bool DrawGreenBox = false;
    #region "Color Management"
    int colorNum = 0;
    //static Pen[] ColoredPens = { Pens.Gray, Pens.Red, Pens.Orange, Pens.Yellow, Pens.Green, Pens.Blue, Pens.Indigo, Pens.Violet };
    //static Pen[] ColoredPens = { Pens.Gray, Pens.Firebrick, Pens.DarkOrange, Pens.LightYellow, Pens.Green, Pens.MediumBlue, Pens.Thistle, Pens.Violet };
    static Pen[] ColoredPens = { Pens.Gray, Pens.Red, Pens.DarkOrange, Pens.Yellow, Pens.Green, Pens.MediumBlue, Pens.Purple, Pens.Violet, Pens.LawnGreen };

    private Pen GetColorPen() {
        //return ColoredPens[colorNum++ % ColoredPens.Length];
        return ColoredPens[colorNum % ColoredPens.Length]; //return single color for each line set. colorNum++ in load XML code
    }

    ////public void ResetColor() {
    ////    colorNum = 0;
    ////    TerminateLine();
    ////    UpdateMainColor();
    ////}

    // This should be redone use an event

    public delegate void dlgUpdateColorHandler(PaintForm sender, string CName);
    //public event dlgUpdateColorHandler UpdateColorEvent;

    ////public void UpdateMainColor() {
    ////    // Report current color to the main form
    ////    var curPen = ColoredPens[colorNum % ColoredPens.Length];        // This is the current color, so no incrementa
    ////    if (myCurrentLine != null)                                      // We have a line so use that one instead
    ////        curPen = myCurrentLine.pen;
    ////    var cName = curPen.Color.ToArgb().ToString("X");
    ////    if (curPen.Color.IsNamedColor)
    ////        cName = curPen.Color.Name;
    ////    if (UpdateColorEvent != null)
    ////        UpdateColorEvent(this, cName);
    ////}

    #endregion

    #region "Line Management"
    ////bool myShouldPaint = true;
    ////bool ShouldPaint {
    ////    get {
    ////        return myShouldPaint;
    ////    }
    ////    set {
    ////        if (value == myShouldPaint)
    ////            return; // No change
    ////        myShouldPaint = value;
    ////        if (!ShouldPaint) // Toggled on
    ////            TerminateLine();
    ////        paintToolStripMenuItem.Checked = myShouldPaint;
    ////    }
    ////}
    ////private void TerminateLine() {
    ////    myCurrentLine = null;

    ////}

    ////private void EyesOpenTerminate() {
    ////    if (MainForm.mForm.openEyes) {
    ////        Saver();
    ////        ClearPath(true);
    ////    }
    ////}

    ////private void TerminateIfTimeout() {
    ////    if (MainForm.mForm.timeOutPaint) {
    ////        if (DateTime.Now.Subtract(LasttTime).TotalSeconds > 1) {
    ////            EyesOpenTerminate();
    ////            TerminateLine();
    ////            UpdateMainColor();

    ////        }
    ////    }
    ////}

    ////private void EyesOpenTimer_Tick(object sender, EventArgs e) {
    ////    //Run TermiinateifTimeout every second to clear lines.            
    ////    TerminateIfTimeout();
    ////}

    public class SPoint {
        public DateTime Stamp = DateTime.Now;
        public Point Pos;
        public int X { get { return Pos.X; } }
        public int Y { get { return Pos.Y; } }

        public static implicit operator Point(SPoint sp) {
            return sp.Pos;
        }

        public static implicit operator SPoint(Point pt) {
            return new SPoint() { Pos = pt };
        }
    }

    public class SLine : List<SPoint> {
        private PaintForm pf;
        public Pen pen;
        public SLine(PaintForm pf) {
            this.pf = pf;
            //pen = ColoredPens[pf.colorNum++ % ColoredPens.Length];
            pen = pf.GetColorPen();
            //pf.UpdateMainColor();
        }

        public Point[] Points { get { return this.ConvertAll(sp => sp.Pos).ToArray(); } }
    }

    ////private SLine myCurrentLine;
    ////private SLine CurrentLine {
    ////    get {
    ////        if (myCurrentLine == null) {
    ////            myCurrentLine = new SLine(this);
    ////            SLines.Add(myCurrentLine);
    ////        }
    ////        return myCurrentLine;
    ////    }
    ////}
    //private SList SLines; // = new SList();
    //private List<SList> HistoryList;// = new List<SList>(SLines = new SList());

    //private SList SLines {  // Return the last entry added
    //    get {
    //        return HistoryList[HistoryList.Count - 1];
    //    }
    //}

    //private HistorySet HistoryList;
    private class HistorySet : List<SList> {
        //public string TrialName ( get ; set; }
        public string TrialName = null;

        public Rectangle Bounds {   // Compute each time -- later we can be smarter
            get {
                var left = int.MaxValue;
                var top = int.MaxValue;
                var right = 0;
                var bottom = 0;
                foreach (var SLines in this) {
                    foreach (var SList in SLines.Where(s => s.Count > 0)) {
                        foreach (var SPoint in SList) {
                            left = Math.Min(left, SPoint.X);
                            top = Math.Min(top, SPoint.Y);
                            right = Math.Max(right, SPoint.X);
                            bottom = Math.Max(bottom, SPoint.Y);
                        }
                        //left = SList.Min(p => p.X);
                        //top = SList.Min(p => p.Y);
                        //left = SList.Max(p => p.X);
                        //top = SList.Max(p => p.Y);
                    }
                }
                return new Rectangle(left, top, right - left, bottom - top);
            }
        }
    }

    private class LoadSet : List<HistorySet> {

    }
    private LoadSet LoadSets = new LoadSet();

    private class SList : List<SLine> {
        public Pen pen { get { return Pens.Blue; } }
        public List<SLine> Points { get { return this; } }

    }

    //private DateTime LastPointTime;
    #endregion

    //private void PaintForm_KeyDown(object sender, KeyEventArgs e) {
    //    //Z to hide cursor 
    //    if (e.KeyCode == Keys.Z) {
    //        Cursor.Hide();
    //    }

    //    //X to show cursor
    //    if (e.KeyCode == Keys.X) {
    //        Cursor.Show();
    //    }

    //    //Q for making border style none
    //    if (e.KeyCode == Keys.Q) {
    //        this.FormBorderStyle = FormBorderStyle.None;
    //    }

    //    //P for pause, stops painting.
    //    if (e.KeyCode == Keys.P) {
    //        //ShouldPaint = false;
    //    } else if (e.KeyCode == Keys.S) {//S for starts painting and initializes a new list of points.
    //        //ShouldPaint = true;
    //        // BoundPainter();
    //    }
    //    if (e.KeyCode == Keys.C) {
    //        ////C for clear points
    //        //Saver();
    //        ////mySavePath = null;
    //        //ShouldPaint = false;
    //        ////Add cleared points to XML file. 
    //        ////SLines.Clear();
    //        ////Invalidate();
    //        //ClearPath(false);

    //    }
    //    if (e.KeyCode == Keys.R) {
    //        recDraw = true;
    //    }

    //    if (e.KeyCode == Keys.D1) { //#1 For First LaserPractice
    //        LaserPractice1();
    //    }

    //    if (e.KeyCode == Keys.D2) {  //#2 For First LaserPractice
    //        LaserPractice2();
    //    }

    //    if (e.KeyCode == Keys.D3) { // Supposed to invalidate just LaserPractice
    //        ClearSurface();
    //    }
    //    if (e.KeyCode == Keys.NumPad1) { //center fixation point
    //        CenterFixation();
    //    }

    //    if (e.KeyCode == Keys.NumPad2) { //center fixation point
    //        LowerFixation();
    //    }

    //    if (e.KeyCode == Keys.NumPad3) { //center fixation point
    //        RsideFixation();
    //    }
    //}

    //private void PaintForm_KeyUp(object sender, KeyEventArgs e) {
    //    if (e.KeyCode == Keys.R) {
    //        recDraw = false;
    //    }
    //}

    public Color[] TransBrush = { Color.Red, Color.Green, Color.Blue };


    private void PaintForm_Paint(object sender, PaintEventArgs e) {
        try {
            ////if (MainForm.mForm.ifVisField == true) {
            ////    LoadedForm = true;
            ////}

            if (LoadedForm)
                GridPaint(e.Graphics);
            ////MainForm.mForm.ifVisField = false;


            //foreach (var ThisLine in SLines)
            //    e.Graphics.DrawCurve(ThisLine.pen, ThisLine.Points); //  pp.ToArray());
            int i = 0;
            var g = e.Graphics;

            int LineCount = 0; //For incremental painting


            foreach (var LoadSet in LoadSets) {
                if (DrawGreenBox) {
                    using (var gpPen = new Pen(Color.LimeGreen, 5)) {
                        var TB = TransBrush[i++ % TransBrush.Length];
                        using (var Tbrush = new SolidBrush(Color.FromArgb(32, TB))) {
                            var bounds = LoadSet.Bounds;
                            g.FillRectangle(Tbrush, bounds); //fill rectangle red around line set.
                            g.DrawRectangle(gpPen, bounds); //Draw Green Rectangle around line set
                            g.DrawString(LoadSet.TrialName, this.Font, Brushes.White, bounds.Location);//Draw full name of line set

                        }
                    }
                }
                int j = 0;
                foreach (var HistoryList in LoadSet) {

                    foreach (var ThisLine in HistoryList) { // .Skip(LoadedForm ? 0 : HistoryList.Count - 1)) {
                        var points = ThisLine.Points;
                        if (points.Length == 0) continue;
                        //ShouldClick();
                        var size = 4;
                        j++;
                        var first = points[0];
                        //g.DrawRectangle(Pens.Green, first.X - size / 2, first.Y - size / 2, size, size); // Draw the first green square at begining of line
                        //g.DrawString(j.ToString(), this.Font, Brushes.White, first.X - size + 2, first.Y - size + 2);//Draw each line number
                        var last = points[points.Length - 1];
                        //g.DrawRectangle(Pens.Red, last.X - size / 2, last.Y - size / 2, size, size);// Draw end RED square for each line
                        g.DrawCurve(ThisLine.pen, points); //  pp.ToArray());

                        if (StepThrough()) {
                            if (++LineCount > IncrementalPosition)
                                goto Painted; // We've gone far enough so break out of both loops
                        }

                    }
                }
            }
        Painted:
            g.DrawImageUnscaled(Surface, new Point(0, 0)); //Draw cashed surface.
        }
        catch (Exception ex) {
            Debug.WriteLine(ex.Message);
        }
    }
    public delegate bool dlgPaintIncrementally();
    public dlgPaintIncrementally PaintIncrementally;
    public bool StepThrough() {
        return PaintIncrementally == null ? false : PaintIncrementally();
    }

    private int IncrementalPosition = 0;
    private void PaintForm_KeyDown(object sender, KeyEventArgs e) {
        // Increment incremental position
        if (e.KeyCode == Keys.Down) {
            IncrementalPosition++;
            this.Invalidate();
            e.Handled = true;
        }
    }

    ////internal void MotionPosition(Point pos) { // Invoked from MotionDetector
    ////    if (this.InvokeRequired) {
    ////        this.Invoke(new MethodInvoker(delegate { MotionPosition(pos); }));
    ////        return;
    ////    }

    ////    //TerminateIfTimeout();
    ////    EyesOpenTimer.Enabled = true;
    ////    PaintPoint(pos);
    ////    if (!MainForm.mForm.timeOutPaint) colorNum = 0;
    ////}

    //private void PaintPoint(Point pos) {
    //    //if (!ShouldPaint)
    //    //    return;
    //    pos.X = pos.X;//compensate for laser and path offset.
    //    pos.Y = pos.Y;//compensate for laser and path offset
    //    LastPointTime = DateTime.Now;
    //    CurrentLine.Add(pos);
    //    //this.Invalidate();
    //    //Paints only two sets of points at a time to produce smooth painting.
    //    if (CurrentLine.Count > 1) {
    //        using (var g = this.CreateGraphics())
    //            g.DrawCurve(CurrentLine.pen, new Point[] { CurrentLine[CurrentLine.Count - 1], CurrentLine[CurrentLine.Count - 2] });
    //    }
    //}

    public Rectangle SelectionRectangle = new Rectangle();
    public Point StartPoint = new Point();
    public Point EndPoint = new Point();

    //MouseDown, inits Rectangle and sets Cature to ture. 
    private void PaintForm_MouseDown(object sender, MouseEventArgs e) {
        if ((e.Button & MouseButtons.Right) != 0) {//&& recDraw) {
            SelectionRectangle.Width = 0;
            SelectionRectangle.Height = 0;
            SelectionRectangle.X = e.X;
            SelectionRectangle.Y = e.Y;

            StartPoint.X = e.X;
            StartPoint.Y = e.Y;
            EndPoint = StartPoint;

        }
        if ((e.Button & MouseButtons.Left) != 0) {
            this.Capture = true;
        }
    }
    ////MouseMove, moves rectangle
    //private void PaintForm_MouseMove(object sender, MouseEventArgs e) {
    //    if ((e.Button & MouseButtons.Right) != 0 && recDraw) {
    //        ControlPaint.DrawReversibleFrame(this.RectangleToScreen(SelectionRectangle),
    //                   Color.Red, FrameStyle.Dashed);
    //        SelectionRectangle.Width = e.X - SelectionRectangle.X;
    //        SelectionRectangle.Height = e.Y - SelectionRectangle.Y;
    //        //ControlPaint.DrawReversibleFrame(this.RectangleToScreen(SelectionRectangle),
    //        //    Color.Yellow, FrameStyle.Dashed);
    //    }
    //    if (!this.Capture)
    //        return;
    //    //PaintPoint(new Point(e.X, e.Y));
    //}

    //MouseUp, Draws the bound rectangle 
    private void PaintForm_MouseUp(object sender, MouseEventArgs e) {
        Graphics g = this.CreateGraphics();
        Pen pen = new Pen(Color.Purple, 4);
        // ControlPaint.DrawReversibleFrame(this.RectangleToScreen(SelectionRectangle), Color.Orange, FrameStyle.Dashed);
        g.DrawRectangle(pen, SelectionRectangle);
        this.Focus();
        //recDraw = false;

        if ((e.Button & MouseButtons.Left) != 0)
            this.Capture = false;
    }
    //Save list of points to XML file on desktop.

    //private static object PFLock = new object();
    //public void Saver() {
    //    try {
    //        //lock (PFLock) {
    //        var xd = new XDocument();
    //        var xt = new XElement("AllPath");
    //        //xd.Add(xt);
    //        //foreach (var SLines in HistoryList) {
    //        //    var xps = new XElement("SLines");
    //        xd.Add(xt);
    //        foreach (var SLines in HistoryList) {
    //            var xps = new XElement("SLines");
    //            xt.Add(xps);
    //            foreach (var path in SLines) {
    //                var xp = new XElement("path", new XAttribute("pen", path.pen.Color.ToArgb().ToString("X"))); // X is hex
    //                xps.Add(xp);
    //                foreach (var point in path)
    //                    xp.Add(new XElement("Point",
    //                        new XAttribute("X", point.X),
    //                        new XAttribute("Y", point.Y),
    //                        new XAttribute("T", point.Stamp.ToString())));
    //            }
    //        }
    //        if (!Directory.Exists(LaserPath_Dir))
    //            Directory.CreateDirectory(LaserPath_Dir);

    //        //var SavePath = Path.Combine(LaserPath_Dir,
    //        //    DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + MainForm.mForm.SuffixInitials + MainForm.mForm.SuffixIntensity + MainForm.mForm.SuffixHemi + "_Paths.xml");

    //        //xd.Save(SavePath + ((new Random().Next(1000)).ToString()));
    //        try {
    //            xd.Save(SavePath);
    //        } catch {
    //            Debug.WriteLine("Savepath failed, will try again");
    //            Thread.Sleep(500);
    //            xd.Save(SavePath);
    //        }
    //        //    }
    //    } catch (Exception ex) {
    //        Debugger.Break();
    //        MessageBox.Show("Saving " + ex.ToString());
    //    }
    //}

    //public void ClearPath(bool eyes) {
    //    if (eyes)
    //        //HistoryList.Add(SLines = new SList());
    //        HistoryList.Add(new SList());
    //    else
    //        SLines.Clear();
    //    ClearSurface();
    //    Invalidate();
    //    // mySavePath = null; //when eyes is not true a new save path is created. 
    //}

    ////public void ClearMyPath() {
    ////    mySavePath = null;
    ////    MainForm.mForm.clearText = true;
    ////}


    string LaserPath_Dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "L-TaP");

    private string mySavePath = null;
    private string SavePath {
        get {
            ////    if (mySavePath == null) {
            ////        if (!Directory.Exists(LaserPath_Dir))
            ////            Directory.CreateDirectory(LaserPath_Dir);
            ////        mySavePath = Path.Combine(LaserPath_Dir,
            ////            DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + MainForm.mForm.SuffixInitials + MainForm.mForm.SuffixIntensity + MainForm.mForm.SuffixHemi + "_Paths.xml");
            ////    }
            return mySavePath;
        }
    }


    //Load saved points.
    public void Loader(string LoadLaserPath) {
        //ShouldPaint = false;
        try {
            LoadedForm = true;
            var xd = XDocument.Load(LoadLaserPath);
            var AllPath = xd.Element("AllPath");
            //HistoryList.Clear();
            var HistoryList = new HistorySet() { TrialName = Path.GetFileNameWithoutExtension(LoadLaserPath) };
            colorNum++;
            LoadSets.Add(HistoryList);

            foreach (var ps in AllPath.Elements("SLines")) {
                //HistoryList.Add(SLines = new SList());
                var SLines = new SList();
                HistoryList.Add(SLines);
                foreach (var path in ps.Elements("path")) {
                    var points = new SLine(this);
                    //var ca = path.Attribute("pen");
                    //if (ca != null)
                    //    points.pen = new Pen(Color.FromArgb(int.Parse(ca.Value, System.Globalization.NumberStyles.AllowHexSpecifier)));
                    //DO same color for each line set
                    points.pen = GetColorPen();
                    SLines.Add(points);

                    var ss = SystemInformation.PrimaryMonitorSize;
                    //int Xval = (int)(ss.Width / 1600);
                    //int Yval = (int)(ss.Height / 1200);

                    double Xval = (ss.Width / 1600.00); //inorder to convert to the size of the projection screen used to capture laser points. (1600x1200)

                    double Yval = (ss.Height / 1200.00);//inorder to convert to the size of the projection screen used to capture laser points. (1600x1200)

                    foreach (var point in path.Elements("Point")) {
                        //var sp = new SPoint() {
                        //Pos = new Point(int.Parse(point.Attribute("X").Value), int.Parse(point.Attribute("Y").Value)),
                        var xdbl = double.Parse(point.Attribute("X").Value) * Xval;
                        var x = System.Convert.ToInt32(xdbl);
                        var ydbl = double.Parse(point.Attribute("Y").Value) * Yval;
                        var y = System.Convert.ToInt32(ydbl);
                        var Pos = new Point(x, y);
                        var sp = new SPoint() {
                            Pos = Pos,
                            Stamp = DateTime.Parse(point.Attribute("T").Value)
                            //Stamp = DateTime.Parse(point.Attribute("T").Value)
                        };
                        points.Add(sp);
                    }
                }
            }
            this.Invalidate();
        }
        catch (Exception ex) {
            MessageBox.Show(ex.ToString());
            Debugger.Break();
            throw;
        }
    }

    //private void savePathToolStripMenuItem_Click(object sender, EventArgs e) {
    //    Saver();
    //}

    //private void paintToolStripMenuItem_Click(object sender, EventArgs e) {
    //    var ptsm = sender as ToolStripMenuItem;
    //    myShouldPaint = ptsm.Checked; // Assume we get this after the check checked
    //}
    Point ctrPoint { get { return new Point(ClientRectangle.Width / 2, ClientRectangle.Height / 2); } }
    int Xstep = 0;//15;
    int StepStep = 15;
    int Diam = 30;

    private void Form1_KeyPress(object sender, KeyPressEventArgs e) { //Use to invalidate and move the two red dots further,
        // into the perhiphrial
        if (e.KeyChar == ' ') {
            // Xstep = 15;
            Xstep += StepStep;
            this.Invalidate(new Rectangle(ctrPoint.X - Xstep - Diam / 2, ctrPoint.Y - Diam / 2, Diam * 2, Diam));
            this.Invalidate(new Rectangle(ctrPoint.X + Xstep - Diam / 2 - Diam, ctrPoint.Y - Diam / 2, Diam * 2, Diam));
        }
    }
    private void GridPaint(Graphics g) {
        int xPoint = 50;
        int yPoint = 50;
        int circlePoint = 100;
        for (var doublePoint = circlePoint; doublePoint <= ClientSize.Width; doublePoint += circlePoint) {
            g.DrawEllipse(Pens.DimGray, ctrPoint.X - xPoint, ctrPoint.Y - yPoint, doublePoint, doublePoint);
            xPoint += 50;
            yPoint += 50;
        }
        var sb = Brushes.Red;
        //g.FillEllipse(sb, ctrPoint.X - 15, ctrPoint.Y - 15, Diam, Diam);//bulls eye

        //var step = 25;
        var step = 50; //~ 50 PPI using the projector screen at 1600x1200 (should actually be 40 but lets not be picky)
        var yxNum = 5;// start at 5degrees = 50pixels = 1inch
        using (var linePen = new Pen(Color.DimGray, 3)) {
            var xFont = new Font("Times", 8);
            //var xNum = 1;
            for (var HVpoints = step; HVpoints <= ClientSize.Width - step; HVpoints += step) {
                var xNum = HVpoints / step;
                //g.DrawLine(Pens.Gray, (ctrPoint.X - 5), HVpoints, (ctrPoint.X + 5), HVpoints); //vertical ticks
                //g.DrawLine(Pens.Gray, HVpoints, (ctrPoint.Y - 5), HVpoints, (ctrPoint.Y + 5)); //Horizontal ticks
                //var xxNum = xNum - ClientSize.Height / 2 / step;
                // g.DrawString(xxNum.ToString(), xFont, Brushes.Blue, ctrPoint.X, HVpoints); //vertical numbers
                if (HVpoints >= ClientSize.Width / 2 + step) {
                    //var yxNum = xNum - ClientSize.Width / 2 / step;

                    g.DrawString(yxNum.ToString(), xFont, Brushes.Red, HVpoints, ctrPoint.Y); //Horizontal numbers //
                    yxNum = yxNum + 5;
                    //xNum++;
                }
            }

            g.DrawLine(linePen, 0, ctrPoint.Y, ClientSize.Width, ctrPoint.Y); //Horizontal line
            g.DrawLine(linePen, ctrPoint.X, ClientSize.Height, ctrPoint.X, 0); //Vertical line

            //g.DrawLine(linePen, 0, 0, ClientSize.Width, ClientSize.Height); //left to right diaginal line
            //g.DrawLine(linePen, ClientSize.Width, 0, 0, ClientSize.Height); //right to left diaginal line

            //g.FillEllipse(Brushes.Red, ctrPoint.X - Xstep - Diam / 2, ctrPoint.Y - Diam / 2, Diam, Diam); //Left Visual Field
            //g.FillEllipse(Brushes.Red, ctrPoint.X + Xstep - Diam / 2, ctrPoint.Y - Diam / 2, Diam, Diam); //Right Visual Field
        }
    }

    private Image Surface;
    private void PaintSurface() {
        using (var g = CreateGraphics())
            g.DrawImageUnscaled(Surface, new Point(0, 0));  // So we don't need to invalidate all
        // Warning -- this only accumulates -- you can't undraw this way
    }

    private void ClearSurface() {
        CreateSurface();
        Invalidate();
    }

    private void CreateSurface() {
        if (Surface != null)
            Surface.Dispose();
        var sc = Screen.FromHandle(this.Handle);
        Surface = new Bitmap(sc.Bounds.Width, sc.Bounds.Height);
    }

    private void LaserPractice1() {
        var PracDotUpCent = new Rectangle(ClientSize.Width / 2 - 15, 100, 30, 30);
        var PractDotUpL = new Rectangle(ClientSize.Width / 6 - 15, 300, 30, 30);
        var PractDotUpR = new Rectangle((ClientSize.Width - (ClientSize.Width / 6) - 15), 300, 30, 30);
        var PractDotLowL = new Rectangle(ClientSize.Width / 6 - 15, ClientSize.Height - 300, 30, 30);
        var PractDotLowR = new Rectangle((ClientSize.Width - (ClientSize.Width / 6) - 15), ClientSize.Height - 300, 30, 30);
        var PractDotLowCent = new Rectangle(ClientSize.Width / 2 - 15, ClientSize.Height - 100, 30, 30);
        var Br = Brushes.Maroon;//Red
        using (var g = Graphics.FromImage(Surface)) {
            g.FillEllipse(Br, PracDotUpCent);
            g.FillEllipse(Br, PractDotUpL);
            g.FillEllipse(Br, PractDotUpR);
            g.FillEllipse(Br, PractDotLowL);
            g.FillEllipse(Br, PractDotLowR);
            g.FillEllipse(Br, PractDotLowCent);
        }
        PaintSurface();
    }

    private void LaserPractice2() {
        var PracDotUpCent = new Rectangle(ClientSize.Width / 2 - 15, 100, 30, 30);
        var PractDotUpL = new Rectangle(ClientSize.Width / 6 - 15, 300, 30, 30);
        var PractDotUpR = new Rectangle((ClientSize.Width - (ClientSize.Width / 6) - 15), 300, 30, 30);
        var PractDotLowL = new Rectangle(ClientSize.Width / 6 - 15, ClientSize.Height - 300, 30, 30);
        var PractDotLowR = new Rectangle((ClientSize.Width - (ClientSize.Width / 6) - 15), ClientSize.Height - 300, 30, 30);
        var PractDotLowCent = new Rectangle(ClientSize.Width / 2 - 15, ClientSize.Height - 100, 30, 30);
        var PractDotUpMidL = new Rectangle(((ClientSize.Width / 2 - 15) - (200)), (ClientSize.Height / 2) - ClientSize.Height / 8, 30, 30);
        var PractDotLowMidL = new Rectangle(((ClientSize.Width / 2 - 15) - (200)), (ClientSize.Height / 2) + ClientSize.Height / 8, 30, 30);
        var PractDotUpMidR = new Rectangle(((ClientSize.Width / 2 - 15) + (200)), (ClientSize.Height / 2) - ClientSize.Height / 8, 30, 30);
        var PractDotLowMidR = new Rectangle(((ClientSize.Width / 2 - 15) + (200)), (ClientSize.Height / 2) + ClientSize.Height / 8, 30, 30);

        var Br = Brushes.Navy;//Blue
        using (var g = Graphics.FromImage(Surface)) {
            g.FillEllipse(Br, PracDotUpCent);
            g.FillEllipse(Br, PractDotUpL);
            g.FillEllipse(Br, PractDotUpR);
            g.FillEllipse(Br, PractDotLowL);
            g.FillEllipse(Br, PractDotLowR);
            g.FillEllipse(Br, PractDotLowCent);
            g.FillEllipse(Br, PractDotUpMidL);
            g.FillEllipse(Br, PractDotLowMidL);
            g.FillEllipse(Br, PractDotUpMidR);
            g.FillEllipse(Br, PractDotLowMidR);
        }
        PaintSurface();
    }

    private void CenterFixation() {
        var Pn = Pens.DimGray;
        using (var g = Graphics.FromImage(Surface)) {
            g.DrawLine(Pn, ClientRectangle.Width / 2 - 10, ClientRectangle.Height / 2, ClientRectangle.Width / 2 + 10, ClientRectangle.Height / 2);
            g.DrawLine(Pn, ClientRectangle.Width / 2, ClientRectangle.Height / 2 - 10, ClientRectangle.Width / 2, ClientRectangle.Height / 2 + 10);
        }
        PaintSurface();
    }

    private void LowerFixation() {
        var Pn = Pens.DimGray;
        using (var g = Graphics.FromImage(Surface)) {
            g.DrawLine(Pn, ClientRectangle.Width / 2 - 10, ClientRectangle.Height / 2 + (ClientRectangle.Height / 4), ClientRectangle.Width / 2 + 10, ClientRectangle.Height / 2 + ClientRectangle.Height / 4);  //ClientRectangle.Width / 2 - 10, ClientRectangle.Height / 2 + (ClientRectangle.Height/4), ClientRectangle.Width / 2 + 10, ClientRectangle.Height / 2 + (ClientRectangle.Height/4));
            g.DrawLine(Pn, ClientRectangle.Width / 2, ClientRectangle.Height / 2 + (ClientRectangle.Height / 4) + 10, ClientRectangle.Width / 2, ClientRectangle.Height / 2 + (ClientRectangle.Height / 4) - 10);
        }
        PaintSurface();
    }

    private void RsideFixation() {
        var Pn = Pens.DimGray;
        using (var g = Graphics.FromImage(Surface)) {
            g.DrawLine(Pn, ClientRectangle.Width / 2 + (ClientRectangle.Width / 4) - 10, ClientRectangle.Height / 2, ClientRectangle.Width / 2 + (ClientRectangle.Width / 4) + 10, ClientRectangle.Height / 2);
            g.DrawLine(Pn, ClientRectangle.Width / 2 + (ClientRectangle.Width / 4), ClientRectangle.Height / 2 - 10, ClientRectangle.Width / 2 + (ClientRectangle.Width / 4), ClientRectangle.Height / 2 + 10);
        }
        PaintSurface();
    }

    private void PaintForm_Load(object sender, EventArgs e) {
        // Create maximal surface (this may not be valid if we move to another screen
        CreateSurface();
        //ResetColor();
    }

    private void PaintForm_SizeChanged(object sender, EventArgs e) {
        this.Invalidate();
    }

    private void PaintForm_FormClosed(object sender, FormClosedEventArgs e) {
        Debug.WriteLine("Form closed");
    }



    ////private void PaintForm_FormClosing(object sender, FormClosingEventArgs e) {
    ////    if (MainForm.PForm == this)
    ////        MainForm.PForm = null;
    ////}
}
////}

