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

#include "precompiled_sd.hxx"

#include "PresenterPreviewCache.hxx"

#include "cache/SlsCacheContext.hxx"
#include "tools/IdleDetection.hxx"
#include "sdpage.hxx"
#include <cppcanvas/vclfactory.hxx>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <com/sun/star/rendering/XBitmapCanvas.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::sd::slidesorter::cache;
using ::rtl::OUString;

namespace sd { namespace presenter {


class PresenterPreviewCache::PresenterCacheContext : public CacheContext
{
public:
    PresenterCacheContext (void);
    virtual ~PresenterCacheContext (void);

    void SetDocumentSlides (
        const Reference<container::XIndexAccess>& rxSlides,
        const Reference<XInterface>& rxDocument);
    void SetVisibleSlideRange (
        const sal_Int32 nFirstVisibleSlideIndex,
        const sal_Int32 nLastVisibleSlideIndex);
    const SdrPage* GetPage (const sal_Int32 nSlideIndex) const;
    void AddPreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);
    void RemovePreviewCreationNotifyListener (const Reference<drawing::XSlidePreviewCacheListener>& rxListener);

    // CacheContext
    virtual void NotifyPreviewCreation (
        CacheKey aKey,
        const Bitmap& rPreview);
    virtual bool IsIdle (void);
    virtual bool IsVisible (CacheKey aKey);
    virtual const SdrPage* GetPage (CacheKey aKey);
    virtual ::boost::shared_ptr<std::vector<CacheKey> > GetEntryList (bool bVisible);
    virtual sal_Int32 GetPriority (CacheKey aKey);
    virtual ::com::sun::star::uno::Reference<com::sun::star::uno::XInterface> GetModel (void);

private:
    Reference<container::XIndexAccess> mxSlides;
    Reference<XInterface> mxDocument;
    sal_Int32 mnFirstVisibleSlideIndex;
    sal_Int32 mnLastVisibleSlideIndex;
    typedef ::std::vector<css::uno::Reference<css::drawing::XSlidePreviewCacheListener> > ListenerContainer;
    ListenerContainer maListeners;

    void CallListeners (const sal_Int32 nSlideIndex);
};




//===== Service ===============================================================

Reference<XInterface> SAL_CALL PresenterPreviewCache_createInstance (
    const Reference<XComponentContext>& rxContext)
{
    return Reference<XInterface>(static_cast<XWeak*>(new PresenterPreviewCache(rxContext)));
}




::rtl::OUString PresenterPreviewCache_getImplementationName (void) throw(RuntimeException)
{
    return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterPreviewCache");
}




Sequence<rtl::OUString> SAL_CALL PresenterPreviewCache_getSupportedServiceNames (void)
    throw (RuntimeException)
{
	static const ::rtl::OUString sServiceName(
        ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterPreviewCache"));
	return Sequence<rtl::OUString>(&sServiceName, 1);
}




//===== PresenterPreviewCache =================================================

PresenterPreviewCache::PresenterPreviewCache (const Reference<XComponentContext>& rxContext)
    : PresenterPreviewCacheInterfaceBase(m_aMutex),
      maPreviewSize(Size(200,200)),
      mpCacheContext(new PresenterCacheContext()),
      mpCache(new PageCache(maPreviewSize, false, mpCacheContext))
{
    (void)rxContext;
}




PresenterPreviewCache::~PresenterPreviewCache (void)
{
}




//----- XInitialize -----------------------------------------------------------

void SAL_CALL PresenterPreviewCache::initialize (const Sequence<Any>& rArguments)
    throw(Exception, RuntimeException)
{
    if (rArguments.getLength() != 0)
        throw RuntimeException();
}




//----- XSlidePreviewCache ----------------------------------------------------

void SAL_CALL PresenterPreviewCache::setDocumentSlides (
    const Reference<container::XIndexAccess>& rxSlides,
    const Reference<XInterface>& rxDocument)
    throw (RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCacheContext.get()!=NULL);

    mpCacheContext->SetDocumentSlides(rxSlides, rxDocument);
}




void SAL_CALL PresenterPreviewCache::setVisibleRange (
    sal_Int32 nFirstVisibleSlideIndex,
    sal_Int32 nLastVisibleSlideIndex)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCacheContext.get()!=NULL);

    mpCacheContext->SetVisibleSlideRange (nFirstVisibleSlideIndex, nLastVisibleSlideIndex);
}




