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

#include "precompiled_sd.hxx"

#include "MasterPageContainer.hxx"

#include "MasterPageDescriptor.hxx"
#include "MasterPageContainerFiller.hxx"
#include "MasterPageContainerQueue.hxx"
#include "TemplateScanner.hxx"
#include "tools/AsynchronousTask.hxx"
#include "strings.hrc"
#include <algorithm>
#include <list>
#include <set>

#include "unomodel.hxx"
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/uno/Reference.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/util/XCloseable.hpp>
#include <comphelper/processfactory.hxx>
#include <tools/urlobj.hxx>
#include <sfx2/app.hxx>
#include <svx/svdpage.hxx>
#include "DrawDocShell.hxx"
#include "drawdoc.hxx"
#include "sdpage.hxx"
#include <svl/itemset.hxx>
#include <svl/eitem.hxx>
#include "sdresid.hxx"
#include "tools/TimerBasedTaskExecution.hxx"
#include "pres.hxx"
#include <osl/mutex.hxx>
#include <boost/weak_ptr.hpp>

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

namespace {

typedef ::std::vector<sd::sidebar::SharedMasterPageDescriptor> MasterPageContainerType;

} // end of anonymous namespace


namespace sd { namespace sidebar {


/** Inner implementation class of the MasterPageContainer.
*/
class MasterPageContainer::Implementation
    : public SdGlobalResource,
      public MasterPageContainerFiller::ContainerAdapter,
      public MasterPageContainerQueue::ContainerAdapter
{
public:
    mutable ::osl::Mutex maMutex;

    static ::boost::weak_ptr<Implementation> mpInstance;
    MasterPageContainerType maContainer;

    static ::boost::shared_ptr<Implementation> Instance (void);

    void LateInit (void);
    void AddChangeListener (const Link& rLink);
    void RemoveChangeListener (const Link& rLink);
    void UpdatePreviewSizePixel (void);
    Size GetPreviewSizePixel (PreviewSize eSize) const;

    bool HasToken (Token aToken) const;
    const SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken) const;
    SharedMasterPageDescriptor GetDescriptor (MasterPageContainer::Token aToken);
    virtual Token PutMasterPage (const SharedMasterPageDescriptor& rDescriptor);
    void InvalidatePreview (Token aToken);
    Image GetPreviewForToken (
        Token aToken,
        PreviewSize ePreviewSize);
    PreviewState GetPreviewState (Token aToken) const;
    bool RequestPreview (Token aToken);

    Reference<frame::XModel> GetModel (void);
    SdDrawDocument* GetDocument (void);

    void FireContainerChange (
        MasterPageContainerChangeEvent::EventType eType,
        Token aToken,
        bool bNotifyAsynchronously = false);

    virtual bool UpdateDescriptor (
        const SharedMasterPageDescriptor& rpDescriptor,
        bool bForcePageObject,
        bool bForcePreview,
        bool bSendEvents);

    void ReleaseDescriptor (Token aToken);

    /** Called by the MasterPageContainerFiller to notify that all master
        pages from template documents have been added.
    */
    virtual void FillingDone (void);

private:
    Implementation (void);
    virtual ~Implementation (void);

    class Deleter { public:
        void operator() (Implementation* pObject) { delete pObject; }
    };
    friend class Deleter;

    enum InitializationState { NOT_INITIALIZED, INITIALIZING, INITIALIZED } meInitializationState;

    ::boost::scoped_ptr<MasterPageContainerQueue> mpRequestQueue;
    ::com::sun::star::uno::Reference<com::sun::star::frame::XModel> mxModel;
    SdDrawDocument* mpDocument;
    PreviewRenderer maPreviewRenderer;
    /** Remember whether the first page object has already been used to
        determine the correct size ratio.
    */
    bool mbFirstPageObjectSeen;

    // The widths for the previews contain two pixels for the border that is
    // painted around the preview.
    static const int SMALL_PREVIEW_WIDTH = 72 + 2;
    static const int LARGE_PREVIEW_WIDTH = 2*72 + 2;

    /** This substitution of page preview shows "Preparing preview" and is
        shown as long as the actual previews are not being present.
    */
    Image maLargePreviewBeingCreated;
    Image maSmallPreviewBeingCreated;

