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

#include "MutexOwner.hxx"
#include "ViewShellBase.hxx"
#include <com/sun/star/frame/XLayoutManager.hpp>
#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp>
#include <com/sun/star/frame/LayoutManagerEvents.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <cppuhelper/compbase1.hxx>

#include <vcl/timer.hxx>
#include <sfx2/viewfrm.hxx>

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

namespace {
typedef cppu::WeakComponentImplHelper1<frame::XLayoutManagerListener> InterfaceBase;
}

namespace sd {


/** This implementation class not only implements the Lock() and Unlock()
    methods but as well listens for the right combination of events to call
    Unlock() when all is ready after the PaneManager has switched (some of)
    its view shells.
*/

class UpdateLockManager::Implementation
    : protected MutexOwner,
      public InterfaceBase
{
public:
    Implementation (ViewShellBase& rBase);
    virtual ~Implementation (void);

    void Lock (void);
    void Unlock (void);
    bool IsLocked (void) const;

    /** Unlock regardless of the current lock level.
    */
    void ForceUnlock (void);

private:
    ViewShellBase& mrBase;
    /// A lock level greater than 0 indicates that the ViewShellBase is locked.
    sal_Int32 mnLockDepth;
    /// The emergency timer to unlock the ViewShellBase when all else fails.
    Timer maTimer;
    /// Remember when to unlock after a layout event from frame::XLayoutManager
    bool mbUnlockOnNextLayout;
    /// Remember whether we are listening to the frame::XLayoutManager
    bool mbListenerIsRegistered;
    /// Remember whether the frame::XLayoutManager is locked.
    bool mbLayouterIsLocked;
    /** We hold a weak reference to the layout manager in order to have
        access to it even when the ViewShellBase object is not valid anymore
        and can not be used to obtain the layout manager.
    */
    WeakReference<frame::XLayoutManager> mxLayoutManager;

    //=====  frame::XLayoutEventListener  =====================================

    /** The event of the layouter are observed to find the best moment for
        unlocking.  This is the first layout after the lock level of the
        layouter drops to one (we hold a lock to it ourselves which we
        release when unlocking).
    */
    virtual void SAL_CALL layoutEvent (
        const lang::EventObject& xSource,
        sal_Int16 eLayoutEvent,
        const Any& rInfo)
        throw (uno::RuntimeException);

    //=====  lang::XEventListener  ============================================
    virtual void SAL_CALL
        disposing (const lang::EventObject& rEventObject)
        throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL disposing (void);

    /** This is only a fallback to make the office usable when for some
        reason the intended way of unlocking it failed.
    */
    DECL_LINK(Timeout, void*);

    /** Convenience method that finds the layout manager associated with the
        frame that shows the ViewShellBase.
    */
    Reference<frame::XLayoutManager> GetLayoutManager (void);

    Implementation (const Implementation&); // Not implemented.
    Implementation& operator= (const Implementation&); // Not implemented.
};




//===== UpdateLockManager =====================================================

UpdateLockManager::UpdateLockManager (ViewShellBase& rBase)
    : mpImpl(new Implementation(rBase))
{
    mpImpl->acquire();
}



UpdateLockManager::~UpdateLockManager (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
    }
}




void UpdateLockManager::Disable (void)
{
    if (mpImpl != NULL)
    {
        mpImpl->ForceUnlock();
        mpImpl->release();
        mpImpl = NULL;
    }
}




void UpdateLockManager::Lock (void)
{
    if (mpImpl != NULL)
        mpImpl->Lock();
}




void UpdateLockManager::Unlock (void)
{
    if (mpImpl != NULL)
        mpImpl->Unlock();
}




bool UpdateLockManager::IsLocked (void) const
{
    if (mpImpl != NULL)
        return mpImpl->IsLocked();
    else
        return false;
}



//===== UpdateLock::Implementation ============================================

UpdateLockManager::Implementation::Implementation (ViewShellBase& rBase)
    : InterfaceBase(maMutex),
      mrBase(rBase),
      mnLockDepth(0),
      maTimer(),
      mbUnlockOnNextLayout(false),
      mbListenerIsRegistered(false),
      mbLayouterIsLocked(false)
{
}




UpdateLockManager::Implementation::~Implementation (void)
{
    OSL_ASSERT(mnLockDepth==0);
    ForceUnlock();
}




