public Rectangle GetProductRectangle(PlacedProduct product, float width, float height, float size)
 {
     Rectangle rectangle;
     if (product.Product.Size.IsEmpty)
     {
         // this is a product that came from the algorithm
         rectangle = new Rectangle
         {
             Height = (int) (product.Product.Height/size*height),
             Width = (int) (product.Product.Width/size*width),
             X = (int) (product.Location.X/size*width),
             Y = (int) (product.Location.Y/size*height)
         };
     }
     else
     {
         rectangle = new Rectangle
         {
             Height = (int) (product.Product.Size.Height/size*height),
             Width = (int) (product.Product.Size.Width/size*width),
             X = (int) (product.Location.X/size*width),
             Y = (int) (product.Location.Y/size*height)
         };
     }
     return rectangle;
 }
        public void rotation_setAngle_90()
        {
            //Make
            PointF point = new PointF(200, 200);
            ProductModel product = new ProductModel(10, 10, 50);
            PlacedProduct placedP = new PlacedProduct(product, point);

            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X + product.Width / 2, point.Y - product.Length / 2); //now the top right
            pointCorner[1] = new PointF(point.X + product.Width / 2, point.Y + product.Length / 2); //now the lower right
            pointCorner[2] = new PointF(point.X - product.Width / 2, point.Y + product.Length / 2); //now the lower left
            pointCorner[3] = new PointF(point.X - product.Width / 2, point.Y - product.Length / 2); //now the top left


            //Do
            placedP.SetAngle(90);



            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product has changed!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product has changed!");

            for (int index = 0; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
 public void CountProductsAmountPlaced(PlacedProduct product)
 {
     // get the current product
     ProductModel productMod = product.Product;
     // use method overload
     CountProductsAmountPlaced(productMod);
 }
        public void rotation_setAngle_45()
        {
            //Make
            PointF point = new PointF(200, 200);
            ProductModel product = new ProductModel(10, 10, 50);
            PlacedProduct placedP = new PlacedProduct(product, point);

            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X, point.Y - (float)Math.Sqrt(50));    //{200 ; 200-√50}
            pointCorner[1] = new PointF(point.X + (float)Math.Sqrt(50), point.Y);                           //{200+√50 ; 200}
            pointCorner[2] = new PointF(point.X, point.Y + (float)Math.Sqrt(50));    //{200 ; 200+√50}
            pointCorner[3] = new PointF(point.X - (float)Math.Sqrt(50), point.Y);                           //{200-√50 ; 200}

            /*
                Coordinate = {(centerlocation) (direction + or -) (size/2)}

                Point 0 = Top Left
                {200-(10/2) ; 200-(10/2)} = {195 ; 195}

                Point 1 = Top Right
                {200+(10/2) ; 200-(10/2)} = {205 ; 195}

                Point 2 = Lower Right
                {200+(10/2) ; 200+(10/2)} = {205 ; 205}

                Point 3 = Lower Left
                {200-(10/2) ; 200+(10/2)} = {195 ; 205}


                Do some math, and when the square turns 45 degrees, the points are the following:

                [0] = {200 ; 200-√50}
                [1] = {200+√50 ; 200}
                [2] = {200 ; 200+√50}
                [3] = {200-√50 ; 200}
            */



            //Do
            placedP.SetAngle(45);



            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product has changed!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product has changed!");

            for (int index = 0; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
        public void collision_MoveCollision()
        {
            //Move -> Collision

            //Move X+50, Y+0
            //Move X+50, Y+0 - can't move all the way because collision, so only X+30

            //Make
            PointF point = new PointF(200, 200); //Right end = 350 (200+150)
            PointF pointWall = new PointF(440, 200); //Left end = 430 (440-10)

            ProductModel product = new ProductModel(100, 300, 50); //Width = 300, so it's 150 + 150
            ProductModel productWall = new ProductModel(20, 20, 50); //Width = 20, so it's 10 + 10
            

            PlacedProduct placedP = new PlacedProduct(product, point);
            PlacedProduct placedWall = new PlacedProduct(productWall, pointWall);

            PlacementController.placedProductList.Add(placedP);
            PlacementController.placedProductList.Add(placedWall);

            int move_x = 60;
            int move_y = 0; 

            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X - (product.Width / 2) + move_x, point.Y - (product.Length / 2) + move_y);   //{205 ; 195}
            pointCorner[1] = new PointF(point.X + (product.Width / 2) + move_x, point.Y - (product.Length / 2) + move_y);   //{215 ; 195}
            pointCorner[2] = new PointF(point.X + (product.Width / 2) + move_x, point.Y + (product.Length / 2) + move_y);   //{215 ; 205}
            pointCorner[3] = new PointF(point.X - (product.Width / 2) + move_x, point.Y + (product.Length / 2) + move_y);   //{205 ; 205}




            //Do
            placedP.GridSpace = 50; //Set grid (movement speed) to 50.
            placedP.Move(true); //{250;200}
            placedP.Move(true); //{300;200}Cant perform this.
            placedP.GridSpace = 10;
            placedP.Move(true); //{260;200} Now it can, because the grid was changed, and that allowed it to move 'slower'
            point.X += move_x;
            point.Y += move_y;


            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product is different!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product is different!");

            for (int index = 0; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
        public void move_SingleMoveVertical()
        {
            //Move X+0, Y+10

            //Make
            PointF point = new PointF(200, 200);
            ProductModel product = new ProductModel(10, 10, 50);
            PlacedProduct placedP = new PlacedProduct(product, point);

            int move_x = 0;
            int move_y = 10;

            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X - (product.Width / 2) + move_x, point.Y - (product.Length / 2) + move_y);   //{195 ; 205}
            pointCorner[1] = new PointF(point.X + (product.Width / 2) + move_x, point.Y - (product.Length / 2) + move_y);   //{205 ; 205}
            pointCorner[2] = new PointF(point.X + (product.Width / 2) + move_x, point.Y + (product.Length / 2) + move_y);   //{205 ; 215}
            pointCorner[3] = new PointF(point.X - (product.Width / 2) + move_x, point.Y + (product.Length / 2) + move_y);   //{195 ; 215}




            //Do
            placedP.GridSpace = 10;
            placedP.Move(false);
            point.X += move_x;
            point.Y += move_y;


            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product is different!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product is different!");

            for (int index = 0; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
        /// <summary>
        /// Selects the Brush where the type matches from the Dictionary kept in the Legend.
        /// </summary>
        /// <param name="product"></param>
        /// <param name="dict"></param>
        /// <returns></returns>
        public SolidBrush SelectBrush(PlacedProduct product, Dictionary<string, SolidBrush> dict)
        {
            SolidBrush brush;
            try
            {
                CategoryModel Currentcat = product.Product.ProductCategory;

                if (Currentcat.IsSubcategoryFrom > -1 || Currentcat.IsSubcategoryFrom == null) // is a subcategory
                {
                    // gets the main category id
                    int MainId = (int) Currentcat.IsSubcategoryFrom;

                    // linq select category with the current id
                    var selectedcategory2 = CategoryModel.List
                        .Where(c => c.CatId == MainId)
                        .Select(c => c)
                        .ToList();

                    CategoryModel Main = selectedcategory2[0];

                    // gets the value (color) from the Main productcategory
                    brush = new SolidBrush(Main.Colour);
                }
                else // is a maincategory
                {
                    // give the color from the main category
                    brush = dict.Single(pair => pair.Key.Equals(product.Product.Category)).Value;
                }
            }
            catch (InvalidOperationException e)
            {
                // This means that the type is not found in the dictionary, and so I will set the Brush to Black
                brush = new SolidBrush(Color.Gray);
            }
            return brush;
        }
 //
 public void ChangeSelected(ProductInfo sender)
 {
     productAdding.productInfo1.setProduct(sender.product); //Sets a new product
     if(currentProduct.Product.Name != sender.product.Name) { currentProduct = null; }
     //Seing as name is an identifier in the database, this can be used to compare the two: Look if the names are the same, if not, then a different product is the currentProduct. Therefore the currentProduct needs to be set to null.
 }
        /// <summary>
        /// Issues the rotation of the image of the product.
        /// </summary>
        public static void placement_rotateImg(PlacedProduct targetProduct)
        {
            Color bkColor = Color.Transparent;
            int angle = targetProduct.CurrentAngle;
            Bitmap defaultMap = targetProduct.DefaultBitMap;

            angle = angle % 360;
            if (angle > 180)
                angle -= 360;

            PixelFormat pf = default(PixelFormat);
            if (bkColor == Color.Transparent)
            {
                pf = PixelFormat.Format32bppArgb;
            }
            else
            {
                pf = defaultMap.PixelFormat;
            }

            float sin = (float)Math.Abs(Math.Sin(angle * Math.PI / 180.0)); // this function takes radians
            float cos = (float)Math.Abs(Math.Cos(angle * Math.PI / 180.0)); // this one too
            float newImgWidth = sin * defaultMap.Height + cos * defaultMap.Width;
            float newImgHeight = sin * defaultMap.Width + cos * defaultMap.Height;
            float originX = 0f;
            float originY = 0f;

            if (angle > 0)
            {
                if (angle <= 90)
                    originX = sin * defaultMap.Height;
                else
                {
                    originX = newImgWidth;
                    originY = newImgHeight - sin * defaultMap.Width;
                }
            }
            else
            {
                if (angle >= -90)
                    originY = sin * defaultMap.Width;
                else
                {
                    originX = newImgWidth - sin * defaultMap.Height;
                    originY = newImgHeight;
                }
            }

            Bitmap newImg = new Bitmap((int)newImgWidth, (int)newImgHeight, pf);
            Graphics g = Graphics.FromImage(newImg);
            g.Clear(bkColor);
            g.TranslateTransform(originX, originY); // offset the origin to our calculated values
            g.RotateTransform(angle); // set up rotate
            g.InterpolationMode = InterpolationMode.HighQualityBilinear;
            g.DrawImageUnscaled(defaultMap, 0, 0); // draw the image at 0, 0
            g.Dispose();

            targetProduct.RotatedMap = newImg;
        }
 public void GetPlacements_FromDatabase()
 {
     foreach (var placement in this.DataSet.placement)
     {
         var p1 = new PlacedProduct(GetSpecificProduct_FromDatabase(placement.product_id), new System.Drawing.PointF(placement.x_position, placement.y_position),placement.angle);
     }
 }
        /// <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);

        }
        /// <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.");
                }
            }
        }
        public void DeleteProduct(PlacedProduct product)
        {
            if (product == null)
                return;

            placedProducts.Remove(product);
            view.Get(ProductGrid.PropertyEnum.Panel).Invalidate();
            ((ProductGrid) view).productList.fixInformation();
        }
        public void PanelMouseDown(object sender, MouseEventArgs e)
        {
            PlacedProduct product = utility.GetProductFromField(e.Location, placedProducts, tileWidth, tileHeight,
                tileSize);

            if (product != null && !(product.StaticProductBoolean && space.Final))
            {
                selectedProduct = product;
                draggingProduct = true;

                selectedProduct.OriginalLocation = selectedProduct.Location;
            }
            else
            {
                selectedProduct = null;
                draggingProduct = false;
            }
            view.Get(ProductGrid.PropertyEnum.Panel).Invalidate();
        }
 private void PaintProduct(PlacedProduct product, Graphics g)
 {
     Rectangle rectangle = utility.GetProductRectangle(product, tileWidth, tileHeight, tileSize);
     SolidBrush brush = utility.SelectBrush(product, legendDictionary);
     int angle = product.CurrentAngle;
     using (Matrix m = new Matrix())
     {
         m.RotateAt(angle, new PointF(rectangle.Left + rectangle.Width/2, rectangle.Top + rectangle.Height/2));
         g.Transform = m;
         if (product == selectedProduct)
         {
             Rectangle selectionRectangle = new Rectangle(rectangle.X, rectangle.Y, rectangle.Width,
                 rectangle.Height);
             Pen pen = new Pen(Color.Red, 4);
             g.DrawRectangle(pen, selectionRectangle);
         }
         g.FillRectangle(brush, rectangle);
         g.ResetTransform();
     }
 }
        public void MoveProduct(ICollisionHandler<PlacedProduct> handler, PlacedProduct selectedProduct,
            List<PlacedProduct> placedProducts, int boundWidth, int boundHeight,
            float realWidth, float realHeight, float x, float y, bool real)
        {
            float selectedWidth = selectedProduct.Product.Size.Width,
                selectedHeight = selectedProduct.Product.Size.Height;

            float newX = (real) ? x : x/(float) boundWidth*realWidth
                         - selectedWidth/2,
                newY = (real) ? y : y/(float) boundHeight*realHeight
                       - selectedHeight/2;
            

            if (newX <= 0)
                newX = 0;
            if (newX + selectedWidth/2 >= realWidth - selectedWidth/2)
                newX = realWidth - selectedWidth;
            if (newY <= 0)
                newY = 0;
            if (newY + selectedHeight/2 >= realHeight - selectedHeight/2)
                newY = realHeight - selectedHeight;

            PointF newLocation = new PointF(newX, newY);
            selectedProduct.Location = !handler.Collision(selectedProduct, placedProducts)
                ? newLocation
                : selectedProduct.OriginalLocation;
        }
        public void rotation_addAngle_45()
        {
            //Make
            PointF point = new PointF(200, 200);
            ProductModel product = new ProductModel(10, 10, 50);
            PlacedProduct placedP = new PlacedProduct(product, point);

            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X, point.Y - (float)Math.Sqrt(50));    //{200 ; 200-√50}
            pointCorner[1] = new PointF(point.X + (float)Math.Sqrt(50), point.Y);                           //{200+√50 ; 200}
            pointCorner[2] = new PointF(point.X, point.Y + (float)Math.Sqrt(50));    //{200 ; 200+√50}
            pointCorner[3] = new PointF(point.X - (float)Math.Sqrt(50), point.Y);                           //{200-√50 ; 200}
            

            //Do
            placedP.AddAngle(25);
            placedP.AddAngle(20);



            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product has changed!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product has changed!");

            for (int index = 0; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
        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());

        }
        //
        public void placeProducts()
        {
            foreach (var placedProduct in dbc.DataSet.placement)
            {
                if (placedProduct.space_number == productAdding.space.Room)
                {
                    // get placed productID product
                    foreach (ProductModel product in ProductModel.List)
                    {
                        if (product.ProductId == placedProduct.product_id)
                        {

                            Point point = new Point(placedProduct.x_position, placedProduct.y_position);
                            PlacedProduct p1 = new PlacedProduct(product, point,0);

                            placedProductList.Add(p1);
                        }
                    }
                }
            }
        }
        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_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 collision_RotateCollision()
        {
            //Rotate -> Collision

            //Rotate 15
            //Rotate 15
            //Rotate 15
            //Rotate 15 -can't do this because collision

            //Make
            PointF point = new PointF(400, 200);
            PointF pointWall = new PointF(400, 50);

            ProductModel product = new ProductModel(100, 300, 50);
            ProductModel productWall = new ProductModel(100, 50, 50);

            PlacedProduct placedP = new PlacedProduct(product, point);
            PlacedProduct placedWall = new PlacedProduct(productWall, pointWall);

            PlacementController.placedProductList.Add(placedP);
            PlacementController.placedProductList.Add(placedWall);
            

            double radius = Math.Sqrt(Math.Pow(product.Width/2, 2) + Math.Pow(product.Length/2, 2));
            double initialAngle = (Math.Atan((0.5 * product.Length) / (0.5 * product.Width)) * 180 / Math.PI);
            
            double angle_Even = 45 + initialAngle;
            double angle_Uneven = 45 - initialAngle;            

            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);


            PointF[] pointCorner = new PointF[4];
            pointCorner[0] = new PointF(point.X - Cos_Even, point.Y - Sin_Even);   //{205 ; 195}
            pointCorner[1] = new PointF(point.X + Cos_Uneven, point.Y + Sin_Uneven);   //{215 ; 195}
            pointCorner[2] = new PointF(point.X + Cos_Even, point.Y + Sin_Even);   //{215 ; 205}
            pointCorner[3] = new PointF(point.X - Cos_Uneven, point.Y - Sin_Uneven);   //{205 ; 205}



            //Do
            placedP.AddAngle(15); //after this it's 15
            placedP.AddAngle(15); //after this it's 30
            placedP.AddAngle(15); //after this it's 45
            placedP.AddAngle(15); //after this it's 60 -Can't perform this because of the collision.
            placedP.AddAngle(15); //after this it's 75 -Can't perform this.
            placedP.AddAngle(15); //after this it's 90 -Can't perform this.


            //Look
            Assert.AreEqual(point.X, placedP.Location.X, 0.1, "The horizontal location of the product is different!");
            Assert.AreEqual(point.Y, placedP.Location.Y, 0.1, "The vertical location of the product is different!");

            for (int index = 1; index < pointCorner.Length; index++)
            {
                Assert.AreEqual(pointCorner[index].ToString(), placedP.CornerPoints[index].ToString(), true, "Corner #" + index + " is in the wrong spot!");
            }
        }
        public void AddNewProduct(ProductModel model, float x, float y, float width, float height, bool realDimensions,
            int angle)
        {
            float viewWidth = view.Get(ProductGrid.PropertyEnum.Panel).Width,
                viewHeight = view.Get(ProductGrid.PropertyEnum.Panel).Height,
                newX = realDimensions ? x : x/viewWidth*meterWidth,
                newY = realDimensions ? y : y/viewHeight*meterHeight;

            PointF center = (realDimensions) ? new PointF(x, y) : new PointF(newX-width/2, newY-height/2);
            int currentangle = angle;

            SizeF size = new SizeF(width, height);
            model.Size = size;
            PlacedProduct newProduct = new PlacedProduct(model, center, currentangle);

            // Do not add product to field if it has collision
            if (!collisionHandler.Collision(newProduct, placedProducts))
            {
                placedProducts.Add(newProduct);
                ((ProductGrid) view).productList.fixInformation();
            }
        }