/**************************************************************
 *
 * 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 "PresenterClock.hxx"
#include "PresenterConfigurationAccess.hxx"
#include "PresenterGeometryHelper.hxx"
#include <com/sun/star/awt/InvalidateStyle.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/awt/Point.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/deployment/XPackageInformationProvider.hpp>
#include <com/sun/star/drawing/framework/XControllerManager.hpp>
#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <com/sun/star/rendering/PathCapType.hpp>
#include <com/sun/star/rendering/TextDirection.hpp>
#include <com/sun/star/rendering/XCanvasFont.hpp>
#include <com/sun/star/rendering/XSpriteCanvas.hpp>
#include <com/sun/star/util/Color.hpp>
#include <osl/mutex.hxx>
#include <osl/time.h>
#include <rtl/ref.hxx>
#include <vos/timer.hxx>
#include <boost/bind.hpp>
#include <cmath>

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

namespace sdext { namespace presenter {


/** Wrapper around a library timer.
*/
class PresenterClock::Timer : public vos::OTimer
{
public:
    explicit Timer (const ::rtl::Reference<PresenterClock>& rpClock);
    virtual ~Timer (void);

    void Stop (void);

protected:
    virtual void SAL_CALL onShot (void);

private:
    ::rtl::Reference<PresenterClock> mpClock;
};




namespace {
    bool GetDateTime (oslDateTime& rDateTime);

    class BitmapDescriptor
    {
    public:
        Reference<rendering::XBitmap> mxBitmap;
        awt::Point maOffset;
        Reference<rendering::XBitmap> mxScaledBitmap;
        geometry::RealPoint2D maScaledOffset;
    };
}




class PresenterClock::Painter
{
public:
    virtual void Paint (
        const Reference<rendering::XCanvas>& rxCanvas,
        const rendering::ViewState& rViewState,
        const rendering::RenderState& rRenderState,
        const util::Color& rBackgroundColor,
        const sal_Int32 nHour,
        const sal_Int32 nMinute,
        const sal_Int32 nSecond,
        const bool bShowSeconds) = 0;
    virtual void Resize (const awt::Size& rSize) = 0;
};




namespace {
    class AnalogDefaultPainter : public PresenterClock::Painter
    {
    public:
        AnalogDefaultPainter (void);
        virtual ~AnalogDefaultPainter (void) {}
        virtual void Paint (
            const Reference<rendering::XCanvas>& rxCanvas,
            const rendering::ViewState& rViewState,
            const rendering::RenderState& rRenderState,
            const util::Color& rBackgroundColor,
            const sal_Int32 nHour,
            const sal_Int32 nMinute,
            const sal_Int32 nSecond,
            const bool bShowSeconds);
        virtual void Resize (const awt::Size& rSize);
    private:
        geometry::RealPoint2D maCenter;
        double mnOuterRadius;
        awt::Size maSize;
        Reference<rendering::XBitmap> mxBitmap;

        /** Relative length (with respect to radius) from center to the tip of
            the hand.
        */
        static const double mnRelativeHourHandLength;
        /** Relative length (with respect to radius) from center to the
            oposing end of the tip of the hand.
        */
        static const double mnRelativeHourHandLength2;
        static const double mnRelativeHourHandWidth;
        static const double mnRelativeMinuteHandLength;
        static const double mnRelativeMinuteHandLength2;
        static const double mnRelativeMinuteHandWidth;
        static const double mnRelativeSecondHandLength;
        static const double mnRelativeSecondHandLength2;
        static const double mnRelativeSecondHandWidth;

        void PaintAngledLine (
            const double nAngle,
            const double nInnerRadius,
            const double nOuterRadius,
            const double nStrokeWidth,
            const Reference<rendering::XCanvas>& rxCanvas,
            const rendering::ViewState& rViewState,
            const rendering::RenderState& rRenderState);
    };


    class AnalogBitmapPainter : public PresenterClock::Painter
    {
    public:
        AnalogBitmapPainter(
            const Reference<XComponentContext>& rxContext,
            const OUString& rsThemeName);
        virtual ~AnalogBitmapPainter (void) {}
        virtual void Paint (
            const Reference<rendering::XCanvas>& rxCanvas,
            const rendering::ViewState& rViewState,
            const rendering::RenderState& rRenderState,
            const util::Color& rBackgroundColor,
            const sal_Int32 nHour,
            const sal_Int32 nMinute,
            const sal_Int32 nSecond,
            const bool bShowSeconds);
        virtual void Resize (const awt::Size& rSize);
    private:
        css::uno::Reference<css::uno::XComponentContext> mxComponentContext;
        const OUString msThemeName;
        bool mbThemeLoaded;
        bool mbThemeLoadingFailed;
        geometry::RealPoint2D maCenter;
        double mnOuterRadius;
        BitmapDescriptor maFace;
        BitmapDescriptor maMinuteHand;
        BitmapDescriptor maHourHand;