void SAL_CALL PresenterPreviewCache::setPreviewSize (
    const css::geometry::IntegerSize2D& rSize)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCache.get()!=NULL);

    maPreviewSize = Size(rSize.Width, rSize.Height);
    mpCache->ChangeSize(maPreviewSize, false);
}




Reference<rendering::XBitmap> SAL_CALL PresenterPreviewCache::getSlidePreview (
    sal_Int32 nSlideIndex,
    const Reference<rendering::XCanvas>& rxCanvas)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCacheContext.get()!=NULL);

    cppcanvas::BitmapCanvasSharedPtr pCanvas (
        cppcanvas::VCLFactory::getInstance().createCanvas(
            Reference<rendering::XBitmapCanvas>(rxCanvas, UNO_QUERY)));

    const SdrPage* pPage = mpCacheContext->GetPage(nSlideIndex);
    if (pPage == NULL)
        throw RuntimeException();

    const BitmapEx aPreview (mpCache->GetPreviewBitmap(pPage,true));
    if (aPreview.IsEmpty())
        return NULL;
    else
        return cppcanvas::VCLFactory::getInstance().createBitmap(
            pCanvas,
            aPreview)->getUNOBitmap();
}




void SAL_CALL PresenterPreviewCache::addPreviewCreationNotifyListener (
    const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
    throw (css::uno::RuntimeException)
{
	if (rBHelper.bDisposed || rBHelper.bInDispose)
        return;
    if (rxListener.is())
        mpCacheContext->AddPreviewCreationNotifyListener(rxListener);
}




void SAL_CALL PresenterPreviewCache::removePreviewCreationNotifyListener (
    const css::uno::Reference<css::drawing::XSlidePreviewCacheListener>& rxListener)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    mpCacheContext->RemovePreviewCreationNotifyListener(rxListener);
}




void SAL_CALL PresenterPreviewCache::pause (void)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCache.get()!=NULL);
    mpCache->Pause();
}




void SAL_CALL PresenterPreviewCache::resume (void)
    throw (css::uno::RuntimeException)
{
    ThrowIfDisposed();
    OSL_ASSERT(mpCache.get()!=NULL);
    mpCache->Resume();
}




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

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




//===== PresenterPreviewCache::PresenterCacheContext ==========================


PresenterPreviewCache::PresenterCacheContext::PresenterCacheContext (void)
    : mxSlides(),
      mxDocument(),
      mnFirstVisibleSlideIndex(-1),
      mnLastVisibleSlideIndex(-1),
      maListeners()
{
}




PresenterPreviewCache::PresenterCacheContext::~PresenterCacheContext (void)
{
}




void PresenterPreviewCache::PresenterCacheContext::SetDocumentSlides (
    const Reference<container::XIndexAccess>& rxSlides,
    const Reference<XInterface>& rxDocument)
{
    mxSlides = rxSlides;
    mxDocument = rxDocument;
    mnFirstVisibleSlideIndex = -1;
    mnLastVisibleSlideIndex = -1;
}




void PresenterPreviewCache::PresenterCacheContext::SetVisibleSlideRange (
    const sal_Int32 nFirstVisibleSlideIndex,
    const sal_Int32 nLastVisibleSlideIndex)
{
    if (nFirstVisibleSlideIndex > nLastVisibleSlideIndex || nFirstVisibleSlideIndex<0)
    {
        mnFirstVisibleSlideIndex = -1;
        mnLastVisibleSlideIndex = -1;
    }
    else
    {
        mnFirstVisibleSlideIndex = nFirstVisibleSlideIndex;
        mnLastVisibleSlideIndex = nLastVisibleSlideIndex;
    }
    if (mxSlides.is() && mnLastVisibleSlideIndex >= mxSlides->getCount())
        mnLastVisibleSlideIndex = mxSlides->getCount() - 1;
}




