/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"

#include "PresenterScrollBar.hxx"
#include "PresenterBitmapContainer.hxx"
#include "PresenterCanvasHelper.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterPaintManager.hxx"
#include "PresenterTimer.hxx"
#include "PresenterUIPainter.hxx"
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/awt/XToolkit.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/weak_ptr.hpp>
#include <math.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using ::rtl::OUString;

#define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))

const static double gnScrollBarGap (10);

namespace sdext { namespace presenter {

//===== PresenterScrollBar::MousePressRepeater ================================

class PresenterScrollBar::MousePressRepeater
    : public ::boost::enable_shared_from_this<MousePressRepeater>
{
public:
    MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar);
    void Dispose (void);
    void Start (const PresenterScrollBar::Area& reArea);
    void Stop (void);
    void SetMouseArea (const PresenterScrollBar::Area& reArea);

private:
    void Callback (const TimeValue& rCurrentTime);
    void Execute (void);

    sal_Int32 mnMousePressRepeaterTaskId;
    ::rtl::Reference<PresenterScrollBar> mpScrollBar;
    PresenterScrollBar::Area meMouseArea;
};




//===== PresenterScrollBar ====================================================

boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps;

PresenterScrollBar::PresenterScrollBar (
    const Reference<XComponentContext>& rxComponentContext,
    const Reference<awt::XWindow>& rxParentWindow,
    const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
    const ::boost::function<void(double)>& rThumbMotionListener)
    : PresenterScrollBarInterfaceBase(m_aMutex),
      mxComponentContext(rxComponentContext),
      mxParentWindow(rxParentWindow),
      mxWindow(),
      mxCanvas(),
      mxPresenterHelper(),
      mpPaintManager(rpPaintManager),
      mnThumbPosition(0),
      mnTotalSize(0),
      mnThumbSize(0),
      mnLineHeight(10),
      maDragAnchor(-1,-1),
      maThumbMotionListener(rThumbMotionListener),
      meButtonDownArea(None),
      meMouseMoveArea(None),
      mbIsNotificationActive(false),
      mpBitmaps(),
      mpPrevButtonDescriptor(),
      mpNextButtonDescriptor(),
      mpPagerStartDescriptor(),
      mpPagerCenterDescriptor(),
      mpPagerEndDescriptor(),
      mpThumbStartDescriptor(),
      mpThumbCenterDescriptor(),
      mpThumbEndDescriptor(),
      mpMousePressRepeater(new MousePressRepeater(this)),
      mpBackgroundBitmap(),
      mpCanvasHelper(new PresenterCanvasHelper())
{
    try
    {
        Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager());
        if ( ! xFactory.is())
            throw RuntimeException();

        mxPresenterHelper = Reference<drawing::XPresenterHelper>(
            xFactory->createInstanceWithContext(
                OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
                rxComponentContext),
            UNO_QUERY_THROW);

        if (mxPresenterHelper.is())
            mxWindow = mxPresenterHelper->createWindow(rxParentWindow,
                sal_False,
                sal_False,
                sal_False,
                sal_False);

        // Make the background transparent.  The slide show paints its own background.
        Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW);
        if (xPeer.is())
        {
            xPeer->setBackground(0xff000000);
        }

        mxWindow->setVisible(sal_True);
        mxWindow->addWindowListener(this);
        mxWindow->addPaintListener(this);
        mxWindow->addMouseListener(this);
        mxWindow->addMouseMotionListener(this);
    }
    catch (RuntimeException&)
    {
    }
}




PresenterScrollBar::~PresenterScrollBar (void)
{
}




void SAL_CALL PresenterScrollBar::disposing (void)
{
    mpMousePressRepeater->Dispose();
    
    if (mxWindow.is())
    {
        mxWindow->removeWindowListener(this);
        mxWindow->removePaintListener(this);
        mxWindow->removeMouseListener(this);
        mxWindow->removeMouseMotionListener(this);
        
        Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY);
        mxWindow = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }

    mpBitmaps.reset();
}




void PresenterScrollBar::SetVisible (const bool bIsVisible)
{
    if (mxWindow.is())
        mxWindow->setVisible(bIsVisible);
}