    /** This substitution of page preview is shown when a preview can not be
        created and thus is not available.
    */
    Image maLargePreviewNotAvailable;
    Image maSmallPreviewNotAvailable;

    ::std::vector<Link> maChangeListeners;

    // We have to remember the tasks for initialization and filling in case
    // a MasterPageContainer object is destroyed before these tasks have
    // been completed.
    ::boost::weak_ptr<sd::tools::TimerBasedTaskExecution> mpFillerTask;

    Size maSmallPreviewSizePixel;
    Size maLargePreviewSizePixel;
    bool mbPageRatioKnown;

    bool mbContainerCleaningPending;

    typedef ::std::pair<MasterPageContainerChangeEvent::EventType,Token> EventData;
    DECL_LINK(AsynchronousNotifyCallback, EventData*);
    ::sd::DrawDocShell* LoadDocument (
        const String& sFileName,
        SfxObjectShellLock& rxDocumentShell);

    Image GetPreviewSubstitution (sal_uInt16 nId, PreviewSize ePreviewSize);

    void CleanContainer (void);
};




//===== MasterPageContainer ===================================================

::boost::weak_ptr<MasterPageContainer::Implementation>
    MasterPageContainer::Implementation::mpInstance;
static const MasterPageContainer::Token NIL_TOKEN (-1);




::boost::shared_ptr<MasterPageContainer::Implementation>
    MasterPageContainer::Implementation::Instance (void)
{
    ::boost::shared_ptr<MasterPageContainer::Implementation> pInstance;

    if (Implementation::mpInstance.expired())
    {
        ::osl::GetGlobalMutex aMutexFunctor;
        ::osl::MutexGuard aGuard (aMutexFunctor());
        if (Implementation::mpInstance.expired())
        {
            OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
            pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
                new MasterPageContainer::Implementation(),
                MasterPageContainer::Implementation::Deleter());
            SdGlobalResourceContainer::Instance().AddResource(pInstance);
            Implementation::mpInstance = pInstance;
        }
        else
            pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
                Implementation::mpInstance);
    }
    else
    {
        OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
        pInstance = ::boost::shared_ptr<MasterPageContainer::Implementation>(
            Implementation::mpInstance);
    }

    DBG_ASSERT (pInstance.get()!=NULL,
        "MasterPageContainer::Implementation::Instance(): instance is NULL");
    return pInstance;
}




MasterPageContainer::MasterPageContainer (void)
    : mpImpl(Implementation::Instance()),
      mePreviewSize(SMALL)
{
    mpImpl->LateInit();
}




MasterPageContainer::~MasterPageContainer (void)
{
}




void MasterPageContainer::AddChangeListener (const Link& rLink)
{
    mpImpl->AddChangeListener(rLink);
}




void MasterPageContainer::RemoveChangeListener (const Link& rLink)
{
    mpImpl->RemoveChangeListener(rLink);
}




void MasterPageContainer::SetPreviewSize (PreviewSize eSize)
{
    mePreviewSize = eSize;
    mpImpl->FireContainerChange(
        MasterPageContainerChangeEvent::SIZE_CHANGED,
        NIL_TOKEN);
}




MasterPageContainer::PreviewSize MasterPageContainer::GetPreviewSize (void) const
{
    return mePreviewSize;
}




Size MasterPageContainer::GetPreviewSizePixel (void) const
{
    return mpImpl->GetPreviewSizePixel(mePreviewSize);
}




MasterPageContainer::Token MasterPageContainer::PutMasterPage (
    const SharedMasterPageDescriptor& rDescriptor)
{
    return mpImpl->PutMasterPage(rDescriptor);
}




void MasterPageContainer::AcquireToken (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
    {
        ++pDescriptor->mnUseCount;
    }
}




void MasterPageContainer::ReleaseToken (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
    {
        OSL_ASSERT(pDescriptor->mnUseCount>0);
        --pDescriptor->mnUseCount;
        if (pDescriptor->mnUseCount <= 0)
        {
            switch (pDescriptor->meOrigin)
            {
                case DEFAULT:
                case TEMPLATE:
                default:
                    break;

                case MASTERPAGE:
                    mpImpl->ReleaseDescriptor(aToken);
                    break;
            }
        }
    }
}




int MasterPageContainer::GetTokenCount (void) const
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->maContainer.size();
}




bool MasterPageContainer::HasToken (Token aToken) const
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->HasToken(aToken);
}