void PresenterPreviewCache::PresenterCacheContext::AddPreviewCreationNotifyListener (
    const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
{
    maListeners.push_back(rxListener);
}




void PresenterPreviewCache::PresenterCacheContext::RemovePreviewCreationNotifyListener (
    const Reference<drawing::XSlidePreviewCacheListener>& rxListener)
{
    ListenerContainer::iterator iListener;
    for (iListener=maListeners.begin(); iListener!=maListeners.end(); ++iListener)
        if (*iListener == rxListener)
        {
            maListeners.erase(iListener);
            return;
        }
}




//----- CacheContext ----------------------------------------------------------

void PresenterPreviewCache::PresenterCacheContext::NotifyPreviewCreation (
    CacheKey aKey,
    const Bitmap& rPreview)
{
    (void)rPreview;
    
    if ( ! mxSlides.is())
        return;
    const sal_Int32 nCount(mxSlides->getCount());
    for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
        if (aKey == GetPage(nIndex))
            CallListeners(nIndex);
}




bool PresenterPreviewCache::PresenterCacheContext::IsIdle (void)
{
    return true;
    /*
    sal_Int32 nIdleState (tools::IdleDetection::GetIdleState(NULL));
    if (nIdleState == tools::IdleDetection::IDET_IDLE)
        return true;
    else
        return false;
    */
}




bool PresenterPreviewCache::PresenterCacheContext::IsVisible (CacheKey aKey)
{
    if (mnFirstVisibleSlideIndex < 0)
        return false;
    for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
    {
        const SdrPage* pPage = GetPage(nIndex);
        if (pPage == static_cast<const SdrPage*>(aKey))
            return true;
    }
    return false;
}




const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (CacheKey aKey)
{
    return static_cast<const SdrPage*>(aKey);
}




::boost::shared_ptr<std::vector<CacheKey> >
    PresenterPreviewCache::PresenterCacheContext::GetEntryList (bool bVisible)
{
    ::boost::shared_ptr<std::vector<CacheKey> > pKeys (new std::vector<CacheKey>());
    
    if ( ! mxSlides.is())
        return pKeys;
    
    const sal_Int32 nFirstIndex (bVisible ? mnFirstVisibleSlideIndex : 0);
    const sal_Int32 nLastIndex (bVisible ? mnLastVisibleSlideIndex : mxSlides->getCount()-1);

    if (nFirstIndex < 0)
        return pKeys;

    for (sal_Int32 nIndex=nFirstIndex; nIndex<=nLastIndex; ++nIndex)
    {
        pKeys->push_back(GetPage(nIndex));
    }

    return pKeys;
}




sal_Int32 PresenterPreviewCache::PresenterCacheContext::GetPriority (CacheKey aKey)
{
    if ( ! mxSlides.is())
        return 0;

    const sal_Int32 nCount (mxSlides->getCount());
    
    for (sal_Int32 nIndex=mnFirstVisibleSlideIndex; nIndex<=mnLastVisibleSlideIndex; ++nIndex)
        if (aKey == GetPage(nIndex))
            return -nCount-1+nIndex;
    
    for (sal_Int32 nIndex=0; nIndex<=nCount; ++nIndex)
        if (aKey == GetPage(nIndex))
            return nIndex;

    return 0;
}




Reference<XInterface> PresenterPreviewCache::PresenterCacheContext::GetModel (void)
{
    return mxDocument;
}




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

const SdrPage* PresenterPreviewCache::PresenterCacheContext::GetPage (
    const sal_Int32 nSlideIndex) const
{
    if ( ! mxSlides.is())
        return NULL;
    if (nSlideIndex < 0 || nSlideIndex >= mxSlides->getCount())
        return NULL;

    Reference<drawing::XDrawPage> xSlide (mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
    const SdPage* pPage = SdPage::getImplementation(xSlide);
    return dynamic_cast<const SdrPage*>(pPage);
}




void PresenterPreviewCache::PresenterCacheContext::CallListeners (
    const sal_Int32 nIndex)
{
    ListenerContainer aListeners (maListeners);
    ListenerContainer::const_iterator iListener;
    for (iListener=aListeners.begin(); iListener!=aListeners.end(); ++iListener)
    {
        try
        {
            (*iListener)->notifyPreviewCreation(nIndex);
        }
        catch (lang::DisposedException&)
        {
            RemovePreviewCreationNotifyListener(*iListener);
        }
    }
}

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