void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox)
{
    if (mxWindow.is())
    {
        mxWindow->setPosSize(
            sal_Int32(floor(rBox.X1)),
            sal_Int32(ceil(rBox.Y1)),
            sal_Int32(ceil(rBox.X2-rBox.X1)),
            sal_Int32(floor(rBox.Y2-rBox.Y1)),
            awt::PosSize::POSSIZE);
        UpdateBorders();
    }
}




void PresenterScrollBar::SetThumbPosition (
    double nPosition,
    const bool bAsynchronousUpdate)
{
    SetThumbPosition(nPosition, bAsynchronousUpdate, true, true);
}




void PresenterScrollBar::SetThumbPosition (
    double nPosition,
    const bool bAsynchronousUpdate,
    const bool bValidate,
    const bool bNotify)
{
    if (bValidate)
        nPosition = ValidateThumbPosition(nPosition);

    if (nPosition != mnThumbPosition && ! mbIsNotificationActive)
    {
        mnThumbPosition = nPosition;

        UpdateBorders();
        Repaint(GetRectangle(Total), bAsynchronousUpdate);
        if (bNotify)
            NotifyThumbPositionChange();
    }
}




double PresenterScrollBar::GetThumbPosition (void) const
{
    return mnThumbPosition;
}




void PresenterScrollBar::SetTotalSize (const double nTotalSize)
{
    if (mnTotalSize != nTotalSize)
    {
        mnTotalSize = nTotalSize + 1;
        UpdateBorders();
        Repaint(GetRectangle(Total), false);
    }
}




double PresenterScrollBar::GetTotalSize (void) const
{
    return mnTotalSize;
}




void PresenterScrollBar::SetThumbSize (const double nThumbSize)
{
    OSL_ASSERT(nThumbSize>=0);
    if (mnThumbSize != nThumbSize)
    {
        mnThumbSize = nThumbSize;
        UpdateBorders();
        Repaint(GetRectangle(Total), false);
    }
}




double PresenterScrollBar::GetThumbSize (void) const
{
    return mnThumbSize;
}




void PresenterScrollBar::SetLineHeight (const double nLineHeight)
{
    mnLineHeight = nLineHeight;
}




double PresenterScrollBar::GetLineHeight (void) const
{
    return mnLineHeight;
}




void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas)
{
    if (mxCanvas != rxCanvas)
    {
        mxCanvas = rxCanvas;
        if (mxCanvas.is())
        {            
            if (mpBitmaps.get()==NULL)
            {
                if (mpSharedBitmaps.expired())
                {
                    try
                    {
                        mpBitmaps.reset(new PresenterBitmapContainer(
                            OUString::createFromAscii("PresenterScreenSettings/ScrollBar/Bitmaps"),
                            ::boost::shared_ptr<PresenterBitmapContainer>(),
                            mxComponentContext,
                            mxCanvas));
                        mpSharedBitmaps = mpBitmaps;
                    }
                    catch(Exception&)
                    {
                        OSL_ASSERT(false);
                    }
                }
                else
                    mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps);
                UpdateBitmaps();
                UpdateBorders();
            }

            Repaint(GetRectangle(Total), false);
        }
    }
}




void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap)
{
    mpBackgroundBitmap = rpBackgroundBitmap;
}



void PresenterScrollBar::CheckValues (void)
{
    mnThumbPosition = ValidateThumbPosition(mnThumbPosition);
}




double PresenterScrollBar::ValidateThumbPosition (double nPosition)
{
    if (nPosition + mnThumbSize > mnTotalSize)
        nPosition = mnTotalSize - mnThumbSize;
    if (nPosition < 0)
        nPosition = 0;
    return nPosition;
}




void PresenterScrollBar::Paint (
    const awt::Rectangle& rUpdateBox,
    const bool bNoClip)
{
    if ( ! mxCanvas.is() || ! mxWindow.is())
    {
        OSL_ASSERT(mxCanvas.is());
        OSL_ASSERT(mxWindow.is());
        return;
    }

    if ( ! bNoClip)
    {
        if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize()))
            return;
    }

    PaintBackground(rUpdateBox);
    PaintComposite(rUpdateBox, PagerUp,
        mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor());
    PaintComposite(rUpdateBox, PagerDown,
        SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor);
    PaintComposite(rUpdateBox, Thumb,
        mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor);
    PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor);
    PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor);

    Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
    if (xSpriteCanvas.is())
        xSpriteCanvas->updateScreen(sal_False);
}






