#pragma once

#include "DiscretePoint.h"

struct BoundaryOffset
{
    bool operator==(const BoundaryOffset& rhs) const
    {
        return (mLeft == rhs.mLeft)
            && (mRight == rhs.mRight)
            && (mTop == rhs.mTop)
            && (mBottom == rhs.mBottom);
    }
    bool operator!=(const BoundaryOffset& rhs) const
    {
        return !operator==(rhs);
    }

    unsigned mLeft = 0;
    unsigned mRight = 0;
    unsigned mTop = 0;
    unsigned mBottom = 0;
};

struct BoundedSize
{
    bool operator==(const BoundedSize& rhs) const
    {
        return (mWidth == rhs.mWidth)
            && (mMaxWidth == rhs.mMaxWidth)
            && (mMinWidth == rhs.mMinWidth)
            && (mHeight == rhs.mHeight)
            && (mMaxHeight == rhs.mMaxHeight)
            && (mMinHeight == rhs.mMinHeight);
    }
    bool operator!=(const BoundedSize& rhs) const
    {
        return !operator==(rhs);
    }

    unsigned mWidth = 0;
    unsigned mMaxWidth = 0;
    unsigned mMinWidth = 0;
    unsigned mHeight = 0;
    unsigned mMaxHeight = 0;
    unsigned mMinHeight = 0;
};

class BoxGeometry
{
public:
    BoxGeometry();

    virtual ~BoxGeometry();

    bool contains(const DiscretePoint& loc) const;

    BoundedSize getSize() const;

    const DiscretePoint& getLocation() const;

    void setWidth(unsigned width);

    void setHeight(unsigned height);

    void setMaxHeight(unsigned maxHieght);

    void setBounds(unsigned width, unsigned height);

    void setSize(const BoundedSize& size);

    void setMaxWidth(unsigned maxWidth);

    void setMargin(unsigned margin);

    void setMargin(const BoundaryOffset& margin);

    void setPadding(unsigned padding);

    void setPadding(const BoundaryOffset& padding);

    void setLocation(const DiscretePoint& loc);

protected:
    DiscretePoint mLocation;
    BoundedSize mSize;
    BoundaryOffset mPadding;
    BoundaryOffset mMargin;

    bool mTransformDirty{ true };
};