MasterPageContainer::Token MasterPageContainer::GetTokenForIndex (int nIndex)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (HasToken(nIndex))
        aResult = mpImpl->maContainer[nIndex]->maToken;
    return aResult;
}




MasterPageContainer::Token MasterPageContainer::GetTokenForURL (
    const String& sURL)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (sURL.Len() > 0)
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::URLComparator(sURL)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}




MasterPageContainer::Token MasterPageContainer::GetTokenForStyleName (const String& sStyleName)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (sStyleName.Len() > 0)
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::StyleNameComparator(sStyleName)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}




MasterPageContainer::Token MasterPageContainer::GetTokenForPageObject (
    const SdPage* pPage)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    Token aResult (NIL_TOKEN);
    if (pPage != NULL)
    {
        MasterPageContainerType::iterator iEntry (
            ::std::find_if (
                mpImpl->maContainer.begin(),
                mpImpl->maContainer.end(),
                MasterPageDescriptor::PageObjectComparator(pPage)));
        if (iEntry != mpImpl->maContainer.end())
            aResult = (*iEntry)->maToken;
    }
    return aResult;
}




String MasterPageContainer::GetURLForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return pDescriptor->msURL;
    else
        return String();
}




String MasterPageContainer::GetPageNameForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return pDescriptor->msPageName;
    else
        return String();
}




String MasterPageContainer::GetStyleNameForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return pDescriptor->msStyleName;
    else
        return String();
}




SdPage* MasterPageContainer::GetPageObjectForToken (
    MasterPageContainer::Token aToken,
    bool bLoad)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SdPage* pPageObject = NULL;
    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
    {
        pPageObject = pDescriptor->mpMasterPage;
        if (pPageObject == NULL)
        {
            // The page object is not (yet) present.  Call
            // UpdateDescriptor() to trigger the PageObjectProvider() to
            // provide it.
            if (bLoad)
                mpImpl->GetModel();
            if (mpImpl->UpdateDescriptor(pDescriptor,bLoad,false, true))
                pPageObject = pDescriptor->mpMasterPage;
        }
    }
    return pPageObject;
}




MasterPageContainer::Origin MasterPageContainer::GetOriginForToken (Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return pDescriptor->meOrigin;
    else
        return UNKNOWN;
}




sal_Int32 MasterPageContainer::GetTemplateIndexForToken (Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    SharedMasterPageDescriptor pDescriptor = mpImpl->GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return pDescriptor->mnTemplateIndex;
    else
        return -1;
}




SharedMasterPageDescriptor MasterPageContainer::GetDescriptorForToken (
    MasterPageContainer::Token aToken)
{
    const ::osl::MutexGuard aGuard (mpImpl->maMutex);

    return mpImpl->GetDescriptor(aToken);
}



void MasterPageContainer::InvalidatePreview (MasterPageContainer::Token aToken)
{
    mpImpl->InvalidatePreview(aToken);
}




Image MasterPageContainer::GetPreviewForToken (MasterPageContainer::Token aToken)
{
    return mpImpl->GetPreviewForToken(aToken,mePreviewSize);
}




MasterPageContainer::PreviewState MasterPageContainer::GetPreviewState (Token aToken)
{
    return mpImpl->GetPreviewState(aToken);
}




bool MasterPageContainer::RequestPreview (Token aToken)
{
    return mpImpl->RequestPreview(aToken);
}




//==== Implementation ================================================

MasterPageContainer::Implementation::Implementation (void)
    : maMutex(),
      maContainer(),
	  meInitializationState(NOT_INITIALIZED),
      mpRequestQueue(NULL),
      mxModel(NULL),
      mpDocument(NULL),
      maPreviewRenderer(),
      mbFirstPageObjectSeen(false),
      maLargePreviewBeingCreated(),
      maSmallPreviewBeingCreated(),
      maLargePreviewNotAvailable(),
      maSmallPreviewNotAvailable(),
      maChangeListeners(),
      maSmallPreviewSizePixel(),
      maLargePreviewSizePixel(),
      mbPageRatioKnown(false),
      mbContainerCleaningPending(true)

{
    UpdatePreviewSizePixel();
}