//----- XWindowListener -------------------------------------------------------
    
void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    (void)rEvent;
}




   
void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    (void)rEvent;
}




void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent)
    throw (css::uno::RuntimeException)
{
    (void)rEvent;
}




void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent)
    throw (css::uno::RuntimeException)
{
    (void)rEvent;
}




//----- XPaintListener --------------------------------------------------------

void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    if (mxWindow.is())
    {
        awt::Rectangle aRepaintBox (rEvent.UpdateRect);
        const awt::Rectangle aWindowBox (mxWindow->getPosSize());
        aRepaintBox.X += aWindowBox.X;
        aRepaintBox.Y += aWindowBox.Y;
        Paint(aRepaintBox);

        Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
        if (xSpriteCanvas.is())
            xSpriteCanvas->updateScreen(sal_False);
    }
}



    
//----- XMouseListener --------------------------------------------------------

void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent)
    throw(css::uno::RuntimeException)
{
    maDragAnchor.X = rEvent.X;
    maDragAnchor.Y = rEvent.Y;
    meButtonDownArea = GetArea(rEvent.X, rEvent.Y);

    mpMousePressRepeater->Start(meButtonDownArea);
}




void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent)
    throw(css::uno::RuntimeException)
{
    (void)rEvent;

    mpMousePressRepeater->Stop();

    if (mxPresenterHelper.is())
        mxPresenterHelper->releaseMouse(mxWindow);
}




void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent)
    throw(css::uno::RuntimeException)
{
    (void)rEvent;
}




void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent)
    throw(css::uno::RuntimeException)
{
    (void)rEvent;
    if (meMouseMoveArea != None)
    {
        const Area eOldMouseMoveArea (meMouseMoveArea);
        meMouseMoveArea = None;
        Repaint(GetRectangle(eOldMouseMoveArea), true);
    }
    meButtonDownArea = None;
    meMouseMoveArea = None;

    mpMousePressRepeater->Stop();
}





//----- XMouseMotionListener --------------------------------------------------
    
void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    const Area eArea (GetArea(rEvent.X, rEvent.Y));
    if (eArea != meMouseMoveArea)
    {
        const Area eOldMouseMoveArea (meMouseMoveArea);
        meMouseMoveArea = eArea;
        if (eOldMouseMoveArea != None)
            Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None);
        if (meMouseMoveArea != None)
            Repaint(GetRectangle(meMouseMoveArea), true);
    }
    mpMousePressRepeater->SetMouseArea(eArea);
}




void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    if (meButtonDownArea != Thumb)
        return;

    mpMousePressRepeater->Stop();
    
    if (mxPresenterHelper.is())
        mxPresenterHelper->captureMouse(mxWindow);

    const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y));
    UpdateDragAnchor(nDragDistance);
    if (nDragDistance != 0)
    {
        SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true);
    }
}




//----- lang::XEventListener --------------------------------------------------

void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent)
    throw (css::uno::RuntimeException)
{
    if (rEvent.Source == mxWindow)
        mxWindow = NULL;
}




//-----------------------------------------------------------------------------

geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const
{
    OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);

    return maBox[eArea];
}




void PresenterScrollBar::Repaint (
    const geometry::RealRectangle2D aBox,
    const bool bAsynchronousUpdate)
{
    if (mpPaintManager.get() != NULL)
        mpPaintManager->Invalidate(
            mxWindow,
            PresenterGeometryHelper::ConvertRectangle(aBox),
            bAsynchronousUpdate);
}




void PresenterScrollBar::PaintBackground(
    const css::awt::Rectangle& rUpdateBox)
{
    if (mpBackgroundBitmap.get() == NULL)
        return;

    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    mpCanvasHelper->Paint(
        mpBackgroundBitmap,
        mxCanvas,
        rUpdateBox,
        aWindowBox,
        awt::Rectangle());
}




