/**************************************************************
 * 
 * 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
