/*******************************************************************************/
/*** Routines graphiques de calcul et routines auxilaires                    ***/
/*** écrit par David Rouchet Copyright © David Rouchet 1993-1999             ***/
/*******************************************************************************/

#ifndef __GRAPHICSUSER_H
#define __GRAPHICSUSER_H

#include <vcl.h>

template <class T> inline void GUExchange(T *a, T *b) {T __iTemp = *a; *a=*b; *b=__iTemp;};
template <class T> inline T GUMin(T a, T b) {return (a<b) ? a : b;};
template <class T> inline T GUMax(T a, T b) {return (a>b) ? a : b;};
template <class T> inline T GUMin3(T a, T b, T c) {return GUMin(GUMin(a, b), c);};

inline Graphics::TColor GUMakeColor(BYTE byRed, BYTE byGreen, BYTE byBlue)
    {return (Graphics::TColor)(MAKELONG(MAKEWORD(byRed, byGreen), MAKEWORD(byBlue, 0)));}
inline BYTE GUGetRed(Graphics::TColor Color) {return (BYTE)(LOBYTE(LOWORD((DWORD)Color)));}
inline BYTE GUGetGreen(Graphics::TColor Color) {return (BYTE)(HIBYTE(LOWORD((DWORD)Color)));}
inline BYTE GUGetBlue(Graphics::TColor Color) {return (BYTE)(LOBYTE(HIWORD((DWORD)Color)));}

inline bool GURectContains(TRect Rect, int iX, int iY)
    {return ((iX>=Rect.Left) && (iX<=Rect.Right))&&((iY>=Rect.Top) && (iY<=Rect.Bottom));}

inline bool GURectContains(TRect Rect, TRect ContainedRect)
    {return ((ContainedRect.Left>=Rect.Left) && (ContainedRect.Top>=Rect.Top) && (ContainedRect.Right<=Rect.Right) && (ContainedRect.Bottom<=Rect.Bottom));}

inline void GURectSet(TRect& Rect, int iX1, int iY1, int iX2, int iY2)
    { Rect.Left=iX1; Rect.Top=iY1; Rect.Right=iX2; Rect.Bottom=iY2;}

inline void GURectCopy(TRect RectFrom, TRect& RectTo)
    {RectTo.Left=RectFrom.Left; RectTo.Top=RectFrom.Top; RectTo.Right=RectFrom.Right; RectTo.Bottom=RectFrom.Bottom;}

inline void GURectInflate(TRect& Rect, int iInflate)
    {Rect.Left-=iInflate; Rect.Top-=iInflate; Rect.Right+=iInflate; Rect.Bottom+=iInflate;}

template <class T> inline bool GUIsObjectContainsPoint(T *lpObject, TPoint P)
    {return ((P.x>=lpObject->Left) && (P.x<=lpObject->Left+lpObject->Width)\
        && (P.y>=lpObject->Top) && (P.y<=lpObject->Top+lpObject->Height))};

template <class T> inline void GUGetObjectRect(T *lpObject, TRect& Rect)
    {Rect.Left=lpObject->Left; Rect.Top=lpObject->Top; Rect.Right=lpObject->Left+lpObject->Width; Rect.Bottom=lpObject->Top+lpObject->Height;};

inline void GURectOffset(TRect& Rect, int iOffset)
    {Rect.Left+=iOffset; Rect.Top+=iOffset; Rect.Right+=iOffset; Rect.Bottom+=iOffset;}

inline void GUUnionRect(TRect& Rect, TRect RectA, TRect RectB)
    {Rect.Left = RectA.Left<RectB.Left ? RectA.Left : RectB.Left;
     Rect.Top = RectA.Top<RectB.Top ? RectA.Top : RectB.Top;
     Rect.Right = RectA.Right<RectB.Right ? RectB.Right : RectA.Right;
     Rect.Bottom = RectA.Bottom<RectB.Bottom ? RectB.Bottom : RectA.Bottom;}

inline bool GURectCompare(TRect Rect1, TRect Rect2)
    {return ((Rect1.Left!=Rect2.Left) || (Rect1.Top!=Rect2.Top) || (Rect1.Right!=Rect2.Right) || (Rect1.Bottom!=Rect2.Bottom));}


inline Graphics::TColor GUGetInvertedColor(Graphics::TColor Color, Graphics::TColor& IColor)
    {return IColor=(Graphics::TColor)MAKELONG(MAKEWORD(0xFF-LOBYTE(LOWORD(Color)), 0xFF-HIBYTE(LOWORD(Color))),
                                       MAKEWORD(0xFF-LOBYTE(HIWORD(Color)), HIBYTE(HIWORD(Color))));}

inline Graphics::TColor GUGetIntermediateColor(Graphics::TColor ColorFrom, Graphics::TColor ColorTo, int iSurfaceWidth, int iCurrentPos)
{
    if (iSurfaceWidth<2) return GUMakeColor(0, 0, 0);
    iSurfaceWidth--;
    BYTE byRedIndex     = (BYTE)(GUGetRed(ColorFrom) + ((iCurrentPos*(GUGetRed(ColorTo)-GUGetRed(ColorFrom)))/iSurfaceWidth));
    BYTE byGreenIndex   = (BYTE)(GUGetGreen(ColorFrom) + ((iCurrentPos*(GUGetGreen(ColorTo)-GUGetGreen(ColorFrom)))/iSurfaceWidth));
    BYTE byBlueIndex    = (BYTE)(GUGetBlue(ColorFrom) + ((iCurrentPos*(GUGetBlue(ColorTo)-GUGetBlue(ColorFrom)))/iSurfaceWidth));
    return  GUMakeColor(byRedIndex, byGreenIndex, byBlueIndex);
}

inline Graphics::TColor GUGetHightLightColor(Graphics::TColor Color)
{
    return GUMakeColor((BYTE)((GUGetRed(Color)*2)/3), (BYTE)((GUGetGreen(Color)*2)/3), (BYTE)((GUGetBlue(Color)*2)/3));
}

inline Graphics::TColor GUGetShadowColor(Graphics::TColor Color)
{
    BYTE byMinColor = GUMin(GUMin(GUGetRed(Color), GUGetGreen(Color)), GUGetBlue(Color));
	BYTE byDelta    = (BYTE)(235-byMinColor);
    return GUMakeColor((BYTE)(GUMin((GUGetRed(Color)+byDelta) , 255)), (BYTE)(GUMin((GUGetGreen(Color)+byDelta), 255)), (BYTE)(GUMin( (GUGetBlue(Color)+byDelta),255)));
}

#endif