void UpdateLockManager::Implementation::Lock (void)
{
    ++mnLockDepth;
    if (mnLockDepth == 1)
    {
        Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
        if (xLayouter.is())
        {
            // Register as event listener.
            Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                xLayouter, UNO_QUERY);
            if (xBroadcaster.is())
            {
                mbListenerIsRegistered = true;
                xBroadcaster->addLayoutManagerEventListener(
                    Reference<frame::XLayoutManagerListener> (
                        static_cast<XWeak*>(this), UNO_QUERY) );
            }

            // Lock the layout manager.
            mbLayouterIsLocked = true;
            xLayouter->lock();
        }

        // As a fallback, when the notification mechanism does not work (or is
        // incorrectly used) we use a timer that will unlock us eventually.
        maTimer.SetTimeout(5000 /*ms*/);
        maTimer.SetTimeoutHdl(LINK(this,UpdateLockManager::Implementation,Timeout));
        maTimer.Start();
    }
}




void UpdateLockManager::Implementation::Unlock (void)
{
    --mnLockDepth;

    if (mnLockDepth == 0)
    {
        // Stop the timer.  We don't need it anymore.
        maTimer.Stop();

        try
        {
            Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
            if (xLayouter.is())
            {
                // Detach from the layouter.
                if (mbListenerIsRegistered)
                {
                    Reference<frame::XLayoutManagerEventBroadcaster> xBroadcaster (
                        xLayouter, UNO_QUERY);
                    if (xBroadcaster.is())
                    {
                        mbListenerIsRegistered = false;
                        xBroadcaster->removeLayoutManagerEventListener(
                            Reference<frame::XLayoutManagerListener> (
                                static_cast<XWeak*>(this), UNO_QUERY) );
                    }
                }

                // Unlock the layouter.
                if (mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        catch (RuntimeException)
        { }

        // Force a rearrangement of the UI elements of the views.
        mrBase.Rearrange();
    }
}




bool UpdateLockManager::Implementation::IsLocked (void) const
{
    return (mnLockDepth > 0);
}




void UpdateLockManager::Implementation::ForceUnlock (void)
{
    while (IsLocked())
        Unlock();
}




void SAL_CALL UpdateLockManager::Implementation::layoutEvent (
    const lang::EventObject&,
    sal_Int16 eLayoutEvent,
    const Any& rInfo)
    throw (uno::RuntimeException)
{
    switch (eLayoutEvent)
    {
        case frame::LayoutManagerEvents::LOCK:
        {
            sal_Int32 nLockCount;
            rInfo >>= nLockCount;
        }
        break;

        case frame::LayoutManagerEvents::UNLOCK:
        {
            sal_Int32 nLockCount = 0;
            rInfo >>= nLockCount;
            if (nLockCount == 1)
            {
                // The lock count dropped to one.  This means that we are
                // the only one that still holds a lock to the layout
                // manager.  We unlock the layout manager now and the
                // ViewShellBase on the next layout of the layout manager.
                mbUnlockOnNextLayout = true;
                Reference<frame::XLayoutManager> xLayouter (GetLayoutManager());
                if (xLayouter.is() && mbLayouterIsLocked)
                {
                    mbLayouterIsLocked = false;
                    xLayouter->unlock();
                }
            }
        }
        break;

        case frame::LayoutManagerEvents::LAYOUT:
            // Unlock when the layout manager is not still locked.
            if (mbUnlockOnNextLayout)
                Unlock();
            break;
    }
}




void SAL_CALL UpdateLockManager::Implementation::disposing (const lang::EventObject& )
    throw (::com::sun::star::uno::RuntimeException)
{
}




void SAL_CALL UpdateLockManager::Implementation::disposing (void)
{
}




IMPL_LINK(UpdateLockManager::Implementation, Timeout, void*, EMPTYARG)
{
    // This method is only called when all else failed.  We unlock
    // regardless of how deep the lock depth.
    while (mnLockDepth > 0)
        Unlock();
    return 1;
}




Reference< ::com::sun::star::frame::XLayoutManager>
    UpdateLockManager::Implementation::GetLayoutManager (void)
{
    Reference<frame::XLayoutManager> xLayoutManager;

    if (mxLayoutManager.get() == NULL)
    {
        if (mrBase.GetViewFrame()!=NULL)
        {
            Reference<beans::XPropertySet> xFrameProperties (
                mrBase.GetViewFrame()->GetFrame().GetFrameInterface(),
                UNO_QUERY);
            if (xFrameProperties.is())
            {
                try
                {
                    Any aValue (xFrameProperties->getPropertyValue(
                        ::rtl::OUString::createFromAscii("LayoutManager")));
                    aValue >>= xLayoutManager;
                }
                catch (const beans::UnknownPropertyException& rException)
                {
                    (void)rException;
                }
            }
            mxLayoutManager = xLayoutManager;
        }
    }
    else
        xLayoutManager = mxLayoutManager;

    return xLayoutManager;
}




} // end of anonymous namespace
