/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek 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:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * 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.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * HOLDER OR 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.
 *
 *****************************************************************************/

/*----------------------------------------------------------------------------*/
/*! @file u_wgl_rect.h 
 *  $RCSfile: $
 *  $Revision: #1 $
 *  $Date: 2015/05/29 $
 *  $Author: brianpc.huang $
 *  
 *  @par Description:
 *         This header file contains public interfaces, constant and type 
 *         definitions of the Widget Library.
 */
/*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/*! @addtogroup groupMW_WGL
 *  @{ 
 */
/*----------------------------------------------------------------------------*/
 
#ifndef _U_WGL_RECT_H_
#define _U_WGL_RECT_H_

/*-----------------------------------------------------------------------------
                    include files
 ----------------------------------------------------------------------------*/
#include "u_common.h"
#include "u_gl.h"

#ifdef __cplusplus
extern "C" {
#endif

/*-----------------------------------------------------------------------------
                    macros, defines, typedefs, enums
 ----------------------------------------------------------------------------*/
#define WGL_RECT_GET_WIDTH(pt_rect)                                                                     \
        (((pt_rect)->i4_right > (pt_rect)->i4_left) ?                                                   \
                                                ((pt_rect)->i4_right - (pt_rect)->i4_left) :            \
                                                ((pt_rect)->i4_left - (pt_rect)->i4_right))    /**<   get rectangle's width,  
                                                                                                                                                                                pt_rect is GL_RECT_T pointer,can not be NULL   */

#define WGL_RECT_GET_HEIGHT(pt_rect)                                                                    \
        (((pt_rect)->i4_bottom > (pt_rect)->i4_top) ?                                                   \
                                                ((pt_rect)->i4_bottom - (pt_rect)->i4_top) :            \
                                                ((pt_rect)->i4_top - (pt_rect)->i4_bottom))     /**<   get rectangle's height, 
                                                                                                                                                                                pt_rect is GL_RECT_T pointer,can not be NULL   */

#define WGL_RECT_SET(pt_rect, left, top, right, bottom)                                         \
        {                                                                                       \
                (pt_rect)->i4_left = ((left) < (right)) ? (left) : (right);                     \
                (pt_rect)->i4_right = ((left) < (right)) ? (right) : (left);                    \
                (pt_rect)->i4_top = ((top) < (bottom)) ? (top) : (bottom);                      \
                (pt_rect)->i4_bottom = ((top) < (bottom)) ? (bottom) : (top);                   \
        }    /**<   set rectangle's value,  
                                pt_rect is GL_RECT_T pointer, can not be NULL ,
                                left, top, right, bottom is INT32 value  */

#define WGL_RECT_SET_BY_SIZE(pt_rect, left, top, width, height)                                 \
        {                                                                                       \
                (pt_rect)->i4_left = ((width) > 0) ? (left) : ((left) + (width));               \
                (pt_rect)->i4_right = ((width) > 0) ? ((left) + (width)) : (left);              \
                (pt_rect)->i4_top = ((height) > 0) ? (top) : ((top) + (height));                \
                (pt_rect)->i4_bottom = ((height) > 0) ? ((top) + (height)) : (top);             \
        }    /**<        */

#define WGL_RECT_COPY(pt_dest_rect, pt_src_rect)                                                \
        {                                                                                       \
                (pt_dest_rect)->i4_left = (pt_src_rect)->i4_left;                               \
                (pt_dest_rect)->i4_right = (pt_src_rect)->i4_right;                             \
                (pt_dest_rect)->i4_top = (pt_src_rect)->i4_top;                                 \
                (pt_dest_rect)->i4_bottom = (pt_src_rect)->i4_bottom;                           \
        }    /**<        */

#define WGL_RECT_INFLATE(pt_rect, i4_cx, i4_cy)                                                 \
        {                                                                                       \
                (pt_rect)->i4_right += i4_cx;                                                   \
                (pt_rect)->i4_bottom += i4_cy;                                                  \
        }    /**<        */

#define WGL_RECT_OFFSET(pt_rect, i4_x, i4_y)                                                    \
        {                                                                                       \
                (pt_rect)->i4_left += i4_x;                                                     \
                (pt_rect)->i4_right += i4_x;                                                    \
                (pt_rect)->i4_top += i4_y;                                                      \
                (pt_rect)->i4_bottom += i4_y;                                                   \
        }    /**<        */

#define WGL_RECT_INSET(pt_rect,i4_l,i4_t,i4_r,i4_b)                                             \
        {                                                                                       \
                (pt_rect)->i4_left += i4_l;                                                     \
                (pt_rect)->i4_right -= i4_r;                                                    \
                (pt_rect)->i4_top += i4_t;                                                      \
                (pt_rect)->i4_bottom -= i4_b;                                                   \
        }    /**<        */

#define WGL_RECT_INSET_W_CHECK(pt_rect,i4_l,i4_t,i4_r,i4_b)                                     \
        {                                                                                       \
                (pt_rect)->i4_left += i4_l;                                                     \
                (pt_rect)->i4_right -= i4_r;                                                    \
                (pt_rect)->i4_top += i4_t;                                                      \
                (pt_rect)->i4_bottom -= i4_b;                                                   \
                (pt_rect)->i4_right = (((pt_rect)->i4_left) >= ((pt_rect)->i4_right)) ? ((pt_rect)->i4_left) : ((pt_rect)->i4_right);  \
                (pt_rect)->i4_bottom = (((pt_rect)->i4_top) >= ((pt_rect)->i4_bottom)) ? ((pt_rect)->i4_top) : ((pt_rect)->i4_bottom); \
        }    /**<        */


#define WGL_RECT_EMPTY(pt_rect)                                                                 \
        {                                                                                       \
                (pt_rect)->i4_left = 0;                                                         \
                (pt_rect)->i4_right = 0;                                                        \
                (pt_rect)->i4_top = 0;                                                          \
                (pt_rect)->i4_bottom = 0;                                                       \
        }    /**<        */
        
#define WGL_RECT_NORMALIZE(pt_rect)                                                             \
        {                                                                                       \
            INT32   i4_temp;                                                                    \
                                                                                                \
            if((pt_rect)->i4_left > (pt_rect)->i4_right)                                        \
            {                                                                                   \
                i4_temp = (pt_rect)->i4_left;                                                   \
                (pt_rect)->i4_left = (pt_rect)->i4_right;                                       \
                (pt_rect)->i4_right = i4_temp;                                                  \
            }                                                                                   \
                                                                                                \
            if((pt_rect)->i4_top > (pt_rect)->i4_bottom)                                        \
            {                                                                                   \
                i4_temp = (pt_rect)->i4_top;                                                    \
                (pt_rect)->i4_top = (pt_rect)->i4_bottom;                                       \
                (pt_rect)->i4_bottom = i4_temp;                                                 \
            }                                                                                   \
        }    /**<        */

#define WGL_RECT_IS_EQUAL(pt_rect1, pt_rect2)                                                   \
        ( ((pt_rect1)->i4_left == (pt_rect2)->i4_left)                                          \
                && ((pt_rect1)->i4_right == (pt_rect2)->i4_right)                               \
                && ((pt_rect1)->i4_top == (pt_rect2)->i4_top)                                   \
                && ((pt_rect1)->i4_bottom == (pt_rect2)->i4_bottom))    /**<        */
                
#define WGL_RECT_IS_EMPTY(pt_rect)                                                              \
        ( ((pt_rect)->i4_left == (pt_rect)->i4_right)                                           \
                || ((pt_rect)->i4_top == (pt_rect)->i4_bottom) )    /**<        */

#define WGL_RECT_IS_INCLUDED(pt_container, pt_rect)                                             \
        ( !(((pt_rect)->i4_left < (pt_container)->i4_left)                                      \
                || ((pt_rect)->i4_right > (pt_container)->i4_right)                             \
                || ((pt_rect)->i4_top < (pt_container)->i4_top)                                 \
                || ((pt_rect)->i4_bottom > (pt_container)->i4_bottom)) )    /**<        */

#define WGL_RECT_IS_PT_INCLUDED(pt_rect_container, pt_point)                            \
        ( ((pt_point)->i4_x >= (pt_rect_container)->i4_left)                            \
                && ((pt_point)->i4_x <= (pt_rect_container)->i4_right)                  \
                && ((pt_point)->i4_y >= (pt_rect_container)->i4_top)                    \
                && ((pt_point)->i4_y <= (pt_rect_container)->i4_bottom) )    /**<        */

#define WGL_RECT_VT_IS_OVERLAP(pt_rect1, pt_rect2)                                             \
        ( !(((pt_rect1)->i4_top > (pt_rect2)->i4_bottom)                                           \
                || ((pt_rect1)->i4_bottom < (pt_rect2)->i4_top)) )    /**<        */

#define WGL_INTERSECT_RECT(rc_out, rc1, rc2)                                \
    do {                                                                \
        (rc_out)->i4_left   = MAX((rc1)->i4_left, (rc2)->i4_left);      \
        (rc_out)->i4_right  = MIN((rc1)->i4_right, (rc2)->i4_right);    \
        (rc_out)->i4_top    = MAX((rc1)->i4_top, (rc2)->i4_top);        \
        (rc_out)->i4_bottom = MIN((rc1)->i4_bottom, (rc2)->i4_bottom);  \
    } while (0)    /**< intersect two rectangles as rc_out */


#define WGL_RECT_OVERLAPPED(rc1, rc2)                                                       \
        ((!RECT_EMPTY(rc1)) &&                                                              \
         (!RECT_EMPTY(rc2)) &&                                                              \
         (((((rc1)->i4_left >= (rc2)->i4_left) && ((rc1)->i4_left < (rc2)->i4_right))  ||   \
           (((rc1)->i4_right > (rc2)->i4_left) && ((rc1)->i4_right <= (rc2)->i4_right))) && \
          ((((rc1)->i4_top >= (rc2)->i4_top) && ((rc1)->i4_top < (rc2)->i4_bottom))     ||  \
           (((rc1)->i4_bottom > (rc2)->i4_top) && ((rc1)->i4_bottom <= (rc2)->i4_bottom)))))    /**< check if two rectangles overlap */


/*-----------------------------------------------------------------------------
                    structures
 ----------------------------------------------------------------------------*/


/*-----------------------------------------------------------------------------
                    functions
 ----------------------------------------------------------------------------*/

#ifdef __cplusplus
}
#endif

#endif

/*----------------------------------------------------------------------------*/
/*! @} */   /* end of  groupMW_WGL*/
/*----------------------------------------------------------------------------*/