        void PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas);
        Reference<container::XNameAccess> GetTheme (
            PresenterConfigurationAccess& rConfiguration);
        bool ThemeNameComparator (
            const ::rtl::OUString& rsKey,
            const Reference<container::XNameAccess>& rxCandidate,
            const ::rtl::OUString& rsCurrentThemeName);
        void LoadBitmaps (
            PresenterConfigurationAccess& rConfiguration,
            const Reference<container::XNameAccess>& rxNameAccess,
            const Reference<rendering::XCanvas>& rxCanvas);
        void LoadBitmap (
            const OUString& rsKey,
            const ::std::vector<Any>& rValues,
            const Reference<container::XNameAccess>& rxBitmapLoader);
        void ScaleBitmaps (void);
    };


    class DigitalDefaultPainter : public PresenterClock::Painter
    {
    public:
        DigitalDefaultPainter (
            const ::rtl::Reference<PresenterController>& rpPresenterController,
            const Reference<XResourceId>& rxViewId);
        virtual ~DigitalDefaultPainter (void);

        virtual void Paint (
            const Reference<rendering::XCanvas>& rxCanvas,
            const rendering::ViewState& rViewState,
            const rendering::RenderState& rRenderState,
            const util::Color& rBackgroundColor,
            const sal_Int32 nHour,
            const sal_Int32 nMinute,
            const sal_Int32 nSecond,
            const bool bShowSeconds);
        virtual void Resize (const awt::Size& rSize);

    private:
        ::rtl::Reference<PresenterController> mpPresenterController;
        bool mbIs24HourFormat;
        bool mbIsAdaptFontSize;
        Reference<rendering::XCanvasFont> mxFont;
        awt::Size maWindowSize;
        OUString msViewURL;

        void CreateFont (
            const Reference<rendering::XCanvas>& rxCanvas,
            const bool bIsShowSeconds);
    };


} // end of anonymous namespace




//===== PresenterClock =================================================================

::rtl::Reference<PresenterClock> PresenterClock::Create (
    const Reference<XComponentContext>& rxContext,
    const Reference<XResourceId>& rxViewId,
    const Reference<frame::XController>& rxController,
    const ::rtl::Reference<PresenterController>& rpPresenterController)
{
    ::rtl::Reference<PresenterClock> pClock (new PresenterClock(
        rxContext,
        rxViewId,
        rxController,
        rpPresenterController));
    pClock->LateInit();
    return pClock;
}




PresenterClock::PresenterClock (
    const Reference<XComponentContext>& rxContext,
    const Reference<XResourceId>& rxViewId,
    const Reference<frame::XController>& rxController,
    const ::rtl::Reference<PresenterController>& rpPresenterController)
    : PresenterClockInterfaceBase(m_aMutex),
      mxComponentContext(rxContext),
      mxViewId(rxViewId),
      mxWindow(),
      mxCanvas(),
      mxPane(),
      mpPresenterController(rpPresenterController),
      mbIsResizePending(true),
      maViewState(),
      maRenderState(),
      mpTimer(),
      mpClockPainter(),
      mpClockPainter2(),
      mnMode(1),
      mnHour(-1),
      mnMinute(-1),
      mnSecond(-1),
      mbIsShowSeconds(true)
{
    SetMode(mnMode);

    maViewState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
    maRenderState.AffineTransform = geometry::AffineMatrix2D(1,0,0, 0,1,0);
    maRenderState.DeviceColor = Sequence<double>(4);
    PresenterCanvasHelper::SetDeviceColor(maRenderState, util::Color(0x00000000));

    try
    {

        Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
        Reference<XConfigurationController> xCC (xCM->getConfigurationController(), UNO_QUERY_THROW);
        mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);

        mxWindow = mxPane->getWindow();
        if (mxWindow.is())
        {
            mxWindow->addPaintListener(this);
            mxWindow->addWindowListener(this);
            mxWindow->addMouseListener(this);
            Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
            if (xPeer.is())
                xPeer->setBackground(util::Color(0xff000000));
            mxWindow->setVisible(sal_True);
        }

        Resize();
    }
    catch (RuntimeException&)
    {
        disposing();
        throw;
    }
}




PresenterClock::~PresenterClock (void)
{
}




void PresenterClock::LateInit (void)
{
    mpTimer = new Timer(this);
}




void SAL_CALL PresenterClock::disposing (void)
{
    //    osl::MutexGuard aGuard (m_aMutex);
    if (mpTimer != NULL)
    {
        mpTimer->Stop();
    }
    if (mxWindow.is())
    {
        mxWindow->removePaintListener(this);
        mxWindow->removeWindowListener(this);
        mxWindow->removeMouseListener(this);
        mxWindow = NULL;
    }
    mxCanvas = NULL;
    mxViewId = NULL;
}




void PresenterClock::UpdateTime (void)
{
    // Get current time and check whether it is different from last time.
    oslDateTime aDateTime;
    if ( ! GetDateTime(aDateTime))
        return;
    if (aDateTime.Hours != mnHour
        || aDateTime.Minutes != mnMinute
        || aDateTime.Seconds != mnSecond)
    {
        mnHour = aDateTime.Hours % 24;
        mnMinute = aDateTime.Minutes % 60;
        mnSecond = aDateTime.Seconds % 60;

        Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
        if (xPeer.is())
            xPeer->invalidate(awt::InvalidateStyle::NOERASE |
            awt::InvalidateStyle::UPDATE);
    }
}




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

