public LevelSelectButton(RectCollider collider, LevelSelectScrollBar scrollBar, int levelNo)
            : base(collider)
        {
            LevelNo = levelNo;
            ScrollBar = scrollBar;

            if (LoadedLevelManager.HighestUnlockedLevel == levelNo)
            {
                ButtonSprite = new Sprite(Assets.LevelSelect.Images.UnclearedLevelButton);
            }
            else if (LoadedLevelManager.HighestUnlockedLevel > levelNo)
            {
                ButtonSprite = new Sprite(Assets.LevelSelect.Images.ClearedLevelButton);
            }
            else
            {
                ButtonSprite = new Sprite(Assets.LevelSelect.Images.LockedLevelButton);
                LockInteraction();
                unlockedLevel = false;
            }
            LevelNoFont  = Assets.LevelSelect.Fonts.LevelNo;

            ButtonSprite.Position = collider.TopLeft;
            var textDimensions = LevelNoFont.MeasureString((LevelNo + 1).ToString());
            TextPosition = (ButtonSprite.Bounds - textDimensions) / 2f + collider.TopLeft;
        }
        public ScrollBarForm(
            Vector2 topLeft, int scrollBarLength, int spanLength, 
            int scrollBarWidth, bool vertical, bool keepsTime = true)
            : base(keepsTime)
        {
            Locked = false;
            Vertical = vertical;
            Span = spanLength - scrollBarLength;

            // Let Sl = scrollBarLength, St = scrollThumbLength, and T = spanLength.
            // Then St/Sl = Sl/T, so St = Sl^2/T.
            var scrollThumbLength = scrollBarLength * scrollBarLength / spanLength;

            // Clamp it so that the scroll thumb can only be as long as the scroll bar.
            scrollThumbLength = Math.Min(scrollThumbLength, scrollBarLength);

            if (vertical)
            {
                ScrollBarCollider   = new RectCollider(topLeft, scrollBarWidth, scrollBarLength);
                ScrollThumbCollider = new RectCollider(topLeft, scrollBarWidth, scrollThumbLength);
            }
            else
            {
                ScrollBarCollider   = new RectCollider(topLeft, scrollBarLength, scrollBarWidth);
                ScrollThumbCollider = new RectCollider(topLeft, scrollThumbLength, scrollBarWidth);
            }

            ClampThumbPosition();

            // Initialize the default values.

            ButtonToPress          = DefaultButtonToPress;
            ScrollActivateKey      = Vertical ? DefaultVerticalScrollActivateKey
                                              : DefaultHorizontalScrollActivateKey;

            JumpAmount             = DefaultJumpAmount;
            MouseWheelScrollAmount = DefaultMouseWheelScrollAmount;
            KeyboardScrollAmount = DefaultKeyboardScrollAmount;
            ScrollWheelDampener    = DefaultScrollWheelDamper;

            ScrollPlusKey          = Vertical ? DefaultVerticalScrollPlusKey
                                              : DefaultHorizontalScrollPlusKey;

            ScrollMinusKey         = Vertical ? DefaultVerticalScrollMinusKey
                                              : DefaultHorizontalScrollMinusKey;
        }
        public GUIButton(GUIButtonInfo info, Vector2 position, PositionType positionType = PositionType.Center)
            : base(null)
        {
            Info = info;
            Font = info.Font;

            ButtonSprite = new Sprite(info.Texture);
            var width = ButtonSprite.Width;
            var height = ButtonSprite.Height;
            var center = PositionConverter.ToCenter(position, width, height, positionType);

            ButtonSprite.CenterOn(center);

            Collider = new RectCollider(
                center - ButtonSprite.TextureCenter,
                ButtonSprite.Width, ButtonSprite.Height);

            TextPosition = center - Font.MeasureString(info.Text) / 2f + TextPositionOffset;
            TextColour = info.InitialTextColour.HasValue ? info.InitialTextColour.Value
                                                        : DefaultTextColour;
        }
        /// <summary>
        /// Check if this EllipseCollider is colliding with the given RectCollider.
        /// </summary>
        /// <param name="rect"></param>
        /// <returns></returns>
        public CollisionResponse CollidingWith(RectCollider rect)
        {
            bool result = false;

            // Check if this works first.
            /*
            if (A == B)
            {
                double rx = rect.X + rect.W / 2, ry = rect.Y + rect.H / 2;
                double x_offset = Math.Abs(X - rx);
                double y_offset = Math.Abs(Y - ry);
                double half_width = rect.W / 2;
                double half_height = rect.H / 2;

                if (x_offset > (half_width + A))
                    result = false;
                else if (y_offset > (half_height + A))
                    result = false;
                else
                {
                    if (x_offset <= half_width)
                        result = true;
                    else if (y_offset <= half_height)
                        result = true;
                    else
                    {
                        double deltax = x_offset - half_width;
                        double deltay = y_offset - half_height;
                        double dist = Math.Pow(deltax, 2) + Math.Pow(deltay, 2);
                        result = dist <= A * A ? true : false;
                    }
                }
            }
            else
            {
             */
            // For the math, see:
            //   http://www.geometrictools.com/Documentation/IntersectionRectangleEllipse.pdf

            // NOTE: Look into using the minkowski sum algorithm suggested there instead,
            // it looks substantially faster.
            var c = Center;
            var corners = rect.Coords;
            for (int i = 0; i < 4; i++)
            {
                if (EllipseUtils.EllipseOverlapSegment(c, A, B, corners[(i - 1) % 4], corners[i]))
                {
                    result = true;
                    break;
                }
            }
            result = rect.X <= X && X <= rect.X + rect.W &&
                     rect.Y <= Y && Y <= rect.Y + rect.H;
            /*}*/
            return new CollisionResponse(this, rect, result);
        }
 public RectCollider(RectCollider rect)
     : this(rect.X, rect.Y, rect.W, rect.H)
 {
 }
 /// <summary>
 /// Check if this RectCollider is colliding with the given RectCollider.
 /// </summary>
 /// <param name="rect"></param>
 /// <returns></returns>
 public CollisionResponse CollidingWith(RectCollider rect)
 {
     return new CollisionResponse(this, rect, RectUtils.Collision(
         X, Y, W, H, rect.X, rect.Y, rect.W, rect.H));
 }
        public InventoryButtonForm(TileType type, Vector2 topLeft, int quantity)
            : base(null, true)
        {
            Type = type;
            Sprite = new Sprite(GetTileTexture(type));
            ButtonSprite = new Sprite(Assets.Level.Images.InventoryButton);
            HoverSprite  = new Sprite(Assets.Level.Images.InventoryButtonHover);

            Collider = new RectCollider(topLeft, ButtonSprite.Width, ButtonSprite.Height);

            Quantity = quantity;
            QuantityFont = Assets.Level.Fonts.InventoryItem;
            QuantityTextPosition = ((RectCollider)Collider).Center + QUANTITY_TEXT_POS_OFFSET;
        }