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

namespace WindowsFormsApplication1
{
    public partial class frmAuto : Form
    {
        private frmAuto()
        {
            InitializeComponent();
            PublicVarClass.numberOfPoints = 0;
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);

        }
        Form callerForm;
        public frmAuto(Form f1)
        {
            InitializeComponent();
            PublicVarClass.numberOfPoints = 0;
            this.DoubleBuffered = true;
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.callerForm = f1;
             
        }
        public void showMe()
        {
            Show();
            if (callerForm != null)
            {
                callerForm.Hide();
            }

        }

        private void btnBrowse_Click(object sender, EventArgs e)
        {
            string Chosen_File = "";
            openFD.Title = "Insert an Image";
            //format should be filtered

            if (openFD.ShowDialog() != DialogResult.Cancel)
            {

                Chosen_File = openFD.FileName;
                pictureBox1.Image = Image.FromFile(Chosen_File);
                pictureBox1.Width = pictureBox1.Image.Width;
                pictureBox1.Height = pictureBox1.Image.Height;
            }
            
        }

        
        public void drawPoint(Point point,Color color)
        {
            int x = point.X;
            int y = point.Y;
	        Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
            //Graphics g = Graphics.FromHwnd(this.Handle );
	        SolidBrush brush = new SolidBrush(color);
    	    Point dPoint = new Point(x, y);//(pictureBox1.Height - y));
	        dPoint.X = dPoint.X - 2;
	        dPoint.Y = dPoint.Y - 2;
	        Rectangle rect = new Rectangle(dPoint, new Size(4, 4));
        	g.FillRectangle(brush, rect);
	        g.Dispose();
        }

        

        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (pictureBox1.Image == null)
                return;
            pictureBox1.Invalidate();
            pictureBox1.Update();

            

            drawPoint(new Point(e.X, e.Y), Color.Violet);

            //Repainting
            PaintPoints();
            

        }

        private void button1_Click(object sender, EventArgs e)
        {
            PublicVarClass.pointBDetermined = PublicVarClass.pointCDetermined = PublicVarClass.pointDDetermined = false;
            rdBPoint.PerformClick();
            PublicVarClass.AutoChangePointSelected = true;
            pictureBox1.Invalidate();
        }


        /// <summary>

        /// Calculate the angle (in degrees) between 3 points

        /// </summary>

        /// <param name="a">end point</param>

        /// <param name="b">center point</param>

        /// <param name="c">end point</param>

        /// <returns>angle (0 to 180)</returns>

        public static int GetAngle(PointF a, PointF b, PointF c)
        {

            double result;

            // calculating the 3 distances

            double ab = GetDistance(a, b);

            double bc = GetDistance(b, c);

            double ac = GetDistance(a, c);

            double cosB = Math.Pow(ac, 2) - Math.Pow(ab, 2) - Math.Pow(bc, 2);

            cosB = cosB / (2 * ab * bc);

            result = 180 - (Math.Acos(cosB) * 180 / Math.PI);

            return Convert.ToInt32(result);

        }

        private static double GetDistance(PointF point1, PointF point2)
        {
            //pythagorean theorem c^2 = a^2 + b^2
            //thus c = square root(a^2 + b^2)
            double a = (double)(point2.X - point1.X);
            double b = (double)(point2.Y - point1.Y);

            return Math.Sqrt(a * a + b * b);
        }

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            PublicVarClass.InvalidPoints = false;
            if (pictureBox1.Image == null)
                return;

            pictureBox1.Invalidate();
            pictureBox1.Update();
            
            int x = e.X;// System.Windows.Forms.Cursor.Position.X;
            int y = pictureBox1.Height -e.Y;// System.Windows.Forms.Cursor.Position.Y;
            

            if (rdBPoint.Checked)
            {
                PublicVarClass.pointB = new Point(x, y);
                PublicVarClass.pointBDetermined=true;
                
            }
            else if (rdCPoint.Checked)
            {
                PublicVarClass.pointC = new Point(x, y);
                PublicVarClass.pointCDetermined=true;
              
            }
            else if (rdDPoint.Checked)
            {
                PublicVarClass.pointD = new Point(x, y);
                PublicVarClass.pointDDetermined=true;
                
            }
            else
            {
                MessageBox.Show("Please chose the point that you want to determine.");
            }

            //repainting points
            PaintPoints();     
       
            //AutoChange
            if (PublicVarClass.AutoChangePointSelected)
                if (rdBPoint.Checked)
                    rdCPoint.PerformClick();
                else if (rdCPoint.Checked)
                    rdDPoint.PerformClick();
                else
                    PublicVarClass.AutoChangePointSelected = false;



        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            if (!(PublicVarClass.pointBDetermined) || !(PublicVarClass.pointCDetermined) || !(PublicVarClass.pointDDetermined))
            {
                MessageBox.Show("Please select the points.");
                return;
            }

            if ((PublicVarClass.InvalidPoints) )
            {
                MessageBox.Show("Please select correct points.");
                return;
            }

            

           

            
                PublicVarClass.x = ((PublicVarClass.pointB.X - PublicVarClass.pointD.X + PublicVarClass.x0) + PublicVarClass.xOffset) * PublicVarClass.xCoef;
                PublicVarClass.x = Convert.ToInt32(PublicVarClass.x * PublicVarClass.scale);
                

                PublicVarClass.y = ((PublicVarClass.pointD.Y - PublicVarClass.pointB.Y - PublicVarClass.y0) + PublicVarClass.yOffset) * PublicVarClass.yCoef;
                PublicVarClass.y = Convert.ToInt32(PublicVarClass.y * PublicVarClass.scale);

                Point tempPointForAngel = new Point(PublicVarClass.pointB.X + 10, PublicVarClass.pointB.Y);
                try
                {
                    int t1 = GetAngle(tempPointForAngel, PublicVarClass.pointB, PublicVarClass.pointC);
                    int t2 = GetAngle(PublicVarClass.pointB, PublicVarClass.pointC, PublicVarClass.pointD);
                    PublicVarClass.a = t1 + t2;
                    frmManual formManual = new frmManual(this);
                    formManual.showMe();
                    this.Hide();
                }
                catch
                {
                    MessageBox.Show("Invalid Points!");
                    PublicVarClass.InvalidPoints = true;
                }
                

                //PublicVarClass.send();
                
            
        }

        public void PaintPoints()
        {//repainting the points
            if (PublicVarClass.pointBDetermined)
            {
                drawPoint(new Point(PublicVarClass.pointB.X, pictureBox1.Height - PublicVarClass.pointB.Y), Color.LimeGreen);

            }
            if (PublicVarClass.pointCDetermined)
                drawPoint(new Point(PublicVarClass.pointC.X, pictureBox1.Height - PublicVarClass.pointC.Y), Color.Blue);
            if (PublicVarClass.pointDDetermined)
                drawPoint(new Point(PublicVarClass.pointD.X, pictureBox1.Height - PublicVarClass.pointD.Y), Color.Red);
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            
            
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void frmAuto_Load(object sender, EventArgs e)
        {
            PaintPoints();
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void frmAuto_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (callerForm != null)
            {
                callerForm.Show();
            }
        }
    }
}
