/**************************************************************
 *
 * 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 "PresenterSlideShowView.hxx"

#include "PresenterCanvasHelper.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterHelper.hxx"
#include "PresenterPaneContainer.hxx"
#include <com/sun/star/awt/InvalidateStyle.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/CanvasFeature.hpp>
#include <com/sun/star/drawing/XPresenterHelper.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/TextDirection.hpp>
#include <com/sun/star/rendering/TexturingMode.hpp>
#include <osl/mutex.hxx>

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

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

namespace sdext { namespace presenter {

//===== PresenterSlideShowView ================================================

PresenterSlideShowView::PresenterSlideShowView (
    const css::uno::Reference<css::uno::XComponentContext>& rxContext,
    const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
    const css::uno::Reference<css::frame::XController>& rxController,
    const ::rtl::Reference<PresenterController>& rpPresenterController)
    : PresenterSlideShowViewInterfaceBase(m_aMutex),
      mxComponentContext(rxContext),
      mpPresenterController(rpPresenterController),
      mxViewId(rxViewId),
      mxController(rxController),
      mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)),
      mxSlideShow(),
      mxCanvas(),
      mxViewCanvas(),
      mxPointer(),
      mxWindow(),
      mxViewWindow(),
      mxTopPane(),
      mxPresenterHelper(),
      mxBackgroundPolygon1(),
      mxBackgroundPolygon2(),
      mbIsViewAdded(false),
      mnPageAspectRatio(28.0/21.0),
      maBroadcaster(m_aMutex),
      mpBackground(),
      mbIsInModifyNotification(false),
      mbIsForcedPaintPending(false),
      mbIsPaintPending(true),
      msClickToExitPresentationText(),
      msClickToExitPresentationTitle(),
      msTitleTemplate(),
      mbIsEndSlideVisible(false),
      mxCurrentSlide()
{
    if (mpPresenterController.get() != NULL)
    {
        mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
        mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
    }
}



void PresenterSlideShowView::LateInit (void)
{
    mxSlideShow = Reference<presentation::XSlideShow> (
        mxSlideShowController->getSlideShow(), UNO_QUERY_THROW);
    Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
    if (xSlideShowComponent.is())
        xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));

    Reference<lang::XMultiComponentFactory> xFactory (
        mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
    mxPresenterHelper.set (xFactory->createInstanceWithContext(
			       OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
			       mxComponentContext),
			   UNO_QUERY_THROW);

    // Use view id and controller to retrieve window and canvas from
    // configuration controller.
    Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
    Reference<XConfigurationController> xCC (xCM->getConfigurationController());

    if (xCC.is())
    {
	mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);

        Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);

        mxWindow = xPane->getWindow();
        mxCanvas = xPane->getCanvas();

        if (mxWindow.is())
        {
            mxWindow->addPaintListener(this);
            mxWindow->addWindowListener(this);
        }

        // The window does not have to paint a background.  We do
        // that ourself.
        Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
        if (xPeer.is())
            xPeer->setBackground(util::Color(0xff000000));
    }

    // Create a window for the actual slide show view.  It is places
    // centered and with maximal size inside the pane.
    mxViewWindow = CreateViewWindow(mxWindow);

    mxViewCanvas = CreateViewCanvas(mxViewWindow);

    if (mxViewWindow.is())
    {
        // Register listeners at window.
        mxViewWindow->addPaintListener(this);
        mxViewWindow->addMouseListener(this);
        mxViewWindow->addMouseMotionListener(this);
    }

    if (mxViewWindow.is())
        Resize();

    if (mxWindow.is())
        mxWindow->setVisible(sal_True);

    // Add the new slide show view to the slide show.
    if (mxSlideShow.is() && ! mbIsViewAdded)
    {
        Reference<presentation::XSlideShowView> xView (this);
        mxSlideShow->addView(xView);
        // Prevent embedded sounds being played twice at the same time by
        // disabling sound for the new slide show view.
        beans::PropertyValue aProperty;
        aProperty.Name = A2S("IsSoundEnabled");
        Sequence<Any> aValues (2);
        aValues[0] <<= xView;
        aValues[1] <<= sal_False;
        aProperty.Value <<= aValues;
        mxSlideShow->setProperty(aProperty);
        mbIsViewAdded = true;
    }

    // Read text for one past last slide.
    PresenterConfigurationAccess aConfiguration (
        mxComponentContext,
        PresenterConfigurationAccess::msPresenterScreenRootName,
        PresenterConfigurationAccess::READ_ONLY);
    aConfiguration.GetConfigurationNode(
        A2S("Presenter/Views/CurrentSlidePreview/"
            "Strings/ClickToExitPresentationText/String"))
        >>= msClickToExitPresentationText;
    aConfiguration.GetConfigurationNode(
        A2S("Presenter/Views/CurrentSlidePreview/"
            "Strings/ClickToExitPresentationTitle/String"))
        >>= msClickToExitPresentationTitle;
}




PresenterSlideShowView::~PresenterSlideShowView (void)
{
}




void PresenterSlideShowView::disposing (void)
{
    // Tell all listeners that we are disposed.
    lang::EventObject aEvent;
    aEvent.Source = static_cast<XWeak*>(this);

    ::cppu::OInterfaceContainerHelper* pIterator
          = maBroadcaster.getContainer(getCppuType((Reference<lang::XEventListener>*)NULL));
    if (pIterator != NULL)
        pIterator->disposeAndClear(aEvent);

    // Do this for
    // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?

    if (mxWindow.is())
    {
        mxWindow->removePaintListener(this);
        mxWindow->removeMouseListener(this);
        mxWindow->removeMouseMotionListener(this);
        mxWindow->removeWindowListener(this);
        mxWindow = NULL;
    }
    mxSlideShowController = NULL;
    mxSlideShow = NULL;
    if (mxViewCanvas.is())
    {
        Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
        mxViewCanvas = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }
    if (mxViewWindow.is())
    {
        Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY);
        mxViewWindow = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }
    if (mxPointer.is())
    {
        Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
        mxPointer = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }
    if (mxBackgroundPolygon1.is())
    {
        Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
        mxBackgroundPolygon1 = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }
    if (mxBackgroundPolygon2.is())
    {
        Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
        mxBackgroundPolygon2 = NULL;
        if (xComponent.is())
            xComponent->dispose();
    }

    mxComponentContext = NULL;
    mpPresenterController = NULL;
    mxViewId = NULL;
    mxController = NULL;
    mxCanvas = NULL;
    mpBackground.reset();
    msClickToExitPresentationText = OUString();
    msClickToExitPresentationTitle = OUString();
    msTitleTemplate = OUString();
    mxCurrentSlide = NULL;
}




//----- XDrawView -------------------------------------------------------------

void SAL_CALL PresenterSlideShowView::setCurrentPage (
    const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
    throw (css::uno::RuntimeException)
{
    mxCurrentSlide = rxSlide;
    if (mpPresenterController.get() != NULL
        && mxSlideShowController.is()
        && ! mpPresenterController->GetCurrentSlide().is()
        && ! mxSlideShowController->isPaused())
    {
        mbIsEndSlideVisible = true;
        Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
        if (xPeer.is())
            xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);

        // For the end slide we use a special title, without the (n of m)
        // part.  Save the title template for the case that the user goes
        // backwards.
        PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
            mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
        if (pDescriptor.get() != NULL)
        {
            msTitleTemplate = pDescriptor->msTitleTemplate;
            pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
            mpPresenterController->UpdatePaneTitles();
        }
    }
    else if (mbIsEndSlideVisible)
    {
        mbIsEndSlideVisible = false;

        // Restore the title template.
        PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
            mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
        if (pDescriptor.get() != NULL)
        {
            pDescriptor->msTitleTemplate = msTitleTemplate;
            pDescriptor->msTitle = OUString();
            mpPresenterController->UpdatePaneTitles();
        }
    }
}




css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage (void)
    throw (css::uno::RuntimeException)
{
    return mxCurrentSlide;
}




//----- CachablePresenterView -------------------------------------------------

void PresenterSlideShowView::ReleaseView (void)
{
    if (mxSlideShow.is() && mbIsViewAdded)
    {
        mxSlideShow->removeView(this);
        mbIsViewAdded = false;
    }
}




//----- XSlideShowView --------------------------------------------------------

Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas (void)
    throw (RuntimeException)
{
    ThrowIfDisposed();

    return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
}




void SAL_CALL PresenterSlideShowView::clear (void)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    mbIsForcedPaintPending = false;
    mbIsPaintPending = false;

    if (mxViewCanvas.is() && mxViewWindow.is())
    {
        // Create a polygon for the window outline.
        awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
        Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height),
            mxViewCanvas->getDevice()));

        rendering::ViewState aViewState (
            geometry::AffineMatrix2D(1,0,0, 0,1,0),
            NULL);
        double aColor[3] = {0,0,0};
        rendering::RenderState aRenderState(
            geometry::AffineMatrix2D(1,0,0, 0,1,0),
            NULL,
            Sequence<double>(aColor,4),
            rendering::CompositeOperation::SOURCE);
        mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
    }
}




geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation (void)
    throw (RuntimeException)
{
    ThrowIfDisposed();

    if (mxViewWindow.is())
    {
        // When the mbIsInModifyNotification is set then a slightly modifed
        // version of the transformation is returned in order to get past
        // optimizations the avoid updates when the transformation is
        // unchanged (when the window size changes then due to the constant
        // aspect ratio the size of the preview may remain the same while
        // the position changes.  The position, however, is repesented by
        // the position of the view window.  This transformation is given
        // relative to the view window and therefore does not contain the
        // position.)
        const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
        return geometry::AffineMatrix2D(
            aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0),
            0, aWindowBox.Height-1, 0);
    }
    else
    {
        return geometry::AffineMatrix2D(1,0,0, 0,1,0);
    }
}




void SAL_CALL PresenterSlideShowView::addTransformationChangedListener(
    const Reference<util::XModifyListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.addListener(
        getCppuType((Reference<util::XModifyListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener(
    const Reference<util::XModifyListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.removeListener(
        getCppuType((Reference<util::XModifyListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::addPaintListener(
    const Reference<awt::XPaintListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.addListener(
        getCppuType((Reference<awt::XPaintListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::removePaintListener(
    const Reference<awt::XPaintListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.removeListener(
        getCppuType((Reference<awt::XPaintListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::addMouseListener(
    const Reference<awt::XMouseListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.addListener(
        getCppuType((Reference<awt::XMouseListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::removeMouseListener(
    const Reference<awt::XMouseListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.removeListener(
        getCppuType((Reference<awt::XMouseListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::addMouseMotionListener(
    const Reference<awt::XMouseMotionListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.addListener(
        getCppuType((Reference<awt::XMouseMotionListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::removeMouseMotionListener(
    const Reference<awt::XMouseMotionListener>& rxListener)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    maBroadcaster.removeListener(
        getCppuType((Reference<awt::XMouseMotionListener>*)NULL),
        rxListener);
}




void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
    throw (RuntimeException)
{
    ThrowIfDisposed();

    // Create a pointer when it does not yet exist.
    if ( ! mxPointer.is())
    {
        Reference<lang::XMultiServiceFactory> xFactory (
            mxComponentContext, UNO_QUERY);
        if (xFactory.is())
            mxPointer = Reference<awt::XPointer>(
                xFactory->createInstance(OUString::createFromAscii("com.sun.star.awt.Pointer")),
                UNO_QUERY);
    }

    // Set the pointer to the given shape and the window(peer) to the
    // pointer.
    Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
    if (mxPointer.is() && xPeer.is())
    {
        mxPointer->setType(nPointerShape);
        xPeer->setPointer(mxPointer);
    }
}



awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea(  ) throw (RuntimeException)
{
    if( mxViewWindow.is() && mxTopPane.is() )
	return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );

    awt::Rectangle aRectangle;

    aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;

    return aRectangle;
}



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

void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
    throw (RuntimeException)
{
    if (rEvent.Source == mxViewWindow)
        mxViewWindow = NULL;
    else if (rEvent.Source == mxSlideShow)
        mxSlideShow = NULL;
}




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

void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
    throw (RuntimeException)
{
    // Deactivated views must not be painted.
    if ( ! mbIsPresenterViewActive)
        return;

    awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
    if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
        return;

    if (rEvent.Source == mxWindow)
        PaintOuterWindow(rEvent.UpdateRect);
    else if (mbIsEndSlideVisible)
        PaintEndSlide(rEvent.UpdateRect);
    else
        PaintInnerWindow(rEvent);
}




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

void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
    }

    // Only when the end slide is displayed we forward the mouse event to
    // the PresenterController so that it switches to the next slide and
    // ends the presentation.
    if (mbIsEndSlideVisible)
        if (mpPresenterController.get() != NULL)
            mpPresenterController->HandleMouseClick(rEvent);
}




void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
    }
}




void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
    }
}




void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
    }
}




//----- XMouseMotionListener --------------------------------------------------

void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
    }
}




void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
    throw (RuntimeException)
{
    awt::MouseEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
    }
}




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

void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;

    ThrowIfDisposed();
	::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());

    Resize();
}





void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    if ( ! mbIsPaintPending)
        mbIsForcedPaintPending = true;
}




void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent)
    throw (RuntimeException)
{
    (void)rEvent;
    Resize();
}




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




//----- XView -----------------------------------------------------------------

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




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




//----- CachablePresenterView -------------------------------------------------

void PresenterSlideShowView::ActivatePresenterView (void)
{
    if (mxSlideShow.is() && ! mbIsViewAdded)
    {
        mxSlideShow->addView(this);
        mbIsViewAdded = true;
    }
}




void PresenterSlideShowView::DeactivatePresenterView (void)
{
    if (mxSlideShow.is() && mbIsViewAdded)
    {
        mxSlideShow->removeView(this);
        mbIsViewAdded = false;
    }
}




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

void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
{
    if ( ! mxCanvas.is())
        return;

    if (mpBackground.get() == NULL)
        return;

    const rendering::ViewState aViewState(
        geometry::AffineMatrix2D(1,0,0, 0,1,0),
        PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));

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

    Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
    if (xBackgroundBitmap.is())
    {
        Sequence<rendering::Texture> aTextures (1);
        const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
        aTextures[0] = rendering::Texture (
            geometry::AffineMatrix2D(
                aBitmapSize.Width,0,0,
                0,aBitmapSize.Height,0),
            1,
            0,
            xBackgroundBitmap,
            NULL,
            NULL,
            rendering::StrokeAttributes(),
            rendering::TexturingMode::REPEAT,
            rendering::TexturingMode::REPEAT);

        if (mxBackgroundPolygon1.is())
            mxCanvas->fillTexturedPolyPolygon(
                mxBackgroundPolygon1,
                aViewState,
                aRenderState,
                aTextures);
        if (mxBackgroundPolygon2.is())
            mxCanvas->fillTexturedPolyPolygon(
                mxBackgroundPolygon2,
                aViewState,
                aRenderState,
                aTextures);
    }
    else
    {
        PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);

        if (mxBackgroundPolygon1.is())
            mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
        if (mxBackgroundPolygon2.is())
            mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
    }
}




void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
{
    if ( ! mxCanvas.is())
        return;

    const rendering::ViewState aViewState(
        geometry::AffineMatrix2D(1,0,0, 0,1,0),
        PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));

    rendering::RenderState aRenderState (
        geometry::AffineMatrix2D(1,0,0, 0,1,0),
        NULL,
        Sequence<double>(4),
        rendering::CompositeOperation::SOURCE);
    PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
    mxCanvas->fillPolyPolygon(
        PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()),
        aViewState,
        aRenderState);

    do
    {
        if (mpPresenterController.get() == NULL)
            break;
        ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
        if (pTheme.get() == NULL)
            break;

        const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
        PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
        if (pFont.get() == NULL)
            break;

        PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
        aRenderState.AffineTransform.m02 = 20;
        aRenderState.AffineTransform.m12 = 40;
        const rendering::StringContext aContext (
            msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength());
        pFont->PrepareFont(mxCanvas);
        mxCanvas->drawText(
            aContext,
            pFont->mxFont,
            aViewState,
            aRenderState,
            rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
    }
    while (false);

    // Finally, in double buffered environments, request the changes to be
    // made visible.
    Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
    if (mxSpriteCanvas.is())
        mxSpriteCanvas->updateScreen(sal_True);
}




void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
{
    // Forward window paint to listeners.
    awt::PaintEvent aEvent (rEvent);
    aEvent.Source = static_cast<XWeak*>(this);
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<awt::XPaintListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
    }

    if (mbIsForcedPaintPending)
        ForceRepaint();

    // Finally, in double buffered environments, request the changes to be
    // made visible.
    Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
    if (mxSpriteCanvas.is())
        mxSpriteCanvas->updateScreen(sal_True);
}




Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow (
    const Reference<awt::XWindow>& rxParentWindow) const
{
    Reference<awt::XWindow> xViewWindow;
    try
    {
        Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
        if ( ! xFactory.is())
            return xViewWindow;

        Reference<awt::XToolkit> xToolkit (
            xFactory->createInstanceWithContext(
                OUString::createFromAscii("com.sun.star.awt.Toolkit"),
                mxComponentContext),
            UNO_QUERY_THROW);
        awt::WindowDescriptor aWindowDescriptor (
            awt::WindowClass_CONTAINER,
            OUString(),
            Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW),
            -1, // parent index not available
            awt::Rectangle(0,0,10,10),
            awt::WindowAttribute::SIZEABLE
                | awt::WindowAttribute::MOVEABLE
                | awt::WindowAttribute::NODECORATION);
        xViewWindow = Reference<awt::XWindow>(
            xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW);

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

        xViewWindow->setVisible(sal_True);
    }
    catch (RuntimeException&)
    {
    }
    return xViewWindow;
}




Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
    const Reference<awt::XWindow>& rxViewWindow) const
{
    // Create a canvas for the view window.
    return mxPresenterHelper->createSharedCanvas(
        Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY),
        mxTopPane->getWindow(),
        mxTopPane->getCanvas(),
        mxTopPane->getWindow(),
        rxViewWindow);
}




void PresenterSlideShowView::Resize (void)
{
    if ( ! mxWindow.is() || ! mxViewWindow.is())
        return;

    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    awt::Rectangle aViewWindowBox;
    if (aWindowBox.Height > 0)
    {
        const double nWindowAspectRatio (
            double(aWindowBox.Width) / double(aWindowBox.Height));
        if (nWindowAspectRatio > mnPageAspectRatio)
        {
            // Slides will be painted with the full parent window height.
            aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5);
            aViewWindowBox.Height = aWindowBox.Height;
            aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2;
            aViewWindowBox.Y = 0;
        }
        else
        {
            // Slides will be painted with the full parent window width.
            aViewWindowBox.Width = aWindowBox.Width;
            aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5);
            aViewWindowBox.X = 0;
            aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2;
        }
        mxViewWindow->setPosSize(
            aViewWindowBox.X,
            aViewWindowBox.Y,
            aViewWindowBox.Width,
            aViewWindowBox.Height,
            awt::PosSize::POSSIZE);
    }

    // Clear the background polygon so that on the next paint it is created
    // for the new size.
    CreateBackgroundPolygons();

    // Notify listeners that the transformation that maps the view into the
    // window has changed.
    lang::EventObject aEvent (static_cast<XWeak*>(this));
    ::cppu::OInterfaceContainerHelper* pIterator
        = maBroadcaster.getContainer(getCppuType((Reference<util::XModifyListener>*)NULL));
    if (pIterator != NULL)
    {
        pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
    }

    // Due to constant aspect ratio resizing may lead a preview that changes
    // its position but not its size.  This invalidates the back buffer and
    // we have to enforce a complete repaint.
    if ( ! mbIsPaintPending)
        mbIsForcedPaintPending = true;
}




void PresenterSlideShowView::ForceRepaint (void)
{
    if (mxSlideShow.is() && mbIsViewAdded)
    {
        mxSlideShow->removeView(this);
        mxSlideShow->addView(this);
    }
}




void PresenterSlideShowView::CreateBackgroundPolygons (void)
{
    const awt::Rectangle aWindowBox (mxWindow->getPosSize());
    const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
    if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
    {
        mxBackgroundPolygon1 = NULL;
        mxBackgroundPolygon2 = NULL;
    }
    else if (aWindowBox.Height == aViewWindowBox.Height)
    {
        // Paint two boxes to the left and right of the view window.
        mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(
                0,
                0,
                aViewWindowBox.X,
                aWindowBox.Height),
            mxCanvas->getDevice());
        mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(
                aViewWindowBox.X + aViewWindowBox.Width,
                0,
                aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
                aWindowBox.Height),
            mxCanvas->getDevice());
    }
    else
    {
        // Paint two boxes above and below the view window.
        mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(
                0,
                0,
                aWindowBox.Width,
                aViewWindowBox.Y),
            mxCanvas->getDevice());
        mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
            awt::Rectangle(
                0,
                aViewWindowBox.Y + aViewWindowBox.Height,
                aWindowBox.Width,
                aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
            mxCanvas->getDevice());
    }
}




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


} } // end of namespace ::sd::presenter