void PresenterScrollBar::PaintBitmap(
    const css::awt::Rectangle& rUpdateBox,
    const Area eArea,
    const SharedBitmapDescriptor& rpBitmaps)
{
    const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea));
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    geometry::RealRectangle2D aBox (aLocalBox);
    aBox.X1 += aWindowBox.X;
    aBox.Y1 += aWindowBox.Y;
    aBox.X2 += aWindowBox.X;
    aBox.Y2 += aWindowBox.Y;

    Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps));
    
    if (xBitmap.is())
    {
        Reference<rendering::XPolyPolygon2D> xClipPolygon (
            PresenterGeometryHelper::CreatePolygon(
                PresenterGeometryHelper::Intersection(rUpdateBox,
                    PresenterGeometryHelper::ConvertRectangle(aBox)),
                mxCanvas->getDevice()));
        
        const rendering::ViewState aViewState (
            geometry::AffineMatrix2D(1,0,0, 0,1,0),
            xClipPolygon);
        
        const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
        rendering::RenderState aRenderState (
            geometry::AffineMatrix2D(
                1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2,
                0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2),
            NULL,
            Sequence<double>(4),
            rendering::CompositeOperation::SOURCE);

        mxCanvas->drawBitmap(
            xBitmap,
            aViewState,
            aRenderState);
    }
}




void PresenterScrollBar::NotifyThumbPositionChange (void)
{
    if ( ! mbIsNotificationActive)
    {
        mbIsNotificationActive = true;

        try
        {
            maThumbMotionListener(mnThumbPosition);
        }
        catch (Exception&)
        {
        }
        
        mbIsNotificationActive = false;
    }
}




PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const
{
    const geometry::RealPoint2D aPoint(nX, nY);
    
    if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint))
    {
        if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint))
            return Thumb;
        else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint))
            return PagerUp;
        else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint))
            return PagerDown;
    }
    else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint))
        return PrevButton;
    else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint))
        return NextButton;

    return None;
}




void PresenterScrollBar::UpdateWidthOrHeight (
    sal_Int32& rSize,
    const SharedBitmapDescriptor& rpDescriptor)
{
    if (rpDescriptor.get() != NULL)
    {
        Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap());
        if (xBitmap.is())
        {
            const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize());
            const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height);
            if (nBitmapSize > rSize)
                rSize = nBitmapSize;
        }
    }
}




css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap (
    const Area eArea,
    const SharedBitmapDescriptor& rpBitmaps) const
{
    if (rpBitmaps.get() == NULL)
        return NULL;
    else
        return rpBitmaps->GetBitmap(GetBitmapMode(eArea));
}




PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode (
    const Area eArea) const
{
    if (IsDisabled(eArea))
        return PresenterBitmapContainer::BitmapDescriptor::Disabled;
    else if (eArea == meMouseMoveArea)
        return PresenterBitmapContainer::BitmapDescriptor::MouseOver;
    else
        return PresenterBitmapContainer::BitmapDescriptor::Normal;
}




bool PresenterScrollBar::IsDisabled (const Area eArea) const
{
    OSL_ASSERT(eArea>=0 && eArea<__AreaCount__);

    return ! maEnabledState[eArea];
}




//===== PresenterVerticalScrollBar ============================================

PresenterVerticalScrollBar::PresenterVerticalScrollBar (
    const Reference<XComponentContext>& rxComponentContext,
    const Reference<awt::XWindow>& rxParentWindow,
    const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
    const ::boost::function<void(double)>& rThumbMotionListener)
    : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
      mnScrollBarWidth(0)
{
}




PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void)
{
}




double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const
{
    (void)nX;
    const double nDistance (nY - maDragAnchor.Y);
    if (nDistance == 0)
        return 0;
    else
    {
        const awt::Rectangle aWindowBox (mxWindow->getPosSize());
        const double nBarWidth (aWindowBox.Width);
        const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
        const double nDragDistance (mnTotalSize / nPagerHeight * nDistance);
        if (nDragDistance + mnThumbPosition < 0)
            return -mnThumbPosition;
        else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
            return mnTotalSize-mnThumbSize-mnThumbPosition;
        else
            return nDragDistance;
    }
}




