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

#include "PresenterPaneContainer.hxx"
#include <com/sun/star/awt/InvalidateStyle.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <boost/bind.hpp>

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

namespace sdext { namespace presenter {

PresenterPaintManager::PresenterPaintManager (
    const css::uno::Reference<css::awt::XWindow>& rxParentWindow,
    const css::uno::Reference<css::drawing::XPresenterHelper>& rxPresenterHelper,
    const rtl::Reference<PresenterPaneContainer>& rpPaneContainer)
    : mxParentWindow(rxParentWindow),
      mxParentWindowPeer(rxParentWindow, UNO_QUERY),
      mxPresenterHelper(rxPresenterHelper),
      mpPaneContainer(rpPaneContainer)
{
}




::boost::function<void(const css::awt::Rectangle& rRepaintBox)>
    PresenterPaintManager::GetInvalidator (
        const css::uno::Reference<css::awt::XWindow>& rxWindow,
        const bool bSynchronous)
{
    return ::boost::bind(
        static_cast<void (PresenterPaintManager::*)(
            const css::uno::Reference<css::awt::XWindow>&,
            const css::awt::Rectangle&,
            const bool)>(&PresenterPaintManager::Invalidate),
        this,
        rxWindow,
        _1,
        bSynchronous);
}




void PresenterPaintManager::Invalidate (
    const css::uno::Reference<css::awt::XWindow>& rxWindow,
    const bool bSynchronous)
{
    sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN);
    if (bSynchronous)
        nInvalidateMode |= awt::InvalidateStyle::UPDATE;

    PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
        mpPaneContainer->FindContentWindow(rxWindow));
    if (pDescriptor.get()==NULL || ! pDescriptor->mbIsOpaque)
        nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT;
    else
        nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT;

    Invalidate(rxWindow, nInvalidateMode);
}




void PresenterPaintManager::Invalidate (
    const css::uno::Reference<css::awt::XWindow>& rxWindow,
    const sal_Int16 nInvalidateFlags)
{
    if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0)
    {
        // Window is transparent and parent window(s) have to be painted as
        // well.  Invalidate the parent explicitly.
        if (mxPresenterHelper.is() && mxParentWindowPeer.is())
        {
            const awt::Rectangle aBBox (
                mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow));
            mxParentWindowPeer->invalidateRect(aBBox, nInvalidateFlags);
        }
    }
    else
    {
        Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY);
        if (xPeer.is())
            xPeer->invalidate(nInvalidateFlags);
    }
}




void PresenterPaintManager::Invalidate (
    const css::uno::Reference<css::awt::XWindow>& rxWindow,
    const css::awt::Rectangle& rRepaintBox,
    const bool bSynchronous)
{
    sal_Int16 nInvalidateMode (awt::InvalidateStyle::CHILDREN);
    if (bSynchronous)
        nInvalidateMode |= awt::InvalidateStyle::UPDATE;

    PresenterPaneContainer::SharedPaneDescriptor pDescriptor(
        mpPaneContainer->FindContentWindow(rxWindow));
    if (pDescriptor.get()==NULL || ! pDescriptor->mbIsOpaque)
        nInvalidateMode |= awt::InvalidateStyle::TRANSPARENT;
    else
        nInvalidateMode |= awt::InvalidateStyle::NOTRANSPARENT;

    Invalidate(rxWindow, rRepaintBox, nInvalidateMode);
}




void PresenterPaintManager::Invalidate (
    const css::uno::Reference<css::awt::XWindow>& rxWindow,
    const css::awt::Rectangle& rRepaintBox,
    const sal_Int16 nInvalidateFlags)
{
    if ((nInvalidateFlags & awt::InvalidateStyle::TRANSPARENT) != 0)
    {
        // Window is transparent and parent window(s) have to be painted as
        // well.  Invalidate the parent explicitly.
        if (mxPresenterHelper.is() && mxParentWindowPeer.is())
        {
            const awt::Rectangle aBBox (
                mxPresenterHelper->getWindowExtentsRelative(rxWindow, mxParentWindow));
            mxParentWindowPeer->invalidateRect(
                awt::Rectangle(
                    rRepaintBox.X + aBBox.X,
                    rRepaintBox.Y + aBBox.Y,
                    rRepaintBox.Width,
                    rRepaintBox.Height),
                nInvalidateFlags);
        }
    }
    else
    {
        Reference<awt::XWindowPeer> xPeer (rxWindow, UNO_QUERY);
        if (xPeer.is())
            xPeer->invalidateRect(rRepaintBox, nInvalidateFlags);
    }
}

} }