void SAL_CALL PresenterClock::disposing (const lang::EventObject& rEventObject)
    throw (RuntimeException)
{
    //    ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
    //    osl::MutexGuard aGuard (m_aMutex);

    if (rEventObject.Source == mxWindow)
    {
        mxWindow = NULL;
        if (mpTimer != NULL)
            mpTimer->Stop();
    }
}




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

void SAL_CALL PresenterClock::windowPaint (const awt::PaintEvent& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    ThrowIfDisposed();
    ::osl::MutexGuard aSolarGuard (::osl::Mutex::getGlobalMutex());
    Paint(rEvent.UpdateRect);
}




//----- XWindowListener -------------------------------------------------------

void SAL_CALL PresenterClock::windowResized (const awt::WindowEvent& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    mbIsResizePending = true;
}




void SAL_CALL PresenterClock::windowMoved (const awt::WindowEvent& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    mbIsResizePending = true;
}




void SAL_CALL PresenterClock::windowShown (const lang::EventObject& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    mbIsResizePending = true;
}




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




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

void SAL_CALL PresenterClock::mousePressed (const css::awt::MouseEvent& rEvent)
    throw (css::uno::RuntimeException)
{
    (void)rEvent;
    if (rEvent.Buttons == awt::MouseButton::LEFT)
    {
        SetMode(mnMode+1);
    }
}




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




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




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




//----- XResourceId -----------------------------------------------------------

Reference<XResourceId> SAL_CALL PresenterClock::getResourceId (void)
    throw (RuntimeException)
{
    return mxViewId;
}




sal_Bool SAL_CALL PresenterClock::isAnchorOnly (void)
    throw (RuntimeException)
{
    return false;
}




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

void PresenterClock::Resize (void)
{
    if (mxPane.is())
        mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
    if (mxWindow.is() && mxCanvas.is())
    {
        const awt::Rectangle aWindowBox (mxWindow->getPosSize());
        const awt::Size aWindowSize(aWindowBox.Width,aWindowBox.Height);
        if (mpClockPainter.get() != NULL)
            mpClockPainter->Resize(aWindowSize);
        if (mpClockPainter2.get() != NULL)
            mpClockPainter2->Resize(aWindowSize);
        mbIsResizePending = false;
    }
}




void PresenterClock::Paint (const awt::Rectangle& rUpdateBox)
{
    if ( ! mxCanvas.is() && mxPane.is())
        mxCanvas = Reference<rendering::XCanvas>(mxPane->getCanvas(), UNO_QUERY);
    if ( ! mxWindow.is()
        || ! mxCanvas.is()
        || ! mxCanvas->getDevice().is())
    {
        return;
    }

    try
    {
        if (mbIsResizePending)
            Resize();

        Reference<rendering::XPolyPolygon2D> xUpdatePolygon (
            PresenterGeometryHelper::CreatePolygon(rUpdateBox, mxCanvas->getDevice()));

        Clear(xUpdatePolygon);

        if (mpClockPainter.get() != NULL)
            mpClockPainter->Paint(mxCanvas,
                maViewState,
                maRenderState,
                mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
                mnHour,
                mnMinute,
                mnSecond,
                mbIsShowSeconds);

        if (mpClockPainter2.get() != NULL)
            mpClockPainter2->Paint(
                mxCanvas,
                maViewState,
                maRenderState,
                mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()),
                mnHour,
                mnMinute,
                mnSecond,
                mbIsShowSeconds);
    }
    catch (RuntimeException& e)
    {
        (void)e;
    }

    // Make the back buffer visible.
    Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
    if (xSpriteCanvas.is())
        xSpriteCanvas->updateScreen(sal_False);
}




void PresenterClock::Clear (const Reference<rendering::XPolyPolygon2D>& rxUpdatePolygon)
{
    rendering::RenderState aRenderState = maRenderState;
    const sal_Int32 nColor (
        mpPresenterController->GetViewBackgroundColor(mxViewId->getResourceURL()));
    aRenderState.DeviceColor[0] = ((nColor&0x00ff0000) >> 16) / 255.0;
    aRenderState.DeviceColor[1] = ((nColor&0x0000ff00) >>  8) / 255.0;
    aRenderState.DeviceColor[2] = ((nColor&0x000000ff) >>  0) / 255.0;

    if (rxUpdatePolygon.is())
        mxCanvas->fillPolyPolygon(
            rxUpdatePolygon,
            maViewState,
            aRenderState);
}




void PresenterClock::SetMode (const sal_Int32 nMode)
{
    mnMode = nMode % 3;

    switch (mnMode)
    {
        case 0:
            mpClockPainter.reset(
                new AnalogBitmapPainter(
                    mxComponentContext,
                    OUString::createFromAscii("ClockTheme")));
            mpClockPainter2.reset();
            break;

        case 1:
            mpClockPainter.reset();
            mpClockPainter2.reset(new AnalogDefaultPainter());
            break;

        case 2:
            mpClockPainter.reset();
            mpClockPainter2.reset(new DigitalDefaultPainter(mpPresenterController, mxViewId));
            break;

        case 3:
            mpClockPainter.reset(
                new AnalogBitmapPainter(
                    mxComponentContext,
                    OUString::createFromAscii("ClockTheme")));
            mpClockPainter2.reset(new AnalogDefaultPainter());
            break;
    }
    Resize();
}