MasterPageContainer::Implementation::~Implementation (void)
{
    // When the initializer or filler tasks are still running then we have
    // to stop them now in order to prevent them from calling us back.
    tools::TimerBasedTaskExecution::ReleaseTask(mpFillerTask);

    mpRequestQueue.reset();

    uno::Reference<util::XCloseable> xCloseable (mxModel, uno::UNO_QUERY);
    if (xCloseable.is())
    {
        try
        {
            xCloseable->close(true);
        }
        catch (::com::sun::star::util::CloseVetoException aException)
        {
        }
    }
    mxModel = NULL;
}




void MasterPageContainer::Implementation::LateInit (void)
{
    const ::osl::MutexGuard aGuard (maMutex);

    if (meInitializationState == NOT_INITIALIZED)
    {
        meInitializationState = INITIALIZING;

        OSL_ASSERT(Instance().get()==this);
        mpRequestQueue.reset(MasterPageContainerQueue::Create(
            ::boost::shared_ptr<MasterPageContainerQueue::ContainerAdapter>(Instance())));

        mpFillerTask = ::sd::tools::TimerBasedTaskExecution::Create(
            ::boost::shared_ptr<tools::AsynchronousTask>(new MasterPageContainerFiller(*this)),
            5,
            50);

        meInitializationState = INITIALIZED;
    }
}




void MasterPageContainer::Implementation::AddChangeListener (const Link& rLink)
{
    const ::osl::MutexGuard aGuard (maMutex);

    ::std::vector<Link>::iterator iListener (
        ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
    if (iListener == maChangeListeners.end())
        maChangeListeners.push_back(rLink);

}




void MasterPageContainer::Implementation::RemoveChangeListener (const Link& rLink)
{
    const ::osl::MutexGuard aGuard (maMutex);

    ::std::vector<Link>::iterator iListener (
        ::std::find(maChangeListeners.begin(),maChangeListeners.end(),rLink));
    if (iListener != maChangeListeners.end())
        maChangeListeners.erase(iListener);
}




void MasterPageContainer::Implementation::UpdatePreviewSizePixel (void)
{
    const ::osl::MutexGuard aGuard (maMutex);

    // The default aspect ratio is 4:3
    int nWidth (4);
    int nHeight (3);

    // Search for the first entry with an existing master page.
    MasterPageContainerType::const_iterator iDescriptor;
    MasterPageContainerType::const_iterator iContainerEnd(maContainer.end());
    for (iDescriptor=maContainer.begin(); iDescriptor!=iContainerEnd; ++iDescriptor)
        if( bool(*iDescriptor) && (*iDescriptor)->mpMasterPage != NULL)
        {
            Size aPageSize ((*iDescriptor)->mpMasterPage->GetSize());
            nWidth = aPageSize.Width();
            nHeight = aPageSize.Height();
            mbFirstPageObjectSeen = true;
            break;
        }

    maSmallPreviewSizePixel.Width() = SMALL_PREVIEW_WIDTH;
    maLargePreviewSizePixel.Width() = LARGE_PREVIEW_WIDTH;

    int nNewSmallHeight ((maSmallPreviewSizePixel.Width()-2) * nHeight / nWidth + 2);
    int nNewLargeHeight ((maLargePreviewSizePixel.Width()-2) * nHeight / nWidth + 2);

    if (nNewSmallHeight!=maSmallPreviewSizePixel.Height()
        || nNewLargeHeight!=maLargePreviewSizePixel.Height())
    {
        maSmallPreviewSizePixel.Height() = nNewSmallHeight;
        maLargePreviewSizePixel.Height() = nNewLargeHeight;
        FireContainerChange(
            MasterPageContainerChangeEvent::SIZE_CHANGED,
            NIL_TOKEN);
    }
}




Size MasterPageContainer::Implementation::GetPreviewSizePixel (PreviewSize eSize) const
{
    if (eSize == SMALL)
        return maSmallPreviewSizePixel;
    else
        return maLargePreviewSizePixel;
}




IMPL_LINK(MasterPageContainer::Implementation,AsynchronousNotifyCallback, EventData*, pData)
{
    const ::osl::MutexGuard aGuard (maMutex);

    if (pData != NULL)
    {
        FireContainerChange(pData->first, pData->second, false);
        delete pData;
    }

    return 0;
}




MasterPageContainer::Token MasterPageContainer::Implementation::PutMasterPage (
    const SharedMasterPageDescriptor& rpDescriptor)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Token aResult (NIL_TOKEN);

    // Get page object and preview when that is inexpensive.
    UpdateDescriptor(rpDescriptor,false,false, false);

    // Look up the new MasterPageDescriptor and either insert it or update
    // an already existing one.
    MasterPageContainerType::iterator aEntry (
        ::std::find_if (
            maContainer.begin(),
            maContainer.end(),
            MasterPageDescriptor::AllComparator(rpDescriptor)));
    if (aEntry == maContainer.end())
    {
        // Insert a new MasterPageDescriptor.
        bool bIgnore (rpDescriptor->mpPageObjectProvider.get()==NULL
            && rpDescriptor->msURL.getLength()==0);

        if ( ! bIgnore)
        {
            if (mbContainerCleaningPending)
                CleanContainer();

            aResult = maContainer.size();
            rpDescriptor->SetToken(aResult);

            // Templates are precious, i.e. we lock them so that they will
            // not be destroyed when (temporarily) no one references them.
            // They will only be deleted when the container is destroyed.
            switch (rpDescriptor->meOrigin)
            {
                case TEMPLATE:
                case DEFAULT:
                    ++rpDescriptor->mnUseCount;
                    break;

                default:
                    break;
            }

            maContainer.push_back(rpDescriptor);
            aEntry = maContainer.end()-1;

            FireContainerChange(MasterPageContainerChangeEvent::CHILD_ADDED,aResult);
        }
    }
    else
    {
        // Update an existing MasterPageDescriptor.
        aResult = (*aEntry)->maToken;
        ::std::auto_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pEventTypes(
            (*aEntry)->Update(*rpDescriptor));
        if (pEventTypes.get()!=NULL && pEventTypes->size()>0)
        {
            // One or more aspects of the descriptor have changed.  Send
            // appropriate events to the listeners.
            UpdateDescriptor(*aEntry,false,false, true);

            std::vector<MasterPageContainerChangeEvent::EventType>::const_iterator iEventType;
            for (iEventType=pEventTypes->begin(); iEventType!=pEventTypes->end(); ++iEventType)
            {
                FireContainerChange(
                    *iEventType,
                    (*aEntry)->maToken,
                    false);
            }
        }
    }

    return aResult;
}