void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    const double nBarWidth (aWindowBox.Width);
    const double nPagerHeight (aWindowBox.Height - 2*nBarWidth);
    maDragAnchor.Y += nDragDistance * nPagerHeight /  mnTotalSize;
}




sal_Int32 PresenterVerticalScrollBar::GetSize (void) const
{
    return mnScrollBarWidth;
}




geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint (
    const double nMajor, const double nMinor) const
{
    return geometry::RealPoint2D(nMinor, nMajor);
}




double PresenterVerticalScrollBar::GetMajor (const double nX, const double nY) const
{
    (void)nX;
    return nY;
}




double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const
{
    (void)nY;
    return nX;
}




void PresenterVerticalScrollBar::UpdateBorders (void)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    double nBottom = aWindowBox.Height;
    
    if (mpNextButtonDescriptor.get() != NULL)
    {
        Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
        if (xBitmap.is())
        {
            geometry::IntegerSize2D aSize (xBitmap->getSize());
            maBox[NextButton] = geometry::RealRectangle2D(
                0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
            nBottom -= aSize.Height + gnScrollBarGap;
        }
    }
    if (mpPrevButtonDescriptor.get() != NULL)
    {
        Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
        if (xBitmap.is())
        {
            geometry::IntegerSize2D aSize (xBitmap->getSize());
            maBox[PrevButton] = geometry::RealRectangle2D(
                0, nBottom - aSize.Height, aWindowBox.Width, nBottom);
            nBottom -= aSize.Height + gnScrollBarGap;
        }
    }
    const double nPagerHeight (nBottom);
    maBox[Pager] = geometry::RealRectangle2D(
        0,0, aWindowBox.Width, nBottom);
    if (mnTotalSize < 1)
    {
        maBox[Thumb] = maBox[Pager];
        
        // Set up the enabled/disabled states.
        maEnabledState[PrevButton] = false;
        maEnabledState[PagerUp] = false;
        maEnabledState[NextButton] = false;
        maEnabledState[PagerDown] = false;
        maEnabledState[Thumb] = false;
    }
    else
    {
        const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
        const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
        maBox[Thumb] = geometry::RealRectangle2D(
            0, nThumbPosition / mnTotalSize * nPagerHeight,
            aWindowBox.Width, 
                (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight);

        // Set up the enabled/disabled states.
        maEnabledState[PrevButton] = nThumbPosition>0;
        maEnabledState[PagerUp] = nThumbPosition>0;
        maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
        maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
        maEnabledState[Thumb] = nThumbSize < mnTotalSize;
    }
    maBox[PagerUp] = geometry::RealRectangle2D(
        maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1);
    maBox[PagerDown] = geometry::RealRectangle2D(
        maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2);
    maBox[Total] = PresenterGeometryHelper::Union(
        PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
        maBox[Pager]);
}




void PresenterVerticalScrollBar::UpdateBitmaps (void)
{
    if (mpBitmaps.get() != NULL)
    {
        mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Up"));
        mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down"));
        mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop"));
        mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical"));
        mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom"));
        mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop"));
        mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical"));
        mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbBottom"));

        mnScrollBarWidth = 0;
        UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor);
        UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor);
        if (mnScrollBarWidth == 0)
            mnScrollBarWidth = 20;
    }
}




void PresenterVerticalScrollBar::PaintComposite(
    const css::awt::Rectangle& rUpdateBox,
    const Area eArea,
    const SharedBitmapDescriptor& rpStartBitmaps,
    const SharedBitmapDescriptor& rpCenterBitmaps,
    const SharedBitmapDescriptor& rpEndBitmaps)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    geometry::RealRectangle2D aBox (GetRectangle(eArea));
    aBox.X1 += aWindowBox.X;
    aBox.Y1 += aWindowBox.Y;
    aBox.X2 += aWindowBox.X;
    aBox.Y2 += aWindowBox.Y;

    // Get bitmaps and sizes.

    PresenterUIPainter::PaintVerticalBitmapComposite(
        mxCanvas,
        rUpdateBox,
        (eArea == Thumb
            ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox)
            : PresenterGeometryHelper::ConvertRectangle(aBox)),
        GetBitmap(eArea, rpStartBitmaps),
        GetBitmap(eArea, rpCenterBitmaps),
        GetBitmap(eArea, rpEndBitmaps));
}