void PresenterClock::ThrowIfDisposed (void)
    throw (::com::sun::star::lang::DisposedException)
{
	if (rBHelper.bDisposed || rBHelper.bInDispose)
	{
        throw lang::DisposedException (
            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                "PresenterClock object has already been disposed")),
            static_cast<uno::XWeak*>(this));
    }
}




//===== Timer =================================================================

PresenterClock::Timer::Timer (const ::rtl::Reference<PresenterClock>& rpClock)
    : OTimer(vos::TTimeValue(10), vos::TTimeValue(100/*ms*/)),
      mpClock(rpClock)
{
    acquire();
    start();
}




PresenterClock::Timer::~Timer (void)
{
    if (mpClock.is())
        Stop();
}




void PresenterClock::Timer::Stop (void)
{
    mpClock = NULL;
    stop();
    release();
}




void SAL_CALL PresenterClock::Timer::onShot (void)
{
    if (mpClock.get() != NULL)
        mpClock->UpdateTime();
}



namespace {

//=============================================================================

bool GetDateTime (oslDateTime& rDateTime)
{
    TimeValue aSystemTime;
    TimeValue aLocalTime;
    if (osl_getSystemTime(&aSystemTime))
        if (osl_getLocalTimeFromSystemTime(&aSystemTime, &aLocalTime))
            if (osl_getDateTimeFromTimeValue(&aLocalTime, &rDateTime))
                return true;
    return false;
}




//===== AnalogDefaultPainter ==================================================

const double AnalogDefaultPainter::mnRelativeHourHandLength = 0.65;
const double AnalogDefaultPainter::mnRelativeHourHandLength2 (-0.1);
const double AnalogDefaultPainter::mnRelativeHourHandWidth (0.055);
const double AnalogDefaultPainter::mnRelativeMinuteHandLength (-0.2);
const double AnalogDefaultPainter::mnRelativeMinuteHandLength2 (0.85);
const double AnalogDefaultPainter::mnRelativeMinuteHandWidth (0.025);
const double AnalogDefaultPainter::mnRelativeSecondHandLength (-0.25);
const double AnalogDefaultPainter::mnRelativeSecondHandLength2 (0.95);
const double AnalogDefaultPainter::mnRelativeSecondHandWidth (0.015);

AnalogDefaultPainter::AnalogDefaultPainter (void)
    : maCenter(0,0),
      mnOuterRadius(0),
      maSize(0,0),
      mxBitmap()
{
}




void AnalogDefaultPainter::Paint (
    const Reference<rendering::XCanvas>& rxCanvas,
    const rendering::ViewState& rViewState,
    const rendering::RenderState& rRenderState,
    const util::Color& rBackgroundColor,
    const sal_Int32 nHour,
    const sal_Int32 nMinute,
    const sal_Int32 nSecond,
    const bool bShowSeconds)
{
    double nInnerRadius (0);
    double nStrokeWidth (0.1);
    const double nClockSize (2*mnOuterRadius);

    // Some antialiasing is created by painting into a bitmap twice the
    // screen size and then scaling it down.
    const sal_Int32 nSuperSampleFactor (2);
    if ( ! mxBitmap.is())
    {
        mxBitmap = (rxCanvas->getDevice()->createCompatibleBitmap(
            geometry::IntegerSize2D(
                maSize.Width*nSuperSampleFactor,
                maSize.Height*nSuperSampleFactor)));
    }
    Reference<rendering::XCanvas> xBitmapCanvas (mxBitmap, UNO_QUERY);
    rendering::RenderState aRenderState(rRenderState);
    aRenderState.AffineTransform.m00 = nSuperSampleFactor;
    aRenderState.AffineTransform.m11 = nSuperSampleFactor;

    // Clear the background.
    aRenderState.DeviceColor[0] = ((rBackgroundColor&0x00ff0000) >> 16) / 255.0;
    aRenderState.DeviceColor[1] = ((rBackgroundColor&0x0000ff00) >>  8) / 255.0;
    aRenderState.DeviceColor[2] = ((rBackgroundColor&0x000000ff) >>  0) / 255.0;
    Reference<rendering::XPolyPolygon2D> xPolygon (
        PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(0,0,maSize.Width,maSize.Height),
            xBitmapCanvas->getDevice()));
    if (xPolygon.is())
        xBitmapCanvas->fillPolyPolygon(xPolygon, rViewState, aRenderState);

    // Clock face and clock hands are painted in black.
    aRenderState.DeviceColor[0] = 0;
    aRenderState.DeviceColor[1] = 0;
    aRenderState.DeviceColor[2] = 0;

    // Paint the clock face.
    for (sal_Int32 nHourMark=0; nHourMark<12; ++nHourMark)
    {
        if (nHourMark%3 == 0)
        {
            nInnerRadius = 0.7 * mnOuterRadius;
            nStrokeWidth = 0.05 * nClockSize;
        }
        else
        {
            nInnerRadius = 0.8 * mnOuterRadius;
            nStrokeWidth = 0.03 * nClockSize;
        }

        const double nAngle (nHourMark * 2 * M_PI / 12);
        PaintAngledLine(nAngle, nInnerRadius, mnOuterRadius, nStrokeWidth,
            xBitmapCanvas, rViewState, aRenderState);
    }