bool MasterPageContainer::Implementation::HasToken (Token aToken) const
{
    return aToken>=0
        && (unsigned)aToken<maContainer.size()
        && maContainer[aToken].get()!=NULL;
}




const SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (
    Token aToken) const
{
    if (aToken>=0 && (unsigned)aToken<maContainer.size())
        return maContainer[aToken];
    else
        return SharedMasterPageDescriptor();
}




SharedMasterPageDescriptor MasterPageContainer::Implementation::GetDescriptor (Token aToken)
{
    if (aToken>=0 && (unsigned)aToken<maContainer.size())
        return maContainer[aToken];
    else
        return SharedMasterPageDescriptor();
}




void MasterPageContainer::Implementation::InvalidatePreview (Token aToken)
{
    const ::osl::MutexGuard aGuard (maMutex);

    SharedMasterPageDescriptor pDescriptor (GetDescriptor(aToken));
    if (pDescriptor.get() != NULL)
    {
        pDescriptor->maSmallPreview = Image();
        pDescriptor->maLargePreview = Image();
        RequestPreview(aToken);
    }
}




Image MasterPageContainer::Implementation::GetPreviewForToken (
    MasterPageContainer::Token aToken,
    PreviewSize ePreviewSize)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Image aPreview;
    PreviewState ePreviewState (GetPreviewState(aToken));

    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);

    // When the preview is missing but inexpensively creatable then do that
    // now.
    if (pDescriptor.get()!=NULL)
    {
        if (ePreviewState == PS_CREATABLE)
            if (UpdateDescriptor(pDescriptor, false,false, true))
                if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
                    ePreviewState = PS_AVAILABLE;

        switch (ePreviewState)
        {
            case PS_AVAILABLE:
                aPreview = pDescriptor->GetPreview(ePreviewSize);
                break;

            case PS_PREPARING:
                aPreview = GetPreviewSubstitution(
                    STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
                    ePreviewSize);
                break;

            case PS_CREATABLE:
                aPreview = GetPreviewSubstitution(
                    STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION,
                    ePreviewSize);
                break;

            case PS_NOT_AVAILABLE:
                aPreview = GetPreviewSubstitution(
                    STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION,
                    ePreviewSize);
                if (ePreviewSize == SMALL)
                    pDescriptor->maSmallPreview = aPreview;
                else
                    pDescriptor->maLargePreview = aPreview;
                break;
        }
    }

    return aPreview;
}




