/******************************************************************

  Module: TiBoxDraw.cpp

  Author: Jon Wiesman

  Description:

    2D box drawing class

  Copyright 2004 Sony Online Entertainment.  All rights reserved.

*******************************************************************/

#include "TiBoxDraw.h"
#include "SyResourceID.h"
#include "SyString.h"
#include "TiUI.h"
#include "string.h"

TiBoxDraw::TiBoxDraw()
{
    for(int i = 0; i < BDP_MAX; ++i)
    {
        m_sizes[i].SetSize(0, 0);
    }
}

void TiBoxDraw::Initialize(const char8 *pszBase)
{
    const char8* pszPieces[] = {
        "TL", "Top", "TR", "Right", "BR", "Bottom", "BL", "Left", "Tile",
    };

    char8 szPiece[100] = "";
    for(int i = 0; i < BDP_MAX; ++i)
    {
        strcpy(szPiece, pszBase);
        strcat(szPiece, pszPieces[i]);

        m_spr[i].SetInfo(SyHashResourceID(szPiece));
        m_sizes[i] = m_spr[i].GetSize();
    }
    m_nInternalOffsetLeft = 0;
    m_nInternalOffsetTop = 0;
    m_nInternalOffsetRight = 0;
    m_nInternalOffsetBottom = 0;
}

TiRect TiBoxDraw::GetInternalRect(TiRect rectBox) const
{
    // this function is very similar to getting the piece rect for the middle piece
    // However, it is possible to have a boxdraw with ornate borders that are meant
    // to be encroached upon.  So this function is used by other content providers
    // to determine where to draw inside the rectangle
    TiRect rect = GetPieceRect(BDP_TILE, rectBox);
    rect.left -= m_nInternalOffsetLeft;
    rect.top -= m_nInternalOffsetTop;
    rect.right += m_nInternalOffsetRight;
    rect.bottom += m_nInternalOffsetBottom;
    return rect;
}

TiRect TiBoxDraw::GetPieceRect(EBoxDrawPiece ePiece, TiRect rectBox) const
{
    TiRect rect = rectBox;

    switch(ePiece)
    {
    case BDP_TL:
        return TiRect(rect.TopLeft(), m_sizes[BDP_TL]);

    case BDP_TOP:
        rect.left = rectBox.left + m_sizes[BDP_TL].cx;
        rect.right = rectBox.right - m_sizes[BDP_TR].cx;
        rect.bottom = rectBox.top + m_sizes[BDP_TOP].cy;
        return rect;

    case BDP_TR:
        rect.left = rectBox.right - m_sizes[BDP_TR].cx;
        rect.bottom = rectBox.top + m_sizes[BDP_TR].cy;
        return rect;

    case BDP_RIGHT:
        rect.left = rectBox.right - m_sizes[BDP_RIGHT].cx;
        rect.top = rectBox.top + m_sizes[BDP_TR].cy;
        rect.bottom = rectBox.bottom - m_sizes[BDP_BR].cy;
        return rect;

    case BDP_BR:
        rect.left = rectBox.right - m_sizes[BDP_BR].cx;
        rect.top = rectBox.bottom - m_sizes[BDP_BR].cy;
        return rect;

    case BDP_BOTTOM:
        rect.top = rectBox.bottom - m_sizes[BDP_BOTTOM].cy;
        rect.right = rectBox.right - m_sizes[BDP_BR].cx;
        rect.left = rectBox.left + m_sizes[BDP_BL].cx;
        return rect;

    case BDP_BL:
        rect.top = rectBox.bottom - m_sizes[BDP_BL].cy;
        rect.right = rectBox.left + m_sizes[BDP_BL].cx;
        return rect;

    case BDP_LEFT:
        rect.right = rectBox.left + m_sizes[BDP_LEFT].cx;
        rect.top = rectBox.top + m_sizes[BDP_TL].cy;
        rect.bottom = rectBox.bottom - m_sizes[BDP_BL].cy;
        return rect;

    case BDP_TILE:
        rect.left = rectBox.left + m_sizes[BDP_LEFT].cx;
        rect.top = rectBox.top + m_sizes[BDP_TOP].cy;
        rect.right = rectBox.right - m_sizes[BDP_RIGHT].cx;
        rect.bottom = rectBox.bottom - m_sizes[BDP_BOTTOM].cy;
        return rect;

    case BDP_MAX:
        break;
    }

    return TiRect(0, 0, -1, -1);
}

void TiBoxDraw::Draw(TiRect rectBox, TiRect rectClip, float fOpacity) const
{
    if(rectBox.IsAbnormal())
        return;

    // do "TILE" piece first
    TiRect rect;

    // do remaining pieces
    for(int i = BDP_TILE; i >= 0; --i)
    {
        rect = GetPieceRect( static_cast< EBoxDrawPiece >( i ), rectBox);
        if(CanStretchPiece(static_cast< EBoxDrawPiece >( i )))
            m_spr[i].Stretch(rect, rectClip, fOpacity);
        else
            m_spr[i].Tile(rect, rectClip, fOpacity);
    }
}

void TiBoxDraw::DrawWithFill(TiRect rectBox, SyColor32F crFill, TiRect rectClip /* = c_rectPS3Screen */, float fOpacity /* = 1.0f */) const
{
  TiRect rect = GetInternalRect(rectBox);

  crFill.A = fOpacity;
  TiUI::Instance()->FillRectangle(rect, crFill);
  Draw(rectBox, rectClip, fOpacity);
}