    // Paint the hour hand.
    const double nHoursAngle (((nHour%12)+nMinute/60.0) * 2 * M_PI / 12);
    PaintAngledLine(nHoursAngle,
        mnRelativeHourHandLength2*mnOuterRadius,
        mnRelativeHourHandLength*mnOuterRadius,
        mnRelativeHourHandWidth*nClockSize,
        xBitmapCanvas, rViewState, aRenderState);

    // Paint the minute hand.
    const double nMinutesAngle ((nMinute+nSecond/60.0) * 2 * M_PI / 60);
    PaintAngledLine(nMinutesAngle,
        mnRelativeMinuteHandLength2*mnOuterRadius,
        mnRelativeMinuteHandLength*mnOuterRadius,
        mnRelativeMinuteHandWidth*nClockSize,
        xBitmapCanvas, rViewState, aRenderState);

    // Optionally paint the second hand.
    if (bShowSeconds)
    {
        const double nSecondsAngle (nSecond * 2 * M_PI / 60);
        PaintAngledLine(nSecondsAngle,
            mnRelativeSecondHandLength2*mnOuterRadius,
            mnRelativeSecondHandLength*mnOuterRadius,
            mnRelativeSecondHandWidth*nClockSize,
            xBitmapCanvas, rViewState, aRenderState);
    }

    aRenderState.AffineTransform.m00 = 1.0 / nSuperSampleFactor;
    aRenderState.AffineTransform.m11 = 1.0 / nSuperSampleFactor;
    rxCanvas->drawBitmap(mxBitmap,rViewState,aRenderState);
}




void AnalogDefaultPainter::PaintAngledLine (
    const double nAngle,
    const double nInnerRadius,
    const double nOuterRadius,
    const double nStrokeWidth,
    const Reference<rendering::XCanvas>& rxCanvas,
    const rendering::ViewState& rViewState,
    const rendering::RenderState& rRenderState)
{
    if ( ! rxCanvas.is())
        return;

    rendering::StrokeAttributes aStrokeAttributes;
    aStrokeAttributes.StrokeWidth = nStrokeWidth;
    aStrokeAttributes.StartCapType = rendering::PathCapType::SQUARE;
    aStrokeAttributes.EndCapType = rendering::PathCapType::SQUARE;
    aStrokeAttributes.StartCapType = rendering::PathCapType::BUTT;
    aStrokeAttributes.EndCapType = rendering::PathCapType::BUTT;
    const double nCos (cos(nAngle - M_PI/2));
    const double nSin (sin(nAngle - M_PI/2));

    Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
    aPoints[0] = Sequence<geometry::RealPoint2D>(2);
    aPoints[0][0] = geometry::RealPoint2D(
        maCenter.X + nInnerRadius*nCos + 0.5,
        maCenter.Y + nInnerRadius*nSin + 0.5);
    aPoints[0][1] = geometry::RealPoint2D(
        maCenter.X + nOuterRadius*nCos + 0.5,
        maCenter.Y + nOuterRadius*nSin + 0.5);

    Reference<rendering::XPolyPolygon2D> xLine (
        rxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPoints),
        UNO_QUERY);
    if ( ! xLine.is())
        return;
    rxCanvas->strokePolyPolygon(
        xLine,
        rViewState,
        rRenderState,
        aStrokeAttributes);
}




void AnalogDefaultPainter::Resize (const awt::Size& rWindowSize)
{
    maSize = rWindowSize;
    maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
    mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
    mxBitmap = NULL;
}




//===== AnalogBitmapPainter ===================================================

AnalogBitmapPainter::AnalogBitmapPainter (
    const Reference<XComponentContext>& rxContext,
    const OUString& rsThemeName)
    : mxComponentContext(rxContext),
      msThemeName(rsThemeName),
      mbThemeLoaded(false),
      mbThemeLoadingFailed(false),
      maCenter(),
      mnOuterRadius(),
      maFace(),
      maMinuteHand(),
      maHourHand()
{
}




