/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_UI_RECT
#define ANDROID_UI_RECT

#include <utils/TypeHelpers.h>
#include <ui/Point.h>

namespace android {

class Rect
{
public:
    int left;
    int top;
    int right;
    int bottom;

    // we don't provide copy-ctor and operator= on purpose
    // because we want the compiler generated versions

    inline Rect()
    {
    }

    inline Rect(int w, int h)
        : left(0), top(0), right(w), bottom(h)
    {
    }

    inline Rect(int l, int t, int r, int b)
        : left(l), top(t), right(r), bottom(b)
    {
    }

    inline Rect(const Point& lt, const Point& rb) 
        : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y)
    {
    }

    void makeInvalid();
    
    // a valid rectangle has a non negative width and height
    inline bool isValid() const {
        return (width()>=0) && (height()>=0);
    }

    // an empty rect has a zero width or height, or is invalid
    inline bool isEmpty() const {
        return (width()<=0) || (height()<=0);
    }

    inline void set(const Rect& rhs) {
        operator = (rhs);
    }

    // rectangle's width
    inline int width() const {
        return right-left;
    }
    
    // rectangle's height
    inline int height() const {
        return bottom-top;
    }

    // returns left-top Point non-const reference, can be assigned
    inline Point& leftTop() {
        return reinterpret_cast<Point&>(left);
    }
    // returns right bottom non-const reference, can be assigned
    inline Point& rightBottom() {
        return reinterpret_cast<Point&>(right);
    }
    
    // the following 4 functions return the 4 corners of the rect as Point
    inline const Point& leftTop() const {
        return reinterpret_cast<const Point&>(left);
    }
    inline const Point& rightBottom() const {
        return reinterpret_cast<const Point&>(right);
    }
    Point rightTop() const {
        return Point(right, top);
    }
    Point leftBottom() const {
        return Point(left, bottom);
    }

    // comparisons
    inline bool operator == (const Rect& rhs) const {
        return (left == rhs.left) && (top == rhs.top) &&
               (right == rhs.right) && (bottom == rhs.bottom);
    }

    inline bool operator != (const Rect& rhs) const {
        return !operator == (rhs);
    }

    // operator < defines an order which allows to use rectangles in sorted
    // vectors.
    bool operator < (const Rect& rhs) const;

    Rect& offsetToOrigin() {
        right -= left;
        bottom -= top;
        left = top = 0;
        return *this;
    }
    Rect& offsetTo(const Point& p) {
        return offsetTo(p.x, p.y);
    }
    Rect& offsetBy(const Point& dp) {
        return offsetBy(dp.x, dp.y);
    }
    Rect& operator += (const Point& rhs) {
        return offsetBy(rhs.x, rhs.y);
    }
    Rect& operator -= (const Point& rhs) {
        return offsetBy(-rhs.x, -rhs.y);
    }
    Rect operator + (const Point& rhs) const;
    Rect operator - (const Point& rhs) const;

    void translate(int dx, int dy) { // legacy, don't use.
        offsetBy(dx, dy);
    }
 
    Rect&   offsetTo(int x, int y);
    Rect&   offsetBy(int x, int y);
    bool    intersect(const Rect& with, Rect* result) const;
};

ANDROID_BASIC_TYPES_TRAITS(Rect)

}; // namespace android

#endif // ANDROID_UI_RECT
