/*--------------------------------------------------------------------------
  Project:  Manual 2D Library - m2d
  File:     m2d_scrollIndicator.cpp

  Copyright (C)2007-2009 Nintendo  All Rights Reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law. They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Revision: 1758 $
 *-------------------------------------------------------------------------*/

#include <ntmv/m2d/inlines.h>
#include <ntmv/m2d/graphicDefines.h>
#include <ntmv/m2d/uiResDefines.h>
#include <ntmv/m2d/Rect.h>
#include <ntmv/m2d/objectConstructor.h>
#include <ntmv/m2d/objG2dInfo.h>
#include <ntmv/m2d/uiStatic.h>
#include <ntmv/m2d/scrollIndicator.h>
#include <ntmv/m2d/nlv_skin_up_obj_NANR_LBLDEFS.h>

namespace ntmv
{
namespace m2d
{

namespace
{

const s16   MOVE_SPEEDY     = 2;

// Margin from the end of the scroll indicator
// Move using a cell animation for this number of pixels.
const s16   CELL_MARGEIN    = 2;

#if 0
/*---------------------------------------------------------------------------*
  Name:         UpdateButtonOffsetY

  Description:  Updates the y-offset position for displaying buttons.

  Arguments:    offsetY:  Current y-offset value.
                visible:  TRUE when the button is displayed.

  Returns:      Returns the updated y-offset value.
 *---------------------------------------------------------------------------*/
s16
UpdateButtonOffsetY(
    s16     offsetY,
    bool    visible
)
{
    return static_cast<s16>(visible ?
        Max(0, offsetY - MOVE_SPEEDY):
        Min(int(detail::SCROLLINDICATOR_HEIGHT), offsetY + MOVE_SPEEDY));
}
#endif

}   // namespace

/*---------------------------------------------------------------------------*
  Name:         ScrollIndicator::ScrollIndicator

  Description:  Constructor.

  Arguments:    None.

  Returns:      None.
 *---------------------------------------------------------------------------*/
ScrollIndicator::ScrollIndicator()
:   mContentHeight(0),
    mViewHeight(0),
    mViewY(0)
{
}

/*---------------------------------------------------------------------------*
  Name:         ScrollIndicator::Init

  Description:  Performs initialization.

  Arguments:    objectConstructor: A reference to an ObjectConstructor object.
                pOamManager:       A pointer to an ObjManager object.
                position:          Display position (center).
                height:            Height of the indicator itself.
                viewHeight:        Height of the display area.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
ScrollIndicator::Init(
    const ObjectConstructor&    objectConstructor,
    ObjManager*                 pObjManager,
    Point                       position,
    s16                         height,
    s16                         viewHeight,
    const u16                   cellIdxAry[]
)
{
    UIElement* elements[UI_MAX];

    for (int i = 0; i < UI_MAX; ++i)
    {
        UIStatic* pButton = objectConstructor.NewObj<UIStatic>();
        NNS_NULL_ASSERT(pButton);
        pButton->Init(
            Point(0, 0),
            Size(detail::SCROLLINDICATOR_WIDTH, detail::SCROLLINDICATOR_HEIGHT),
            pObjManager->CreateCellAnim(cellIdxAry[i]));
        elements[i] = pButton;
    }

    Base::Init(
        objectConstructor,
        elements,
        UI_MAX,
        position,
        Size(detail::SCROLLINDICATOR_WIDTH, height));

    SetHeight(height);

    mViewHeight = viewHeight;

    for (int i = 0; i < UI_MAX; ++i)
    {
        mOffsetYs[i] = detail::SCROLLINDICATOR_HEIGHT;
    }
}

/*---------------------------------------------------------------------------*
  Name:         ScrollIndicator::SetHeight

  Description:  Sets the height of the scroll indicator controller.

  Arguments:    height: Height of the scroll indicator controller.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
ScrollIndicator::SetHeight(s16 height)
{
    s16 posY = detail::SCROLLINDICATOR_HEIGHT / 2;
    s16 initPosY[UI_MAX] =
    {
        static_cast<s16>(- height / 2 + posY + CELL_MARGEIN),
        static_cast<s16>(height - height / 2 - (detail::SCROLLINDICATOR_HEIGHT - posY) - CELL_MARGEIN),
    };

    for (int i = 0; i < UI_MAX; ++i)
    {
        Point pos = mElements[i]->GetPosition();
        pos.y = initPosY[i];
        mElements[i]->SetPosition(pos);
    }
}

/*---------------------------------------------------------------------------*
  Name:         ScrollIndicator::UpdateViewY

  Description:  Set the display position (y-coordinate) for the content.

  Arguments:    viewY:  y-coordinate of the content's display position.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
ScrollIndicator::UpdateViewY(s16 viewY)
{
    mViewY = viewY;
}

/*---------------------------------------------------------------------------*
  Name:         ScrollIndicator::Animate

  Description:  Updates the animation state.

  Arguments:    pObjManager: A pointer to an ObjManager object.

  Returns:      None.
 *---------------------------------------------------------------------------*/
void
ScrollIndicator::Animate(ObjManager* pObjManager)
{
#if 0
    // Update the position to display the Up button
    {
        Point pos = mElements[BUTTON_UP]->GetPosition();
        mOffsetYs[BUTTON_UP] = UpdateButtonOffsetY(mOffsetYs[BUTTON_UP], mViewY > 0);
        pos.y = static_cast<s16>(0 - mOffsetYs[BUTTON_UP]);
        mElements[BUTTON_UP]->SetPosition(pos);
    }

    // Update the position to display the Down button
    {
        Point pos = mElements[BUTTON_DOWN]->GetPosition();
        mOffsetYs[BUTTON_DOWN] = UpdateButtonOffsetY(
                        mOffsetYs[BUTTON_DOWN],
                        mViewY + mViewHeight < mContentHeight);
        pos.y = static_cast<s16>(mSize.height - detail::SCROLLINDICATOR_HEIGHT + mOffsetYs[BUTTON_DOWN]);
        mElements[BUTTON_DOWN]->SetPosition(pos);
    }
#else
    // Update the cell animation.
    static_cast<UIStatic*>(mElements[BUTTON_UP])->Animate(pObjManager);
    static_cast<UIStatic*>(mElements[BUTTON_DOWN])->Animate(pObjManager);

    mElements[BUTTON_UP]->SetVisible(mViewY > 0);
    mElements[BUTTON_DOWN]->SetVisible(mViewY + mViewHeight < mContentHeight);
#endif
}

}   // namespace m2d
}   // namespace ntmv