void AnalogBitmapPainter::Paint (
    const Reference<rendering::XCanvas>& rxCanvas,
    const rendering::ViewState& rViewState,
    const rendering::RenderState& rRenderState,
    const util::Color& rBackgroundColor,
    const sal_Int32 nHour,
    const sal_Int32 nMinute,
    const sal_Int32 nSecond,
    const bool bShowSeconds)
{
    (void)rBackgroundColor;
    (void)nSecond;
    (void)bShowSeconds;

    if ( ! rxCanvas.is())
        return;

    rendering::RenderState aRenderState = rRenderState;

    try
    {
        PrepareBitmaps(rxCanvas);

        if (maFace.mxScaledBitmap.is())
        {
            aRenderState.AffineTransform = geometry::AffineMatrix2D(
                1,0, maCenter.X - maFace.maScaledOffset.X,
                0,1, maCenter.Y - maFace.maScaledOffset.Y);
            rxCanvas->drawBitmap(maFace.mxScaledBitmap, rViewState, aRenderState);
        }

        if (maMinuteHand.mxScaledBitmap.is())
        {
            const double nMinuteAngle ((nMinute+nSecond/60.0) * 2.0 * M_PI / 60.0);
            const double nCos (cos(nMinuteAngle - M_PI/2));
            const double nSin (sin(nMinuteAngle - M_PI/2));
            aRenderState.AffineTransform = geometry::AffineMatrix2D(
                nCos,
                -nSin,
                -maMinuteHand.maScaledOffset.X*nCos
                    + maMinuteHand.maScaledOffset.Y*nSin+maCenter.X,
                nSin,
                nCos,
                -maMinuteHand.maScaledOffset.X*nSin
                    - maMinuteHand.maScaledOffset.Y*nCos+maCenter.Y);
            rxCanvas->drawBitmap(maMinuteHand.mxScaledBitmap, rViewState, aRenderState);
        }

        if (maHourHand.mxScaledBitmap.is())
        {
            const double nHoursAngle ((nHour%12+nMinute/60.0) * 2.0 * M_PI / 12.0);
            const double nCos (cos(nHoursAngle - M_PI/2));
            const double nSin (sin(nHoursAngle - M_PI/2));
            aRenderState.AffineTransform = geometry::AffineMatrix2D(
                nCos,
                -nSin,
                -maHourHand.maScaledOffset.X*nCos+maHourHand.maScaledOffset.Y*nSin+maCenter.X,
                nSin,
                nCos,
                -maHourHand.maScaledOffset.X*nSin-maHourHand.maScaledOffset.Y*nCos+maCenter.Y);
            rxCanvas->drawBitmap(maHourHand.mxScaledBitmap, rViewState, aRenderState);
        }
    }
    catch(beans::UnknownPropertyException&)
    {
    }
    catch(RuntimeException&)
    {
    }
}




void AnalogBitmapPainter::Resize (const awt::Size& rWindowSize)
{
    maCenter = geometry::RealPoint2D(rWindowSize.Width/2.0, rWindowSize.Height/2.0);
    mnOuterRadius = ::std::min(rWindowSize.Width, rWindowSize.Height) / 2.0 - 2;
    maFace.mxScaledBitmap = NULL;
    maHourHand.mxScaledBitmap = NULL;
    maMinuteHand.mxScaledBitmap = NULL;
}




void AnalogBitmapPainter::PrepareBitmaps (const Reference<rendering::XCanvas>& rxCanvas)
{
    if (mbThemeLoadingFailed)
    {
        // Theme loading has failed previously.  Do not try a second time.
        return;
    }
    if ( ! rxCanvas.is())
    {
        // No canvas => bitmaps can neither be loaded, transformed into the
        // right format, nor can they be painted.
        return;
    }

    if ( ! mbThemeLoaded)
    {
        mbThemeLoaded = true;

        // Get access to the clock bitmaps in the configuration.
        PresenterConfigurationAccess aConfiguration (
            mxComponentContext,
            OUString::createFromAscii("org.openoffice.Office.PresenterScreen"),
            PresenterConfigurationAccess::READ_ONLY);

        Reference<container::XNameAccess> xTheme (GetTheme(aConfiguration));
        if (xTheme.is())
            LoadBitmaps(aConfiguration, xTheme, rxCanvas);
        else
            mbThemeLoadingFailed = true;
    }

    ScaleBitmaps();
}




Reference<container::XNameAccess> AnalogBitmapPainter::GetTheme (
    PresenterConfigurationAccess& rConfiguration)
{
    Reference<container::XNameAccess> xTheme;

    // Get root of clock themes.
    Reference<container::XHierarchicalNameAccess> xClock (
        rConfiguration.GetConfigurationNode(
            OUString::createFromAscii("PresenterScreenSettings/AnalogBitmapClock")),
        UNO_QUERY);

    // Determine the name of the theme to use.
    OUString sCurrentThemeName (OUString::createFromAscii("DefaultTheme"));
    rConfiguration.GetConfigurationNode(
        xClock,
        OUString::createFromAscii("CurrentTheme")) >>= sCurrentThemeName;

    // Load the clock theme.
    Reference<container::XNameAccess> xThemes (
        rConfiguration.GetConfigurationNode(
            xClock,
            OUString::createFromAscii("Themes")),
        UNO_QUERY);
    if (xThemes.is())
    {
        xTheme = Reference<container::XNameAccess>(
            PresenterConfigurationAccess::Find(
                xThemes,
                ::boost::bind(&AnalogBitmapPainter::ThemeNameComparator,
                    this, _1, _2, sCurrentThemeName)),
            UNO_QUERY);
    }

    return xTheme;
}




bool AnalogBitmapPainter::ThemeNameComparator (
    const OUString& rsKey,
    const Reference<container::XNameAccess>& rxCandidate,
    const OUString& rsCurrentThemeName)
{
    (void)rsKey;
    if (rxCandidate.is())
    {
        OUString sThemeName;
        if (rxCandidate->getByName(OUString::createFromAscii("ThemeName")) >>= sThemeName)
        {
            return sThemeName == rsCurrentThemeName;
        }
    }
    return false;
}