MasterPageContainer::PreviewState MasterPageContainer::Implementation::GetPreviewState (
    Token aToken) const
{
    const ::osl::MutexGuard aGuard (maMutex);

    PreviewState eState (PS_NOT_AVAILABLE);

    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
    {
        if (pDescriptor->maLargePreview.GetSizePixel().Width() != 0)
            eState = PS_AVAILABLE;
        else if (pDescriptor->mpPreviewProvider.get() != NULL)
        {
            // The preview does not exist but can be created.  When that is
            // not expensive then do it at once.
            if (mpRequestQueue->HasRequest(aToken))
                eState = PS_PREPARING;
            else
                eState = PS_CREATABLE;
        }
        else
            eState = PS_NOT_AVAILABLE;
    }

    return eState;
}




bool MasterPageContainer::Implementation::RequestPreview (Token aToken)
{
    SharedMasterPageDescriptor pDescriptor = GetDescriptor(aToken);
    if (pDescriptor.get() != NULL)
        return mpRequestQueue->RequestPreview(pDescriptor);
    else
        return false;
}




Reference<frame::XModel> MasterPageContainer::Implementation::GetModel (void)
{
    const ::osl::MutexGuard aGuard (maMutex);

    if ( ! mxModel.is())
    {
        // Get the desktop a s service factory.
        ::rtl::OUString sDesktopServiceName (
            RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop"));
        uno::Reference<frame::XComponentLoader> xDesktop (
            ::comphelper::getProcessServiceFactory()->createInstance(
                sDesktopServiceName),
            uno::UNO_QUERY);

        // Create a new model.
        ::rtl::OUString sModelServiceName (
            RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.presentation.PresentationDocument"));
        mxModel = uno::Reference<frame::XModel>(
            ::comphelper::getProcessServiceFactory()->createInstance(
                sModelServiceName),
            uno::UNO_QUERY);

        // Initialize the model.
        uno::Reference<frame::XLoadable> xLoadable (mxModel,uno::UNO_QUERY);
        if (xLoadable.is())
            xLoadable->initNew();

        // Use its tunnel to get a pointer to its core implementation.
        uno::Reference<lang::XUnoTunnel> xUnoTunnel (mxModel, uno::UNO_QUERY);
        if (xUnoTunnel.is())
        {
            mpDocument = reinterpret_cast<SdXImpressDocument*>(
                xUnoTunnel->getSomething(
                    SdXImpressDocument::getUnoTunnelId()))->GetDoc();
        }

        // Create a default page.
        uno::Reference<drawing::XDrawPagesSupplier> xSlideSupplier (mxModel, uno::UNO_QUERY);
        if (xSlideSupplier.is())
        {
            uno::Reference<drawing::XDrawPages> xSlides (
                xSlideSupplier->getDrawPages(), uno::UNO_QUERY);
            if (xSlides.is())
            {
                sal_Int32 nIndex (0);
                uno::Reference<drawing::XDrawPage> xNewPage (xSlides->insertNewByIndex(nIndex));
                uno::Reference<beans::XPropertySet> xProperties(xNewPage, uno::UNO_QUERY);
                if (xProperties.is())
                    xProperties->setPropertyValue(
                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Layout")),
                        makeAny((sal_Int16)AUTOLAYOUT_TITLE));
            }
        }
    }
    return mxModel;
}




SdDrawDocument* MasterPageContainer::Implementation::GetDocument (void)
{
    GetModel();
    return mpDocument;
}




Image MasterPageContainer::Implementation::GetPreviewSubstitution (
    sal_uInt16 nId,
    PreviewSize ePreviewSize)
{
    const ::osl::MutexGuard aGuard (maMutex);

    Image aPreview;

    switch (nId)
    {
        case STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION:
        {
            Image& rPreview (ePreviewSize==SMALL
                ? maSmallPreviewBeingCreated
                : maLargePreviewBeingCreated);
            if (rPreview.GetSizePixel().Width() == 0)
            {
                rPreview = maPreviewRenderer.RenderSubstitution(
                    ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
                    SdResId(STR_TASKPANEL_PREPARING_PREVIEW_SUBSTITUTION));
            }
            aPreview = rPreview;
        }
        break;

        case STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION:
        {
            Image& rPreview (ePreviewSize==SMALL
                ? maSmallPreviewNotAvailable
                : maLargePreviewNotAvailable);
            if (rPreview.GetSizePixel().Width() == 0)
            {
                rPreview = maPreviewRenderer.RenderSubstitution(
                    ePreviewSize==SMALL ? maSmallPreviewSizePixel : maLargePreviewSizePixel,
                    SdResId(STR_TASKPANEL_NOT_AVAILABLE_SUBSTITUTION));
            }
            aPreview = rPreview;
        }
        break;
    }

    return aPreview;
}




void MasterPageContainer::Implementation::CleanContainer (void)
{
    // Remove the empty elements at the end of the container.  The empty
    // elements in the middle can not be removed because that would
    // invalidate the references still held by others.
    int nIndex (maContainer.size()-1);
    while (nIndex>=0 && maContainer[nIndex].get()==NULL)
        --nIndex;
    maContainer.resize(++nIndex);
}




void MasterPageContainer::Implementation::FireContainerChange (
    MasterPageContainerChangeEvent::EventType eType,
    Token aToken,
    bool bNotifyAsynchronously)
{
    if (bNotifyAsynchronously)
    {
        Application::PostUserEvent(
            LINK(this,Implementation,AsynchronousNotifyCallback),
            new EventData(eType,aToken));
    }
    else
    {
        ::std::vector<Link> aCopy(maChangeListeners.begin(),maChangeListeners.end());
        ::std::vector<Link>::iterator iListener;
        MasterPageContainerChangeEvent aEvent;
        aEvent.meEventType = eType;
        aEvent.maChildToken = aToken;
        for (iListener=aCopy.begin(); iListener!=aCopy.end(); ++iListener)
            iListener->Call(&aEvent);
    }
}




bool MasterPageContainer::Implementation::UpdateDescriptor (
    const SharedMasterPageDescriptor& rpDescriptor,
    bool bForcePageObject,
    bool bForcePreview,
    bool bSendEvents)
{
    const ::osl::MutexGuard aGuard (maMutex);

    // We have to create the page object when the preview provider needs it
    // and the caller needs the preview.
    bForcePageObject |= (bForcePreview
        && rpDescriptor->mpPreviewProvider->NeedsPageObject()
        && rpDescriptor->mpMasterPage==NULL);

    // Define a cost threshold so that an update or page object or preview
    // that is at least this cost are made at once. Updates with higher cost
    // are scheduled for later.
    sal_Int32 nCostThreshold (mpRequestQueue->IsEmpty() ? 5 : 0);

    // Update the page object (which may be used for the preview update).
    if (bForcePageObject)
        GetDocument();
    bool bPageObjectModified (rpDescriptor->UpdatePageObject(
        (bForcePageObject ? -1 : nCostThreshold),
        mpDocument));
    if (bPageObjectModified && bSendEvents)
        FireContainerChange(
            MasterPageContainerChangeEvent::DATA_CHANGED,
            rpDescriptor->maToken);
    if (bPageObjectModified && ! mbFirstPageObjectSeen)
        UpdatePreviewSizePixel();

    // Update the preview.
    bool bPreviewModified (rpDescriptor->UpdatePreview(
        (bForcePreview ? -1 : nCostThreshold),
        maSmallPreviewSizePixel,
        maLargePreviewSizePixel,
        maPreviewRenderer));

    if (bPreviewModified && bSendEvents)
        FireContainerChange(
            MasterPageContainerChangeEvent::PREVIEW_CHANGED,
            rpDescriptor->maToken);

    return bPageObjectModified || bPreviewModified;
}




void MasterPageContainer::Implementation::ReleaseDescriptor (Token aToken)
{
    if (aToken>=0 && (unsigned)aToken<maContainer.size())
    {
        maContainer[aToken].reset();
        mbContainerCleaningPending = true;
    }
}




void MasterPageContainer::Implementation::FillingDone (void)
{
    mpRequestQueue->ProcessAllRequests();
}



} } // end of namespace sd::sidebar
