/*
 * Copyright (C) 2003, 2006, 2009 Apple Inc. All rights reserved.
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef SKY_ENGINE_PLATFORM_GEOMETRY_ROUNDEDRECT_H_
#define SKY_ENGINE_PLATFORM_GEOMETRY_ROUNDEDRECT_H_

#include "sky/engine/platform/geometry/FloatQuad.h"
#include "sky/engine/platform/geometry/IntRect.h"

namespace blink {

// This class is used to represent rectangles with rounded corners. It is only
// used for painting. It uses integer units because using layout units leads to
// blurry rounded corners.
class PLATFORM_EXPORT RoundedRect {
public:
    class PLATFORM_EXPORT Radii {
    public:
        Radii() { }
        Radii(const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight)
            : m_topLeft(topLeft)
            , m_topRight(topRight)
            , m_bottomLeft(bottomLeft)
            , m_bottomRight(bottomRight)
        {
        }

        void setTopLeft(const IntSize& size) { m_topLeft = size; }
        void setTopRight(const IntSize& size) { m_topRight = size; }
        void setBottomLeft(const IntSize& size) { m_bottomLeft = size; }
        void setBottomRight(const IntSize& size) { m_bottomRight = size; }
        const IntSize& topLeft() const { return m_topLeft; }
        const IntSize& topRight() const { return m_topRight; }
        const IntSize& bottomLeft() const { return m_bottomLeft; }
        const IntSize& bottomRight() const { return m_bottomRight; }

        bool isZero() const;

        void includeLogicalEdges(const Radii& edges, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);

        void scale(float factor);
        void expand(int topWidth, int bottomWidth, int leftWidth, int rightWidth);
        void expand(int size) { expand(size, size, size, size); }
        void shrink(int topWidth, int bottomWidth, int leftWidth, int rightWidth) { expand(-topWidth, -bottomWidth, -leftWidth, -rightWidth); }
        void shrink(int size) { shrink(size, size, size, size); }

    private:
        IntSize m_topLeft;
        IntSize m_topRight;
        IntSize m_bottomLeft;
        IntSize m_bottomRight;
    };

    explicit RoundedRect(const IntRect&, const Radii& = Radii());
    RoundedRect(int x, int y, int width, int height);
    RoundedRect(const IntRect&, const IntSize& topLeft, const IntSize& topRight, const IntSize& bottomLeft, const IntSize& bottomRight);

    const IntRect& rect() const { return m_rect; }
    const Radii& radii() const { return m_radii; }
    bool isRounded() const { return !m_radii.isZero(); }
    bool isEmpty() const { return m_rect.isEmpty(); }

    // Returns a quickly computed rect enclosed by the rounded rect.
    IntRect radiusCenterRect() const;

    void setRect(const IntRect& rect) { m_rect = rect; }
    void setRadii(const Radii& radii) { m_radii = radii; }

    void move(const IntSize& size) { m_rect.move(size); }
    void inflate(int size) { m_rect.inflate(size);  }
    void inflateWithRadii(int size);
    void expandRadii(int size) { m_radii.expand(size); }
    void shrinkRadii(int size) { m_radii.shrink(size); }

    void includeLogicalEdges(const Radii& edges, bool includeLogicalLeftEdge, bool includeLogicalRightEdge);

    bool isRenderable() const;
    void adjustRadii();

    // Tests whether the quad intersects any part of this rounded rectangle.
    // This only works for convex quads.
    bool intersectsQuad(const FloatQuad&) const;

private:
    IntRect m_rect;
    Radii m_radii;
};

inline bool operator==(const RoundedRect::Radii& a, const RoundedRect::Radii& b)
{
    return a.topLeft() == b.topLeft() && a.topRight() == b.topRight() && a.bottomLeft() == b.bottomLeft() && a.bottomRight() == b.bottomRight();
}

inline bool operator!=(const RoundedRect::Radii& a, const RoundedRect::Radii& b)
{
    return !(a == b);
}

inline bool operator==(const RoundedRect& a, const RoundedRect& b)
{
    return a.rect() == b.rect() && a.radii() == b.radii();
}


} // namespace blink

#endif  // SKY_ENGINE_PLATFORM_GEOMETRY_ROUNDEDRECT_H_