void AnalogBitmapPainter::LoadBitmaps (
    PresenterConfigurationAccess& rConfiguration,
    const Reference<container::XNameAccess>& rxClockTheme,
    const Reference<rendering::XCanvas>& rxCanvas)
{
    (void)rConfiguration;
    // Create the bitmap loader.
    Reference<lang::XMultiComponentFactory> xFactory (
        mxComponentContext->getServiceManager(), UNO_QUERY);
    if ( ! xFactory.is())
        return;
    Sequence<Any> aArguments(1);
    aArguments[0] <<= rxCanvas;
    Reference<container::XNameAccess> xBitmapLoader(
        xFactory->createInstanceWithArgumentsAndContext(
            OUString::createFromAscii("com.sun.star.drawing.PresenterWorkaroundService"),
            aArguments,
            mxComponentContext),
        UNO_QUERY);
    if ( ! xBitmapLoader.is())
        return;


    // Iterate over all entries in the bitmap list and load the bitmaps.
    Reference<container::XNameAccess> xBitmaps (
        rxClockTheme->getByName(OUString::createFromAscii("Bitmaps")),
        UNO_QUERY);
    ::std::vector<rtl::OUString> aBitmapProperties (3);
    aBitmapProperties[0] = OUString::createFromAscii("FileName");
    aBitmapProperties[1] = OUString::createFromAscii("XOffset");
    aBitmapProperties[2] = OUString::createFromAscii("YOffset");
    PresenterConfigurationAccess::ForAll(
        xBitmaps,
        aBitmapProperties,
        ::boost::bind(&AnalogBitmapPainter::LoadBitmap,
            this,
            _1,
            _2,
            xBitmapLoader));
}




void AnalogBitmapPainter::LoadBitmap (
    const OUString& rsKey,
    const ::std::vector<Any>& rValues,
    const Reference<container::XNameAccess>& rxBitmapLoader)
{
    if (rValues.size() == 3)
    {
        BitmapDescriptor* pDescriptor = NULL;
        if (rsKey == OUString::createFromAscii("Face"))
            pDescriptor = &maFace;
        else if (rsKey == OUString::createFromAscii("HourHand"))
            pDescriptor = &maHourHand;
        else if (rsKey == OUString::createFromAscii("MinuteHand"))
            pDescriptor = &maMinuteHand;

        if (pDescriptor == NULL)
            return;

        OUString sFileName;
        if ( ! (rValues[0] >>= sFileName))
            return;

        rValues[1] >>= pDescriptor->maOffset.X;
        rValues[2] >>= pDescriptor->maOffset.Y;

        pDescriptor->mxBitmap = Reference<rendering::XBitmap>(
            rxBitmapLoader->getByName(sFileName), UNO_QUERY);

        if ( ! pDescriptor->mxBitmap.is())
            mbThemeLoadingFailed = true;
    }
}




void AnalogBitmapPainter::ScaleBitmaps (void)
{
    if (mbThemeLoadingFailed)
        return;
    if ( ! maFace.mxBitmap.is())
        return;

    const geometry::IntegerSize2D aFaceSize (maFace.mxBitmap->getSize());
    const sal_Int32 nSize = std::max(aFaceSize.Width, aFaceSize.Height);
    const double nScale = mnOuterRadius*2 / nSize;

    BitmapDescriptor* aDescriptors[3] = { &maFace, &maHourHand, &maMinuteHand };
    for (int nIndex=0; nIndex<3; ++nIndex)
    {
        BitmapDescriptor& rDescriptor (*aDescriptors[nIndex]);
        if ( ! rDescriptor.mxScaledBitmap.is() && rDescriptor.mxBitmap.is())
        {
            const geometry::IntegerSize2D aBitmapSize (rDescriptor.mxBitmap->getSize());
            rDescriptor.mxScaledBitmap = rDescriptor.mxBitmap->getScaledBitmap(
                geometry::RealSize2D(aBitmapSize.Width*nScale, aBitmapSize.Height*nScale),
                sal_False);
            rDescriptor.maScaledOffset = geometry::RealPoint2D(
                rDescriptor.maOffset.X * nScale,
                rDescriptor.maOffset.Y * nScale);
        }
    }
}




//===== DigitalDefaultPainter =================================================

DigitalDefaultPainter::DigitalDefaultPainter (
    const ::rtl::Reference<PresenterController>& rpPresenterController,
    const Reference<XResourceId>& rxViewId)
    :  mpPresenterController(rpPresenterController),
       mbIs24HourFormat(false),
       mbIsAdaptFontSize(true),
       mxFont(),
       maWindowSize(0,0),
       msViewURL(rxViewId.is() ? rxViewId->getResourceURL() : OUString())
{
}




DigitalDefaultPainter::~DigitalDefaultPainter (void)
{
}




