public void event_PanelMouseDown(object sender, MouseEventArgs e)
        {
            foreach (PlacedProduct PlacedP in PlacementController.placedProductList)
            {
                //Get the mouse location
                var     MouseLocation = new Point(e.X, e.Y);
                Polygon P             = new Polygon();
                P.Points.Add(new Vector(MouseLocation.X, MouseLocation.Y));
                P.BuildEdges();

                //And compare it to all possible polygons, so that when one collides, you know which one the user has clicked on.
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(P, PlacedP.Poly, new Vector(0, 0));

                if (r.WillIntersect)
                {
                    //Do DragDrop
                    clickLocation = MouseLocation;
                    productAdding.DoDragDrop(PlacedP, DragDropEffects.Copy);
                    //Set as current product
                    productAdding.productInfo1.setProduct(PlacedP.Product);
                    currentProduct = PlacedP;
                    break;
                }
            }
        }
        private void placement_MoveProduct(object sender, DragEventArgs e)
        {
            PlacedProduct product = (PlacedProduct)e.Data.GetData(typeof(PlacedProduct));

            //Get the location of the mouse
            Point newLocation = new Point(e.X, e.Y);

            newLocation    = motherFrame.PointToClient(newLocation);
            newLocation.X -= productAdding.productPanel.Left;
            newLocation.Y -= productAdding.productPanel.Top;
            newLocation.Y -= motherFrame.menuStrip1.Height;

            //Failsafe if user clicks the item and doesn't want to move it.
            if (Math.Abs(clickLocation.X - newLocation.X) == 0 || Math.Abs(clickLocation.Y - newLocation.Y) == 0)
            {
                DoRepaint();
                return;
            }


            int deltaX = newLocation.X - clickLocation.X;
            int deltaY = newLocation.Y - clickLocation.Y;

            //Round down to the closest spot on the grid (the movementspeed of an object)
            deltaX = ((deltaX / MovementSpeed) * MovementSpeed);
            deltaY = ((deltaY / MovementSpeed) * MovementSpeed);


            Point   delta        = new Point((int)(product.Location.X + deltaX), (int)(product.Location.Y + deltaY));
            Polygon movedProduct = product.GetVirtualPolygon(delta);


            foreach (Polygon placedP in product.PolyList)
            {
                //Looks to see if the current loop has itself
                if (placedP == product.Poly)
                {
                    continue;
                }

                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(movedProduct, placedP, new Vector(0, 0));

                if (r.WillIntersect)
                {
                    //At the collision, quit the method
                    DoRepaint();
                    return;
                }
            }

            //The moving of the product
            product.MoveTo(delta);
            DoRepaint();
        }
        private void placement_NewProduct(object sender, DragEventArgs e)
        {
            ProductModel model = (ProductModel)e.Data.GetData(typeof(ProductModel));

            //Get the correct location
            Point newLocation = new Point(e.X, e.Y);

            newLocation    = motherFrame.PointToClient(newLocation);
            newLocation.X -= productAdding.productPanel.Left;
            newLocation.Y -= productAdding.productPanel.Top;
            newLocation.Y -= motherFrame.menuStrip1.Height;

            newLocation.X /= MovementSpeed; newLocation.X *= MovementSpeed; //Round down to the movement speed.
            newLocation.Y /= MovementSpeed; newLocation.Y *= MovementSpeed; //Round down to the movement speed.

            PlacedProduct product = new PlacedProduct(model, newLocation);


            //Collision Loop
            foreach (Polygon placedP in product.PolyList)
            {
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(product.Poly, placedP, new Vector(0, 0));

                if (r.WillIntersect)
                {
                    //At the collision, quit the method
                    DoRepaint();
                    return;
                }
            }

            //The adding of the product
            placedProductList.Add(product);
            //Set as current product
            currentProduct = product;
            productAdding.productList1.fixInformation();
            //Redraw
            DoRepaint();
        }
        public void MoveProduct(PlacedProduct selectedProduct, List <PlacedProduct> placedProducts, Vector deltaVector, int panelWidth, int panelHeight)
        {
            //A variable to keep track of collision
            bool collision = false;


            //The new location that the product is going towards
            Point newLocationPoint = new Point(
                (int)(selectedProduct.Location.X + deltaVector.X),
                (int)(selectedProduct.Location.Y + deltaVector.Y));



            //Checkes the borders
            foreach (Polygon wall in selectedProduct.PolyBorder(panelWidth, panelHeight))
            {
                PolygonCollisionController.PolygonCollisionResult result =
                    PolygonCollisionController.PolygonCollision(selectedProduct.Poly, wall, deltaVector);

                if (result.WillIntersect)
                {
                    collision = true;
                    break;
                }
            }


            //Loops through each item and determines if it collides with any of them
            foreach (PlacedProduct collisionTarget in placedProducts)
            {
                if (collision)
                {
                    break;
                }
                if (selectedProduct.Product.Collidable == false) //If the selected product is not collidable. For example an 'Energy Socket'. Break out the loop and place it.
                {
                    break;
                }
                if (collisionTarget.Product.Collidable == false) //If the target is not collidable. For example an 'Energy Socket'. Skip this loop and go to the next target.
                {
                    continue;
                }

                PolygonCollisionController.PolygonCollisionResult result =
                    PolygonCollisionController.PolygonCollision(selectedProduct.Poly, collisionTarget.Poly, deltaVector);

                if (result.WillIntersect)
                {
                    collision = true;
                    break;
                }
            }

            //Failsafe check at the end
            if (!collision)
            { /*selectedProduct.MoveTo(newLocationPoint); */
            }
            else
            {
                MessageBox.Show("Fail");
            }
            MessageBox.Show(newLocationPoint.ToString());
        }
        /// <summary>
        /// Issues the rotation of the product.
        /// </summary>
        /// <param name="fallbackAngle">The fallback angle to provide should the product not be able to rotate.</param>
        public static void placement_rotatePoints(PlacedProduct targetProduct, int fallbackAngle)
        {
            PointF[]     fallbackPoints = new PointF[5];
            ProductModel product        = targetProduct.Product;
            PointF       location       = targetProduct.Location;

            for (int index = 0; index < targetProduct.CornerPoints.Length; index++)
            {
                fallbackPoints[index] = targetProduct.CornerPoints[index];
            }

            double angle_Even   = (double)targetProduct.CurrentAngle;
            double angle_Uneven = targetProduct.CurrentAngle;
            double radius       = Math.Sqrt(Math.Pow(0.5 * product.Width, 2) + Math.Pow(0.5 * product.Length, 2));


            //Tan^-1 ( (1/2H) / (1/2W) )
            //This is to get the angle of the center of the rectangle relevant to the sides. (To get the angle inside the rectangle)
            angle_Even   += (Math.Atan((0.5 * product.Length) / (0.5 * product.Width)) * 180 / Math.PI);
            angle_Uneven -= 90 - (Math.Atan((0.5 * product.Width) / (0.5 * product.Length)) * 180 / Math.PI);
            //If the angle is negative, add 360 to it to get the positive version
            while (angle_Uneven < 0)
            {
                angle_Uneven += 360;
            }
            while (angle_Even < 0)
            {
                angle_Even += 360;
            }
            //MessageBox.Show("Depth: " + product.depth + ". Width: " + product.width);
            //MessageBox.Show("Even angle: " + angle_Even.ToString() + ". Uneven angle: " + angle_Uneven.ToString());

            //Get the total angle to know what direction the item is facing. (To know where to apply the deltaX and deltaY)
            int directional_Even   = Convert.ToInt32(angle_Even) % 360;
            int directional_Uneven = Convert.ToInt32(angle_Uneven) % 360;

            //Gets a 4 possible outcome to determine what deltaX and deltaY do.
            directional_Even   = directional_Even / 90;
            directional_Uneven = directional_Uneven / 90;

            /*
             * 0-89 = 0 (360 degrees is 0 degrees)
             * 90-179 = 1
             * 180-269 = 2
             * 270-359 = 3
             */

            //Gets the angle nearest to 90, so that the Cos and Sin methods work.
            angle_Even   = angle_Even % 90;
            angle_Uneven = angle_Uneven % 90;
            //MessageBox.Show("Even angle: " + angle_Even.ToString() + ". Uneven angle: " + angle_Uneven.ToString());


            //Get the difference in X and Y to be applied to the centre point so the corner points can be calculated
            float Cos_Even = (float)(Math.Cos(angle_Even * Math.PI / 180) * radius);
            float Sin_Even = (float)(Math.Sin(angle_Even * Math.PI / 180) * radius);

            float Cos_Uneven = (float)(Math.Cos(angle_Uneven * Math.PI / 180) * radius);
            float Sin_Uneven = (float)(Math.Sin(angle_Uneven * Math.PI / 180) * radius);



            //Determine what deltaX and deltaY do.
            switch (directional_Even)
            {
            case 0:     //Total degree is between 0 and 89
                targetProduct.CornerPoints[0] = new PointF(location.X - Cos_Even, location.Y - Sin_Even);
                targetProduct.CornerPoints[2] = new PointF(location.X + Cos_Even, location.Y + Sin_Even);
                break;


            case 1:     //Total degree is between 90 and 179
                targetProduct.CornerPoints[0] = new PointF(location.X + Sin_Even, location.Y - Cos_Even);
                targetProduct.CornerPoints[2] = new PointF(location.X - Sin_Even, location.Y + Cos_Even);
                break;


            case 2:     //Total degree is between 180 and 269
                targetProduct.CornerPoints[0] = new PointF(location.X + Cos_Even, location.Y + Sin_Even);
                targetProduct.CornerPoints[2] = new PointF(location.X - Cos_Even, location.Y - Sin_Even);
                break;


            case 3:     //Total degree is between 270 and 359
                targetProduct.CornerPoints[0] = new PointF(location.X - Sin_Even, location.Y + Cos_Even);
                targetProduct.CornerPoints[2] = new PointF(location.X + Sin_Even, location.Y - Cos_Even);
                break;

            default:
                goto case 0;
            }
            switch (directional_Uneven)
            {
            case 0:     //Total degree is between 1 and 90
                targetProduct.CornerPoints[1] = new PointF(location.X + Cos_Uneven, location.Y + Sin_Uneven);
                targetProduct.CornerPoints[3] = new PointF(location.X - Cos_Uneven, location.Y - Sin_Uneven);
                break;


            case 1:     //Total degree is between 91 and 180
                targetProduct.CornerPoints[1] = new PointF(location.X - Sin_Uneven, location.Y + Cos_Uneven);
                targetProduct.CornerPoints[3] = new PointF(location.X + Sin_Uneven, location.Y - Cos_Uneven);
                break;


            case 2:     //Total degree is between 181 and 270
                targetProduct.CornerPoints[1] = new PointF(location.X - Cos_Uneven, location.Y - Sin_Uneven);
                targetProduct.CornerPoints[3] = new PointF(location.X + Cos_Uneven, location.Y + Sin_Uneven);
                break;


            case 3:     //Total degree is between 271 and 360
                targetProduct.CornerPoints[1] = new PointF(location.X + Sin_Uneven, location.Y - Cos_Uneven);
                targetProduct.CornerPoints[3] = new PointF(location.X - Sin_Uneven, location.Y + Cos_Uneven);
                break;

            default:
                goto case 0;
            }
            //Set the last angle to the first angle to complete the square
            targetProduct.CornerPoints[4] = targetProduct.CornerPoints[0];



            //Setting the new points to the polygon
            targetProduct.Poly = new Polygon();
            foreach (PointF point in targetProduct.CornerPoints)
            {
                targetProduct.Poly.Points.Add(new Vector(point.X, point.Y));
            }
            targetProduct.Poly.BuildEdges();



            //Testing if turning caused a collision
            foreach (Polygon placedPoly in targetProduct.PolyList)
            {
                //Test if the selected polygon is himself
                if (placedPoly == targetProduct.Poly)
                {
                    continue;
                }

                //Test if the polygon collides with others
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(targetProduct.Poly, placedPoly, new Vector(0, 0));

                //If it does, cancel the rotation
                if (r.WillIntersect)
                {
                    //Issue the fallback
                    targetProduct.CurrentAngle = fallbackAngle;

                    //Issue the fallback
                    for (int index = 0; index < targetProduct.CornerPoints.Length; index++)
                    {
                        targetProduct.CornerPoints[index] = fallbackPoints[index];
                    }

                    //Restate the polygon
                    targetProduct.Poly = new Polygon();
                    foreach (PointF point in targetProduct.CornerPoints)
                    {
                        targetProduct.Poly.Points.Add(new Vector(point.X, point.Y));
                    }
                    targetProduct.Poly.BuildEdges();

                    //MessageBox.Show("The rotation has caused a collision.");
                }
            }
        }
        /// <summary>
        /// Moves the product a certain amount to a certain direction
        /// </summary>
        /// <param name="X_Axis">Chooses the axis that the product moves on. True for X-axis. False for Y-axis</param>
        public static void placement_Move(PlacedProduct targetProduct, bool X_Axis)
        {
            int x = 0;
            int y = 0;

            if (X_Axis)
            {
                x += targetProduct.GridSpace;
            }
            else
            {
                y += targetProduct.GridSpace;
            }

            Vector velocity           = new Vector(x, y);
            Vector playerTranslation1 = velocity;
            Vector playerTranslation2 = velocity;

            //Resets the speed, after the velocity has been assigned.
            if (targetProduct.GridSpace < 0)
            {
                targetProduct.GridSpace *= -1;
            }


            //Test all product polygons for a collision
            foreach (PlacedProduct placedP in placedProductList)
            {
                //Test if the selected polygon is himself
                if (placedP.Poly == targetProduct.Poly)
                {
                    continue;
                }

                //Test if the polygon collides with others
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(targetProduct.Poly, placedP.Poly, velocity);

                //If it does, alter the speed
                if (r.WillIntersect)
                {
                    //
                    playerTranslation1 = velocity + r.MinimumTranslationVector;

                    if (X_Axis) //Moving the x-axis, so set the y-axis velocity to 0
                    {
                        playerTranslation1.Y = 0;
                    }
                    else //Moving the y-axis, so set the x-axis velocity to 0
                    {
                        playerTranslation1.X = 0;
                    }

                    //If there is any movement along the Y axis while moving along the X axis, then the polygon collision want to move around the other polygon. Can't let that happen. So set all movement to 0.
                    if (X_Axis && r.MinimumTranslationVector.Y != 0)
                    {
                        playerTranslation1.X = 0;
                        playerTranslation1.Y = 0;
                    }
                    if (!X_Axis && r.MinimumTranslationVector.X != 0)
                    {
                        playerTranslation1.X = 0;
                        playerTranslation1.Y = 0;
                    }

                    //Round down to the closest x pixels
                    playerTranslation1.X = ((int)playerTranslation1.X / targetProduct.GridSpace) * targetProduct.GridSpace;
                    playerTranslation1.Y = ((int)playerTranslation1.Y / targetProduct.GridSpace) * targetProduct.GridSpace;
                    //MessageBox.Show("then " + playerTranslation1.X.ToString() + " and " + playerTranslation1.Y.ToString());
                    break;
                }
            }


            //Test all product polygons for a collision
            foreach (PlacedProduct placedO in staticlyPlacedObjectList)
            {
                //Test if the selected polygon is himself
                if (placedO.Poly == targetProduct.Poly)
                {
                    continue;
                }

                //Test if the polygon collides with others
                PolygonCollisionController.PolygonCollisionResult r = PolygonCollisionController.PolygonCollision(targetProduct.Poly, placedO.Poly, velocity);

                //If it does, alter the speed
                if (r.WillIntersect)
                {
                    //
                    playerTranslation2 = velocity + r.MinimumTranslationVector;

                    if (X_Axis) //Moving the x-axis, so set the y-axis velocity to 0
                    {
                        playerTranslation2.Y = 0;
                    }
                    else //Moving the y-axis, so set the x-axis velocity to 0
                    {
                        playerTranslation2.X = 0;
                    }

                    //If there is any movement along the Y axis while moving along the X axis, then the polygon collision want to move around the other polygon. Can't let that happen. So set all movement to 0.
                    if (X_Axis && r.MinimumTranslationVector.Y != 0)
                    {
                        playerTranslation2.X = 0;
                        playerTranslation2.Y = 0;
                    }
                    if (!X_Axis && r.MinimumTranslationVector.X != 0)
                    {
                        playerTranslation2.X = 0;
                        playerTranslation2.Y = 0;
                    }

                    //Round down to the closest x pixels
                    playerTranslation2.X = ((int)playerTranslation2.X / targetProduct.GridSpace) * targetProduct.GridSpace;
                    playerTranslation2.Y = ((int)playerTranslation2.Y / targetProduct.GridSpace) * targetProduct.GridSpace;
                    //MessageBox.Show("then " + playerTranslation2.X.ToString() + " and " + playerTranslation2.Y.ToString());
                    break;
                }
            }

            //Compares the tanslations

            /*
             * 1. Makes a new vector
             * 2. compares the two, and chooses the highest for the X and the highest for the Y (it looks for the highest number, even when negative. ie. -10 is higher than 4)
             * 3. If one of the two is 0, then set that Axis to 0
             */
            //1
            Vector playerTranslation = new Vector();

            //2
            playerTranslation.X = Math.Abs(playerTranslation1.X) > Math.Abs(playerTranslation2.X)
                ? playerTranslation1.X
                : playerTranslation2.X;
            playerTranslation.Y = Math.Abs(playerTranslation1.Y) > Math.Abs(playerTranslation2.Y)
                ? playerTranslation1.Y
                : playerTranslation2.Y;
            //3
            if (playerTranslation1.X == 0 || playerTranslation2.X == 0)
            {
                playerTranslation.X = 0;
            }
            if (playerTranslation1.Y == 0 || playerTranslation2.Y == 0)
            {
                playerTranslation.Y = 0;
            }

            //Set the polygon points
            targetProduct.Poly.Offset(playerTranslation);

            //Update the corner points
            for (int index = 0; index < targetProduct.Poly.Points.Count; index++)
            {
                targetProduct.CornerPoints[index] = new PointF(targetProduct.Poly.Points[index].X, targetProduct.Poly.Points[index].Y);
            }

            //Update the center point
            targetProduct.Location = new PointF(targetProduct.Location.X + playerTranslation.X, targetProduct.Location.Y + playerTranslation.Y);
        }