//===== PresenterHorizontalScrollBar ============================================

PresenterHorizontalScrollBar::PresenterHorizontalScrollBar (
    const Reference<XComponentContext>& rxComponentContext,
    const Reference<awt::XWindow>& rxParentWindow,
    const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
    const ::boost::function<void(double)>& rThumbMotionListener)
    : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener),
      mnScrollBarHeight(0)
{
}




PresenterHorizontalScrollBar::~PresenterHorizontalScrollBar (void)
{
}




double PresenterHorizontalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const
{
    (void)nY;
    const double nDistance (nX - maDragAnchor.X);
    if (nDistance == 0)
        return 0;
    else
    {
        const awt::Rectangle aWindowBox (mxWindow->getPosSize());
        const double nBarHeight (aWindowBox.Height);
        const double nPagerWidth (aWindowBox.Width - 2*nBarHeight);
        const double nDragDistance (mnTotalSize / nPagerWidth * nDistance);
        if (nDragDistance + mnThumbPosition < 0)
            return -mnThumbPosition;
        else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize)
            return mnTotalSize-mnThumbSize-mnThumbPosition;
        else
            return nDragDistance;
    }
}




void PresenterHorizontalScrollBar::UpdateDragAnchor (const double nDragDistance)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
        const double nBarHeight (aWindowBox.Height);
        const double nPagerWidth (aWindowBox.Width - 2*nBarHeight);
    maDragAnchor.X += nDragDistance * nPagerWidth /  mnTotalSize;
}




sal_Int32 PresenterHorizontalScrollBar::GetSize (void) const
{
    return mnScrollBarHeight;
}





geometry::RealPoint2D PresenterHorizontalScrollBar::GetPoint (
    const double nMajor, const double nMinor) const
{
    return geometry::RealPoint2D(nMajor, nMinor);
}




double PresenterHorizontalScrollBar::GetMajor (const double nX, const double nY) const
{
    (void)nY;
    return nX;
}




double PresenterHorizontalScrollBar::GetMinor (const double nX, const double nY) const
{
    (void)nX;
    return nY;
}




void PresenterHorizontalScrollBar::UpdateBorders (void)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    double nRight = aWindowBox.Width;
    const double nGap (2);
    
    if (mpNextButtonDescriptor.get() != NULL)
    {
        Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap());
        if (xBitmap.is())
        {
            geometry::IntegerSize2D aSize (xBitmap->getSize());
            maBox[NextButton] = geometry::RealRectangle2D(
                nRight - aSize.Width,0, nRight, aWindowBox.Height);
            nRight -= aSize.Width + nGap;
        }
    }
    if (mpPrevButtonDescriptor.get() != NULL)
    {
        Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap());
        if (xBitmap.is())
        {
            geometry::IntegerSize2D aSize (xBitmap->getSize());
            maBox[PrevButton] = geometry::RealRectangle2D(
                nRight - aSize.Width,0, nRight, aWindowBox.Height);
            nRight -= aSize.Width + nGap;
        }
    }
    
    const double nPagerWidth (nRight);
    maBox[Pager] = geometry::RealRectangle2D(
        0,0, nRight, aWindowBox.Height);
    if (mnTotalSize == 0)
    {
        maBox[Thumb] = maBox[Pager];
        
        // Set up the enabled/disabled states.
        maEnabledState[PrevButton] = false;
        maEnabledState[PagerUp] = false;
        maEnabledState[NextButton] = false;
        maEnabledState[PagerDown] = false;
        maEnabledState[Thumb] = false;
    }
    else
    {
        const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize);
        const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize);
        maBox[Thumb] = geometry::RealRectangle2D(
            (nThumbPosition) / mnTotalSize * nPagerWidth, 0,
            (nThumbPosition+nThumbSize) / mnTotalSize * nPagerWidth, aWindowBox.Height);

        // Set up the enabled/disabled states.
        maEnabledState[PrevButton] = nThumbPosition>0;
        maEnabledState[PagerUp] = nThumbPosition>0;
        maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize;
        maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize;
        maEnabledState[Thumb] = nThumbSize < mnTotalSize;
    }
    maBox[PagerUp] = geometry::RealRectangle2D(
        maBox[Pager].X1, maBox[Pager].Y1, maBox[Thumb].X1-1, maBox[Pager].Y2);
    maBox[PagerDown] = geometry::RealRectangle2D(
        maBox[Thumb].X2+1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Pager].Y2);
    maBox[Total] = PresenterGeometryHelper::Union(
        PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]),
        maBox[Pager]);
}