void DigitalDefaultPainter::Paint (
    const Reference<rendering::XCanvas>& rxCanvas,
    const rendering::ViewState& rViewState,
    const rendering::RenderState& rRenderState,
    const util::Color& rBackgroundColor,
    const sal_Int32 nHour,
    const sal_Int32 nMinute,
    const sal_Int32 nSecond,
    const bool bIsShowSeconds)
{
    (void)rBackgroundColor;
    (void)rRenderState;

    if ( ! mxFont.is())
        CreateFont(rxCanvas,bIsShowSeconds);
    if ( ! mxFont.is())
        return;

    OUString sText;

    if (mbIs24HourFormat)
        sText = OUString::valueOf(nHour);
    else
    {
        sText = OUString::valueOf(nHour>12 ? nHour-12 : nHour);
    }
    sText += OUString::createFromAscii(":");
    const OUString sMinutes (OUString::valueOf(nMinute));
    switch (sMinutes.getLength())
    {
        case 1 :
            sText += OUString::createFromAscii("0") + sMinutes;
            break;
        case 2:
            sText += sMinutes;
            break;

        default:
            return;
    }
    if (bIsShowSeconds)
    {
        sText += OUString::createFromAscii(":");
        const OUString sSeconds (OUString::valueOf(nSecond));
        switch (sSeconds.getLength())
        {
            case 1 :
                sText += OUString::createFromAscii("0") + sSeconds;
                break;
            case 2:
                sText += sSeconds;
                break;

            default:
                return;
        }
    }

    rendering::StringContext aContext (
        sText,
        0,
        sText.getLength());
    Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
        aContext,
        rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
        0));
    if ( ! xLayout.is())
        return;
    geometry::RealRectangle2D aBox (xLayout->queryTextBounds());


    rendering::RenderState aRenderState(
        geometry::AffineMatrix2D(1,0,0, 0,1,0),
        NULL,
        Sequence<double>(4),
        rendering::CompositeOperation::SOURCE);

    util::Color aFontColor (mpPresenterController->GetViewFontColor(msViewURL));
    PresenterCanvasHelper::SetDeviceColor(aRenderState, aFontColor);
    aRenderState.AffineTransform.m02
        = (maWindowSize.Width - (aBox.X2-aBox.X1+1)) / 2 - aBox.X1;
    aRenderState.AffineTransform.m12
        = (maWindowSize.Height - (aBox.Y2-aBox.Y1+1)) / 2 - aBox.Y1;
    rxCanvas->drawText(
        aContext,
        mxFont,
        rViewState,
        aRenderState,
        rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
}




void DigitalDefaultPainter::Resize (const awt::Size& rSize)
{
    if (maWindowSize.Width != rSize.Width || maWindowSize.Height != rSize.Height)
    {
        maWindowSize = rSize;
        if (mbIsAdaptFontSize)
            mxFont = NULL;
    }
}




void DigitalDefaultPainter::CreateFont (
    const Reference<rendering::XCanvas>& rxCanvas,
    const bool bIsShowSeconds)
{
    if (rxCanvas.is()
        && rxCanvas->getDevice().is()
        && maWindowSize.Width>0
        && maWindowSize.Height>0)
    {
        // Create a time template for determinging the right font size.
        // Assume that 0 is the widest digit or that all digits have the
        // same width.
        OUString sTimeTemplate;
        // For the case that not all digits have the same width, create
        // different templates for 12 and 24 hour mode.
        if (mbIs24HourFormat)
            sTimeTemplate = OUString::createFromAscii("20");
        else
            sTimeTemplate = OUString::createFromAscii("10");
        if (bIsShowSeconds)
            sTimeTemplate += OUString::createFromAscii(":00:00");
        else
            sTimeTemplate += OUString::createFromAscii(":00");

        rendering::StringContext aContext (
            sTimeTemplate,
            0,
            sTimeTemplate.getLength());

        // When the font size is adapted to the window size (as large as
        // possible without overlapping) then that is done in a four step
        // process:
        // 1. Create a font in a default size, e.g. 10pt.
        // 2. Determine a scale factor from enlarging the text bounding box
        // to maximal size inside the window.
        // 3. Create a new font by scaling the default size with the factor
        // calculated in step 2.
        // 4. Text may be rendered differently in different sizes.
        // Therefore repeat step 2 and 3 once.  More iterations may lead to
        // even better results but probably not to visible differences.
        rendering::FontRequest aFontRequest (mpPresenterController->GetViewFontRequest(msViewURL));
        // TODO: use font from view style from configuration
        aFontRequest.CellSize = 10;

        for (sal_Int32 nLoop=0; nLoop<3; ++nLoop)
        {
            mxFont = rxCanvas->createFont(
                aFontRequest,
                Sequence<beans::PropertyValue>(),
                geometry::Matrix2D(1,0,0,1));
            if (mxFont.is())
            {
                Reference<rendering::XTextLayout> xLayout (mxFont->createTextLayout(
                    aContext,
                    rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
                    0));

                if ( ! xLayout.is())
                    break;

                geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
                if (aBox.X2<=aBox.X1 || aBox.Y2<=aBox.Y1)
                    break;
                const double nHorizontalFactor = maWindowSize.Width / (aBox.X2-aBox.X1+1);
                const double nVerticalFactor = maWindowSize.Height / (aBox.Y2-aBox.Y1+1);
                aFontRequest.CellSize *= ::std::min(nHorizontalFactor,nVerticalFactor);
            }
        }
    }
}


} // end of anonymous namespace


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