void PresenterHorizontalScrollBar::UpdateBitmaps (void)
{
    if (mpBitmaps.get() != NULL)
    {
        mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Left"));
        mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Right"));
        mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerLeft"));
        mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerHorizontal"));
        mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerRight"));
        mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbLeft"));
        mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbHorizontal"));
        mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbRight"));

        mnScrollBarHeight = 0;
        UpdateWidthOrHeight(mnScrollBarHeight, mpPrevButtonDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpNextButtonDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpPagerStartDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpPagerCenterDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpPagerEndDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpThumbStartDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpThumbCenterDescriptor);
        UpdateWidthOrHeight(mnScrollBarHeight, mpThumbEndDescriptor);
        if (mnScrollBarHeight == 0)
            mnScrollBarHeight = 20;
    }
}



void PresenterHorizontalScrollBar::PaintComposite(
    const css::awt::Rectangle& rUpdateBox,
    const Area eArea,
    const SharedBitmapDescriptor& rpStartBitmaps,
    const SharedBitmapDescriptor& rpCenterBitmaps,
    const SharedBitmapDescriptor& rpEndBitmaps)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    geometry::RealRectangle2D aBox (GetRectangle(eArea));
    aBox.X1 += aWindowBox.X;
    aBox.Y1 += aWindowBox.Y;
    aBox.X2 += aWindowBox.X;
    aBox.Y2 += aWindowBox.Y;

    PresenterUIPainter::PaintHorizontalBitmapComposite(
        mxCanvas,
        rUpdateBox,
        PresenterGeometryHelper::ConvertRectangle(aBox),
        GetBitmap(eArea, rpStartBitmaps),
        GetBitmap(eArea, rpCenterBitmaps),
        GetBitmap(eArea, rpEndBitmaps));
}




//===== PresenterScrollBar::MousePressRepeater ================================

PresenterScrollBar::MousePressRepeater::MousePressRepeater (
    const ::rtl::Reference<PresenterScrollBar>& rpScrollBar)
    : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId),
      mpScrollBar(rpScrollBar),
      meMouseArea(PresenterScrollBar::None)
{
}




void PresenterScrollBar::MousePressRepeater::Dispose (void)
{
    Stop();
    mpScrollBar = NULL;
}




void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea)
{
    meMouseArea = reArea;

    if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId)
    {
        // Execute key press operation at least this one time.
        Execute();

        // Schedule repeated executions.
        mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask (
            ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1),
            500000000,
            250000000);
    }
    else
    {
        // There is already an active repeating task.
    }
}




void PresenterScrollBar::MousePressRepeater::Stop (void)
{
    if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
    {
        const sal_Int32 nTaskId (mnMousePressRepeaterTaskId);
        mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId;
        PresenterTimer::CancelTask(nTaskId);
    }
}




void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea)
{
    if (meMouseArea != reArea)
    {
        if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId)
        {
            Stop();
        }
    }
}




void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime)
{
    (void)rCurrentTime;
    
    if (mpScrollBar.get() == NULL)
    {
        Stop();
        return;
    }

    Execute();
}




void PresenterScrollBar::MousePressRepeater::Execute (void)
{
    const double nThumbPosition (mpScrollBar->GetThumbPosition());
    switch (meMouseArea)
    {
        case PrevButton:
            mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true);
            break;
            
        case NextButton:
            mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true);
            break;

        case PagerUp:
            mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true);
            break;

        case PagerDown:
            mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true);
            break;

        default:
            break;
    }
}



} } // end of namespace ::sdext::presenter
