/**************************************************************
 * 
 * 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 "PresenterPaneBorderPainter.hxx"
#include "PresenterCanvasHelper.hxx"
#include "PresenterConfigurationAccess.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterTheme.hxx"
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/awt/Point.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/awt/SimpleFontMetric.hpp>
#include <com/sun/star/awt/XFont.hpp>
#include <com/sun/star/drawing/XPresenterHelper.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/graphic/XGraphicRenderer.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <com/sun/star/rendering/FillRule.hpp>
#include <com/sun/star/rendering/TextDirection.hpp>
#include <com/sun/star/rendering/XIntegerBitmap.hpp>
#include <com/sun/star/rendering/XSpriteCanvas.hpp>
#include <map>
#include <vector>
#include <boost/shared_ptr.hpp>

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

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

namespace sdext { namespace presenter {

namespace {
    class BorderSize
    {
    public:
        BorderSize (void);
        BorderSize (const BorderSize& rBorderSize);
        BorderSize& operator= (const BorderSize& rBoderSize);
        sal_Int32 mnLeft;
        sal_Int32 mnTop;
        sal_Int32 mnRight;
        sal_Int32 mnBottom;
    };

    class RendererPaneStyle
    {
    public:
        RendererPaneStyle (
            const ::boost::shared_ptr<PresenterTheme>& rpTheme,
            const OUString& rsStyleName);

        awt::Rectangle AddBorder (
            const awt::Rectangle& rBox,
            drawing::framework::BorderType eBorderType) const;
        awt::Rectangle RemoveBorder (
            const awt::Rectangle& rBox,
            drawing::framework::BorderType eBorderType) const;
        const Reference<rendering::XCanvasFont> GetFont (
            const Reference<rendering::XCanvas>& rxCanvas) const;
        
        SharedBitmapDescriptor mpTopLeft;
        SharedBitmapDescriptor mpTop;
        SharedBitmapDescriptor mpTopRight;
        SharedBitmapDescriptor mpLeft;
        SharedBitmapDescriptor mpRight;
        SharedBitmapDescriptor mpBottomLeft;
        SharedBitmapDescriptor mpBottom;
        SharedBitmapDescriptor mpBottomRight;
        SharedBitmapDescriptor mpBottomCallout;
        SharedBitmapDescriptor mpBackground;
        SharedBitmapDescriptor mpEmpty;
        PresenterTheme::SharedFontDescriptor mpFont;
        sal_Int32 mnFontXOffset;
        sal_Int32 mnFontYOffset;
        enum Anchor { AnchorLeft, AnchorRight, AnchorCenter } meFontAnchor;
        BorderSize maInnerBorderSize;
        BorderSize maOuterBorderSize;
        BorderSize maTotalBorderSize;
        enum Side { Left, Top, Right, Bottom };
    private:
        void UpdateBorderSizes (void);
        SharedBitmapDescriptor GetBitmap(
            const ::boost::shared_ptr<PresenterTheme>& rpTheme,
            const OUString& rsStyleName,
            const OUString& rsBitmapName);
    };
}



class  PresenterPaneBorderPainter::Renderer
{
public:
    Renderer (
        const Reference<XComponentContext>& rxContext,
        const ::boost::shared_ptr<PresenterTheme>& rpTheme);
    ~Renderer (void);
        
    void SetCanvas (const Reference<rendering::XCanvas>& rxCanvas);
    void PaintBorder (
        const OUString& rsTitle,
        const awt::Rectangle& rBBox,
        const awt::Rectangle& rUpdateBox,
        const OUString& rsPaneURL);
    void PaintTitle (
        const OUString& rsTitle,
        const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
        const awt::Rectangle& rUpdateBox,
        const awt::Rectangle& rOuterBox,
        const awt::Rectangle& rInnerBox,
        const bool bPaintBackground);
    void SetupClipping (
        const awt::Rectangle& rUpdateBox,
        const awt::Rectangle& rOuterBox,
        const OUString& rsPaneStyleName);
    ::boost::shared_ptr<RendererPaneStyle> GetRendererPaneStyle (const OUString& rsResourceURL);
    void SetCalloutAnchor (
        const awt::Point& rCalloutAnchor);
        
private:
    ::boost::shared_ptr<PresenterTheme> mpTheme;
    typedef ::std::map<OUString, ::boost::shared_ptr<RendererPaneStyle> > RendererPaneStyleContainer;
    RendererPaneStyleContainer maRendererPaneStyles;
    Reference<rendering::XCanvas> mxCanvas;
    Reference<drawing::XPresenterHelper> mxPresenterHelper;
    css::rendering::ViewState maViewState;
    Reference<rendering::XPolyPolygon2D> mxViewStateClip;
    bool mbHasCallout;
    awt::Point maCalloutAnchor;
    
    void PaintBitmap(
        const awt::Rectangle& rBox,
        const awt::Rectangle& rUpdateBox,
        const sal_Int32 nXPosition,
        const sal_Int32 nYPosition,
        const sal_Int32 nStartOffset,
        const sal_Int32 nEndOffset,
        const bool bExpand,
        const SharedBitmapDescriptor& rpBitmap,
        const SharedBitmapDescriptor& rpBackgroundBitmap);
};




// ===== PresenterPaneBorderPainter ===========================================
    
PresenterPaneBorderPainter::PresenterPaneBorderPainter (
    const Reference<XComponentContext>& rxContext)
    : PresenterPaneBorderPainterInterfaceBase(m_aMutex),
      mxContext(rxContext),
      mpTheme(),
      mpRenderer()
{
}




PresenterPaneBorderPainter::~PresenterPaneBorderPainter (void)
{
}




//----- XPaneBorderPainter ----------------------------------------------------

awt::Rectangle SAL_CALL PresenterPaneBorderPainter::addBorder (
    const rtl::OUString& rsPaneBorderStyleName,
    const css::awt::Rectangle& rRectangle,
    drawing::framework::BorderType eBorderType)
    throw(css::uno::RuntimeException)
{
    ThrowIfDisposed();
    
    ProvideTheme();

    return AddBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
}




awt::Rectangle SAL_CALL PresenterPaneBorderPainter::removeBorder (
    const rtl::OUString& rsPaneBorderStyleName,
    const css::awt::Rectangle& rRectangle,
    drawing::framework::BorderType eBorderType)
    throw(css::uno::RuntimeException)
{
    ThrowIfDisposed();
    
    ProvideTheme();

    return RemoveBorder(rsPaneBorderStyleName, rRectangle, eBorderType);
}




void SAL_CALL PresenterPaneBorderPainter::paintBorder (
    const rtl::OUString& rsPaneBorderStyleName,
    const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
    const css::awt::Rectangle& rOuterBorderRectangle,
    const css::awt::Rectangle& rRepaintArea,
    const rtl::OUString& rsTitle)
    throw(css::uno::RuntimeException)
{
    ThrowIfDisposed();

    // Early reject paints completely outside the repaint area.
    if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
        || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
        || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
        || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
    {
        return;
    }
    ProvideTheme(rxCanvas);
    
    if (mpRenderer.get() != NULL)
    {
        mpRenderer->SetCanvas(rxCanvas);
        mpRenderer->SetupClipping(
            rRepaintArea,
            rOuterBorderRectangle,
            rsPaneBorderStyleName);
        mpRenderer->PaintBorder(
            rsTitle,
            rOuterBorderRectangle,
            rRepaintArea,
            rsPaneBorderStyleName);
    }
}




void SAL_CALL PresenterPaneBorderPainter::paintBorderWithCallout (
    const rtl::OUString& rsPaneBorderStyleName,
    const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
    const css::awt::Rectangle& rOuterBorderRectangle,
    const css::awt::Rectangle& rRepaintArea,
    const rtl::OUString& rsTitle,
    const css::awt::Point& rCalloutAnchor)
    throw(css::uno::RuntimeException)
{
    ThrowIfDisposed();

    // Early reject paints completely outside the repaint area.
    if (rRepaintArea.X >= rOuterBorderRectangle.X+rOuterBorderRectangle.Width
        || rRepaintArea.Y >= rOuterBorderRectangle.Y+rOuterBorderRectangle.Height
        || rRepaintArea.X+rRepaintArea.Width <= rOuterBorderRectangle.X
        || rRepaintArea.Y+rRepaintArea.Height <= rOuterBorderRectangle.Y)
    {
        return;
    }
    ProvideTheme(rxCanvas);
    
    if (mpRenderer.get() != NULL)
    {
        mpRenderer->SetCanvas(rxCanvas);
        mpRenderer->SetupClipping(
            rRepaintArea,
            rOuterBorderRectangle,
            rsPaneBorderStyleName);
        mpRenderer->SetCalloutAnchor(rCalloutAnchor);
        mpRenderer->PaintBorder(
            rsTitle,
            rOuterBorderRectangle,
            rRepaintArea,
            rsPaneBorderStyleName);
    }
}




awt::Point SAL_CALL PresenterPaneBorderPainter::getCalloutOffset (
    const rtl::OUString& rsPaneBorderStyleName)
    throw(css::uno::RuntimeException)
{
    ThrowIfDisposed();
    ProvideTheme();
    if (mpRenderer.get() != NULL)
    {
        const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(
            mpRenderer->GetRendererPaneStyle(rsPaneBorderStyleName));
        if (pRendererPaneStyle.get() != NULL
            && pRendererPaneStyle->mpBottomCallout.get() != NULL)
        {
            return awt::Point (
                0,
                pRendererPaneStyle->mpBottomCallout->mnHeight
                    - pRendererPaneStyle->mpBottomCallout->mnYHotSpot);
        }
    }

    return awt::Point(0,0);
}




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

bool PresenterPaneBorderPainter::ProvideTheme (const Reference<rendering::XCanvas>& rxCanvas)
{
    bool bModified (false);
    
    if ( ! mxContext.is())
        return false;

    if (mpTheme.get() != NULL)
    {
        // Check if the theme already has a canvas.
        if ( ! mpTheme->HasCanvas())
        {
            mpTheme->ProvideCanvas(rxCanvas);
            bModified = true;
        }
    }
    else
    {
        mpTheme.reset(new PresenterTheme(mxContext, OUString(), rxCanvas));
        bModified = true;
    }

    if (mpTheme.get() != NULL && bModified)
    {
        if (mpRenderer.get() == NULL)
            mpRenderer.reset(new Renderer(mxContext, mpTheme));
        else
            mpRenderer->SetCanvas(rxCanvas);
    }

    return bModified;
}




bool PresenterPaneBorderPainter::ProvideTheme (void)
{
    if (mpTheme.get() == NULL)
    {
        // Create a theme without bitmaps (no canvas => no bitmaps).
        return ProvideTheme(NULL);
    }
    else
    {
        // When there already is a theme then without a canvas we can not
        // add anything new.
        return false;
    }
}




bool PresenterPaneBorderPainter::HasTheme (void) const
{
    return mpTheme.get()!=NULL && mpRenderer.get()!=NULL;
}




void PresenterPaneBorderPainter::SetTheme (const ::boost::shared_ptr<PresenterTheme>& rpTheme)
{
    mpTheme = rpTheme;
    if (mpRenderer.get() == NULL)
        mpRenderer.reset(new Renderer(mxContext, mpTheme));
}




awt::Rectangle PresenterPaneBorderPainter::AddBorder (
    const ::rtl::OUString& rsPaneURL,
    const awt::Rectangle& rInnerBox,
    const css::drawing::framework::BorderType eBorderType) const
{
    if (mpRenderer.get() != NULL)
    {
        const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
        if (pRendererPaneStyle.get() != NULL)
            return pRendererPaneStyle->AddBorder(rInnerBox, eBorderType);
    }
    return rInnerBox;
}




awt::Rectangle PresenterPaneBorderPainter::RemoveBorder (
    const ::rtl::OUString& rsPaneURL,
    const css::awt::Rectangle& rOuterBox,
    const css::drawing::framework::BorderType eBorderType) const
{
    if (mpRenderer.get() != NULL)
    {
        const ::boost::shared_ptr<RendererPaneStyle> pRendererPaneStyle(mpRenderer->GetRendererPaneStyle(rsPaneURL));
        if (pRendererPaneStyle.get() != NULL)
            return pRendererPaneStyle->RemoveBorder(rOuterBox, eBorderType);
    }
    return rOuterBox;
}




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




//===== PresenterPaneBorderPainter::Renderer =====================================


PresenterPaneBorderPainter::Renderer::Renderer (
    const Reference<XComponentContext>& rxContext,
    const ::boost::shared_ptr<PresenterTheme>& rpTheme)
    : mpTheme(rpTheme),
      maRendererPaneStyles(),
      mxCanvas(),
      mxPresenterHelper(),
      maViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
      mxViewStateClip(),
      mbHasCallout(false),
      maCalloutAnchor()
{
    (void)rxContext;

    Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
    if (xFactory.is())
    {
        mxPresenterHelper = Reference<drawing::XPresenterHelper>(
            xFactory->createInstanceWithContext(
                OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
                rxContext),
            UNO_QUERY_THROW);
    }
}




PresenterPaneBorderPainter::Renderer::~Renderer (void)
{
}




void PresenterPaneBorderPainter::Renderer::SetCanvas (const Reference<rendering::XCanvas>& rxCanvas)
{
    if (mxCanvas != rxCanvas)
    {
        mxCanvas = rxCanvas;
    }
}




void PresenterPaneBorderPainter::Renderer::PaintBorder (
    const OUString& rsTitle,
    const awt::Rectangle& rBBox,
    const awt::Rectangle& rUpdateBox,
    const OUString& rsPaneURL)
{
    if ( ! mxCanvas.is())
        return;
    
    // Create the outer and inner border of the, ahm, border.
    ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneURL));
    if (pStyle.get() == NULL)
        return;
    
    awt::Rectangle aOuterBox (rBBox);
    awt::Rectangle aCenterBox (
        pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_OUTER_BORDER));
    awt::Rectangle aInnerBox (
        pStyle->RemoveBorder(aOuterBox, drawing::framework::BorderType_TOTAL_BORDER));

    // Prepare references for all used bitmaps.
    SharedBitmapDescriptor pTop (pStyle->mpTop);
    SharedBitmapDescriptor pTopLeft (pStyle->mpTopLeft);
    SharedBitmapDescriptor pTopRight (pStyle->mpTopRight);
    SharedBitmapDescriptor pLeft (pStyle->mpLeft);
    SharedBitmapDescriptor pRight (pStyle->mpRight);
    SharedBitmapDescriptor pBottomLeft (pStyle->mpBottomLeft);
    SharedBitmapDescriptor pBottomRight (pStyle->mpBottomRight);
    SharedBitmapDescriptor pBottom (pStyle->mpBottom);
    SharedBitmapDescriptor pBackground (pStyle->mpBackground);

    // Paint the sides.
    PaintBitmap(aCenterBox, rUpdateBox, 0,-1,
        pTopLeft->mnXOffset, pTopRight->mnXOffset, true, pTop, pBackground);
    PaintBitmap(aCenterBox, rUpdateBox, -1,0,
        pTopLeft->mnYOffset, pBottomLeft->mnYOffset, true, pLeft, pBackground);
    PaintBitmap(aCenterBox, rUpdateBox, +1,0,
        pTopRight->mnYOffset, pBottomRight->mnYOffset, true, pRight, pBackground);
    if (mbHasCallout && pStyle->mpBottomCallout->GetNormalBitmap().is())
    {
        const sal_Int32 nCalloutWidth (pStyle->mpBottomCallout->mnWidth);
        sal_Int32 nCalloutX (maCalloutAnchor.X - pStyle->mpBottomCallout->mnXHotSpot
            - (aCenterBox.X - aOuterBox.X));
        if (nCalloutX < pBottomLeft->mnXOffset + aCenterBox.X)
            nCalloutX = pBottomLeft->mnXOffset + aCenterBox.X;
        if (nCalloutX > pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width)
            nCalloutX = pBottomRight->mnXOffset + aCenterBox.X + aCenterBox.Width;
        // Paint bottom callout.
        PaintBitmap(aCenterBox, rUpdateBox, 0,+1, nCalloutX,0, false, pStyle->mpBottomCallout, pBackground);
        // Paint regular bottom bitmap left and right.
        PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
            pBottomLeft->mnXOffset, nCalloutX-aCenterBox.Width, true, pBottom, pBackground);
        PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
            nCalloutX+nCalloutWidth, pBottomRight->mnXOffset, true, pBottom, pBackground);
    }
    else
    {
        // Stretch the bottom bitmap over the full width.
        PaintBitmap(aCenterBox, rUpdateBox, 0,+1,
            pBottomLeft->mnXOffset, pBottomRight->mnXOffset, true, pBottom, pBackground);
    }

    // Paint the corners.
    PaintBitmap(aCenterBox, rUpdateBox, -1,-1, 0,0, false, pTopLeft, pBackground);
    PaintBitmap(aCenterBox, rUpdateBox, +1,-1, 0,0, false, pTopRight, pBackground);
    PaintBitmap(aCenterBox, rUpdateBox, -1,+1, 0,0, false, pBottomLeft, pBackground);
    PaintBitmap(aCenterBox, rUpdateBox, +1,+1, 0,0, false, pBottomRight, pBackground);

    // Paint the title.
    PaintTitle(rsTitle, pStyle, rUpdateBox, aOuterBox, aInnerBox, false);

    // In a double buffering environment request to make the changes visible.
    Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
    if (xSpriteCanvas.is())
        xSpriteCanvas->updateScreen(sal_False);
}




void PresenterPaneBorderPainter::Renderer::PaintTitle (
    const OUString& rsTitle,
    const ::boost::shared_ptr<RendererPaneStyle>& rpStyle,
    const awt::Rectangle& rUpdateBox,
    const awt::Rectangle& rOuterBox,
    const awt::Rectangle& rInnerBox,
    bool bPaintBackground)
{
    if ( ! mxCanvas.is())
        return;
    
    if (rsTitle.getLength() == 0)
        return;

    Reference<rendering::XCanvasFont> xFont (rpStyle->GetFont(mxCanvas));
    if ( ! xFont.is())
        return;
    
    rendering::StringContext aContext (
        rsTitle,
        0,
        rsTitle.getLength());
    Reference<rendering::XTextLayout> xLayout (xFont->createTextLayout(
        aContext,
        rendering::TextDirection::WEAK_LEFT_TO_RIGHT,
        0));
    if ( ! xLayout.is())
        return;

    geometry::RealRectangle2D aBox (xLayout->queryTextBounds());
    const double nTextHeight = aBox.Y2 - aBox.Y1;
    const double nTextWidth = aBox.X2 - aBox.X1;
    double nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
    const sal_Int32 nTitleBarHeight = rInnerBox.Y - rOuterBox.Y - 1;
    double nY = rOuterBox.Y + (nTitleBarHeight - nTextHeight) / 2 - aBox.Y1;
    if (nY >= rInnerBox.Y)
        nY = rInnerBox.Y - 1;
    switch (rpStyle->meFontAnchor)
    {
        default:
        case RendererPaneStyle::AnchorLeft:
            nX = rInnerBox.X;
            break;
        case RendererPaneStyle::AnchorRight:
            nX = rInnerBox.X + rInnerBox.Width - nTextWidth;
            break;
        case RendererPaneStyle::AnchorCenter:
            nX = rInnerBox.X + (rInnerBox.Width - nTextWidth)/2;
            break;
    }
    nX += rpStyle->mnFontXOffset;
    nY += rpStyle->mnFontYOffset;
        
    if (rUpdateBox.X >= nX+nTextWidth
        || rUpdateBox.Y >= nY+nTextHeight
        || rUpdateBox.X+rUpdateBox.Width <= nX
        || rUpdateBox.Y+rUpdateBox.Height <= nY)
    {
        return;
    }
                
    rendering::RenderState aRenderState(
        geometry::AffineMatrix2D(1,0,nX, 0,1,nY),
        NULL,
        Sequence<double>(4),
        rendering::CompositeOperation::SOURCE);
        
    if (bPaintBackground)
    {
        PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
        Sequence<Sequence<geometry::RealPoint2D> > aPolygons(1);
        aPolygons[0] = Sequence<geometry::RealPoint2D>(4);
        aPolygons[0][0] = geometry::RealPoint2D(0, -nTextHeight);
        aPolygons[0][1] = geometry::RealPoint2D(0, 0);
        aPolygons[0][2] = geometry::RealPoint2D(nTextWidth, 0);
        aPolygons[0][3] = geometry::RealPoint2D(nTextWidth, -nTextHeight);
        Reference<rendering::XPolyPolygon2D> xPolygon (
            mxCanvas->getDevice()->createCompatibleLinePolyPolygon(aPolygons), UNO_QUERY);
        if (xPolygon.is())
            xPolygon->setClosed(0, sal_True);
        mxCanvas->fillPolyPolygon(
            xPolygon,
            maViewState,
            aRenderState);
    }
    else
    {
        PresenterCanvasHelper::SetDeviceColor(
            aRenderState,
            rpStyle->mpFont->mnColor);

        mxCanvas->drawText(
            aContext,
            xFont,
            maViewState,
            aRenderState,
            rendering::TextDirection::WEAK_LEFT_TO_RIGHT);
    }
}



::boost::shared_ptr<RendererPaneStyle>
    PresenterPaneBorderPainter::Renderer::GetRendererPaneStyle (const OUString& rsResourceURL)
{
    OSL_ASSERT(mpTheme.get()!=NULL);

    RendererPaneStyleContainer::const_iterator iStyle (maRendererPaneStyles.find(rsResourceURL));
    if (iStyle == maRendererPaneStyles.end())
    {
        OUString sPaneStyleName (OUString::createFromAscii("DefaultRendererPaneStyle"));

        // Get pane layout name for resource URL.
        const OUString sStyleName (mpTheme->GetStyleName(rsResourceURL));
        if (sStyleName.getLength() > 0)
            sPaneStyleName = sStyleName;
        
        // Create a new pane style object and initialize it with bitmaps.
        ::boost::shared_ptr<RendererPaneStyle> pStyle (
            new RendererPaneStyle(mpTheme,sPaneStyleName));
        iStyle = maRendererPaneStyles.insert(
            RendererPaneStyleContainer::value_type(rsResourceURL, pStyle)).first;
    }
    if (iStyle != maRendererPaneStyles.end())
        return iStyle->second;
    else
        return ::boost::shared_ptr<RendererPaneStyle>();
}




void PresenterPaneBorderPainter::Renderer::SetCalloutAnchor (
    const awt::Point& rCalloutAnchor)
{
    mbHasCallout = true;
    maCalloutAnchor = rCalloutAnchor;
}




void PresenterPaneBorderPainter::Renderer::PaintBitmap(
    const awt::Rectangle& rBox,
    const awt::Rectangle& rUpdateBox,
    const sal_Int32 nXPosition,
    const sal_Int32 nYPosition,
    const sal_Int32 nStartOffset,
    const sal_Int32 nEndOffset,
    const bool bExpand,
    const SharedBitmapDescriptor& rpBitmap,
    const SharedBitmapDescriptor& rpBackgroundBitmap)
{
    (void)rpBackgroundBitmap;
    
    bool bUseCanvas (mxCanvas.is());
    if ( ! bUseCanvas)
        return;

    if (rpBitmap->mnWidth<=0 || rpBitmap->mnHeight<=0)
        return;

    Reference<rendering::XBitmap> xBitmap (rpBitmap->GetNormalBitmap(), UNO_QUERY);
    if ( ! xBitmap.is())
        return;

    // Calculate position, and for side bitmaps, the size.
    sal_Int32 nX = 0;
    sal_Int32 nY = 0;
    sal_Int32 nW = rpBitmap->mnWidth;
    sal_Int32 nH = rpBitmap->mnHeight;
    if (nXPosition < 0)
    {
        nX = rBox.X - rpBitmap->mnWidth + rpBitmap->mnXOffset;
    }
    else if (nXPosition > 0)
    {
        nX = rBox.X + rBox.Width + rpBitmap->mnXOffset;
    }
    else
    {
        nX = rBox.X + nStartOffset;
        if (bExpand)
            nW = rBox.Width - nStartOffset + nEndOffset;
    }

    if (nYPosition < 0)
    {
        nY = rBox.Y - rpBitmap->mnHeight + rpBitmap->mnYOffset;
    }
    else if (nYPosition > 0)
    {
        nY = rBox.Y + rBox.Height + rpBitmap->mnYOffset;
    }
    else
    {
        nY = rBox.Y + nStartOffset;
        if (bExpand)
            nH = rBox.Height - nStartOffset + nEndOffset;
    }

    // Do not paint when bitmap area does not intersect with update box.
    if (nX >= rUpdateBox.X + rUpdateBox.Width
        || nX+nW <= rUpdateBox.X
        || nY >= rUpdateBox.Y + rUpdateBox.Height
        || nY+nH <= rUpdateBox.Y)
    {
        return;
    }

    /*
    Reference<rendering::XBitmap> xMaskedBitmap (
        PresenterBitmapHelper::FillMaskedWithColor (
            mxCanvas,
            Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
            rBitmap.mxMaskBitmap,
            0x00ff0000,
            rBackgroundBitmap.maReplacementColor));
    if (xMaskedBitmap.is())
        xBitmap = xMaskedBitmap;
    else if (rBitmap.mxMaskBitmap.is() && mxPresenterHelper.is())
    {
        const static sal_Int32 nOutsideMaskColor (0x00ff0000);
        Reference<rendering::XIntegerBitmap> xMask (
            mxPresenterHelper->createMask(
                mxCanvas,
                rBitmap.mxMaskBitmap,
                nOutsideMaskColor,
                false));
        xBitmap = mxPresenterHelper->applyBitmapMaskWithColor(
            mxCanvas,
            Reference<rendering::XIntegerBitmap>(xBitmap, UNO_QUERY),
            xMask,
            rBackgroundBitmap.maReplacementColor);
    }
    */
    rendering::RenderState aRenderState (
        geometry::AffineMatrix2D(
            double(nW)/rpBitmap->mnWidth, 0, nX,
            0, double(nH)/rpBitmap->mnHeight, nY),
        NULL,
        Sequence<double>(4),
        rendering::CompositeOperation::OVER);

    if (xBitmap.is())
        mxCanvas->drawBitmap(
            xBitmap,
            maViewState,
            aRenderState);
}




void PresenterPaneBorderPainter::Renderer::SetupClipping (
    const awt::Rectangle& rUpdateBox,
    const awt::Rectangle& rOuterBox,
    const OUString& rsPaneStyleName)
{
    mxViewStateClip = NULL;
    maViewState.Clip = NULL;

    if ( ! mxCanvas.is())
        return;

    ::boost::shared_ptr<RendererPaneStyle> pStyle (GetRendererPaneStyle(rsPaneStyleName));
    if (pStyle.get() == NULL)
    {
        mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
            rUpdateBox,
            mxCanvas->getDevice());
    }
    else
    {
        awt::Rectangle aInnerBox (
            pStyle->RemoveBorder(rOuterBox, drawing::framework::BorderType_TOTAL_BORDER));
        ::std::vector<awt::Rectangle> aRectangles;
        aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, rOuterBox));
        aRectangles.push_back(PresenterGeometryHelper::Intersection(rUpdateBox, aInnerBox));
        mxViewStateClip = PresenterGeometryHelper::CreatePolygon(
            aRectangles,
            mxCanvas->getDevice());
        if (mxViewStateClip.is())
            mxViewStateClip->setFillRule(rendering::FillRule_EVEN_ODD);
    }
    maViewState.Clip = mxViewStateClip;
}    



namespace {

//===== BorderSize ============================================================

BorderSize::BorderSize (void)
    : mnLeft(0),
      mnTop(0),
      mnRight(0),
      mnBottom(0)
{
}




BorderSize::BorderSize (const BorderSize& rBorderSize)
    : mnLeft(rBorderSize.mnLeft),
      mnTop(rBorderSize.mnTop),
      mnRight(rBorderSize.mnRight),
      mnBottom(rBorderSize.mnBottom)
{
}




BorderSize& BorderSize::operator= (const BorderSize& rBorderSize)
{
    if (&rBorderSize != this)
    {
        mnLeft = rBorderSize.mnLeft;
        mnTop = rBorderSize.mnTop;
        mnRight = rBorderSize.mnRight;
        mnBottom = rBorderSize.mnBottom;
    }
    return *this;
}




//===== RendererPaneStyle  ============================================================

RendererPaneStyle::RendererPaneStyle (
    const ::boost::shared_ptr<PresenterTheme>& rpTheme,
    const OUString& rsStyleName)
    : mpTopLeft(),
      mpTop(),
      mpTopRight(),
      mpLeft(),
      mpRight(),
      mpBottomLeft(),
      mpBottom(),
      mpBottomRight(),
      mpBottomCallout(),
      mpBackground(),
      mpEmpty(new PresenterBitmapDescriptor()),
      mpFont(),
      mnFontXOffset(0),
      mnFontYOffset(0),
      meFontAnchor(AnchorCenter),
      maInnerBorderSize(),
      maOuterBorderSize(),
      maTotalBorderSize()
{
    if (rpTheme.get() != NULL)
    {
        mpTopLeft = GetBitmap(rpTheme, rsStyleName, A2S("TopLeft"));
        mpTop = GetBitmap(rpTheme, rsStyleName,  A2S("Top"));
        mpTopRight = GetBitmap(rpTheme, rsStyleName,  A2S("TopRight"));
        mpLeft = GetBitmap(rpTheme, rsStyleName, A2S("Left"));
        mpRight = GetBitmap(rpTheme, rsStyleName,  A2S("Right"));
        mpBottomLeft = GetBitmap(rpTheme, rsStyleName, A2S("BottomLeft"));
        mpBottom = GetBitmap(rpTheme, rsStyleName,  A2S("Bottom"));
        mpBottomRight = GetBitmap(rpTheme, rsStyleName,  A2S("BottomRight"));
        mpBottomCallout = GetBitmap(rpTheme, rsStyleName,  A2S("BottomCallout"));
        mpBackground = GetBitmap(rpTheme, OUString(), A2S("Background"));
            
        // Get font description.
        mpFont = rpTheme->GetFont(rsStyleName);

        OUString sAnchor (OUString::createFromAscii("Left"));
        if (mpFont.get() != NULL)
        {
            sAnchor = mpFont->msAnchor;
            mnFontXOffset = mpFont->mnXOffset;
            mnFontYOffset = mpFont->mnYOffset;
        }

        if (sAnchor == OUString::createFromAscii("Left"))
            meFontAnchor = AnchorLeft;
        else if (sAnchor == OUString::createFromAscii("Right"))
            meFontAnchor = AnchorRight;
        else if (sAnchor == OUString::createFromAscii("Center"))
            meFontAnchor = AnchorCenter;
        else
            meFontAnchor = AnchorCenter;

        // Get border sizes.
        try
        {
            ::std::vector<sal_Int32> aInnerBorder (rpTheme->GetBorderSize(rsStyleName, false));
            OSL_ASSERT(aInnerBorder.size()==4);
            maInnerBorderSize.mnLeft = aInnerBorder[0];
            maInnerBorderSize.mnTop = aInnerBorder[1];
            maInnerBorderSize.mnRight = aInnerBorder[2];
            maInnerBorderSize.mnBottom = aInnerBorder[3];

            ::std::vector<sal_Int32> aOuterBorder (rpTheme->GetBorderSize(rsStyleName, true));
            OSL_ASSERT(aOuterBorder.size()==4);
            maOuterBorderSize.mnLeft = aOuterBorder[0];
            maOuterBorderSize.mnTop = aOuterBorder[1];
            maOuterBorderSize.mnRight = aOuterBorder[2];
            maOuterBorderSize.mnBottom = aOuterBorder[3];
        }
        catch(beans::UnknownPropertyException&)
        {
            OSL_ASSERT(false);
        }
        
        UpdateBorderSizes();
    }
}





awt::Rectangle RendererPaneStyle::AddBorder (
    const awt::Rectangle& rBox,
    const drawing::framework::BorderType eBorderType) const
{
    const BorderSize* pBorderSize = NULL;
    switch (eBorderType)
    {
        case drawing::framework::BorderType_INNER_BORDER:
            pBorderSize = &maInnerBorderSize;
            break;
        case drawing::framework::BorderType_OUTER_BORDER:
            pBorderSize = &maOuterBorderSize;
            break;
        case drawing::framework::BorderType_TOTAL_BORDER:
            pBorderSize = &maTotalBorderSize;
            break;
        default:
            return rBox;
    }
    return awt::Rectangle (
        rBox.X - pBorderSize->mnLeft,
        rBox.Y - pBorderSize->mnTop,
        rBox.Width + pBorderSize->mnLeft + pBorderSize->mnRight,
        rBox.Height + pBorderSize->mnTop + pBorderSize->mnBottom);
}




awt::Rectangle RendererPaneStyle::RemoveBorder (
    const awt::Rectangle& rBox,
    const css::drawing::framework::BorderType eBorderType) const
{
    const BorderSize* pBorderSize = NULL;
    switch (eBorderType)
    {
        case drawing::framework::BorderType_INNER_BORDER:
            pBorderSize = &maInnerBorderSize;
            break;
        case drawing::framework::BorderType_OUTER_BORDER:
            pBorderSize = &maOuterBorderSize;
            break;
        case drawing::framework::BorderType_TOTAL_BORDER:
            pBorderSize = &maTotalBorderSize;
            break;
        default:
            return rBox;
    }
    return awt::Rectangle (
        rBox.X + pBorderSize->mnLeft,
        rBox.Y + pBorderSize->mnTop,
        rBox.Width - pBorderSize->mnLeft - pBorderSize->mnRight,
        rBox.Height - pBorderSize->mnTop - pBorderSize->mnBottom);
}




const Reference<rendering::XCanvasFont> RendererPaneStyle::GetFont (
    const Reference<rendering::XCanvas>& rxCanvas) const
{
    if (mpFont.get() != NULL)
        mpFont->PrepareFont(rxCanvas);
    return mpFont->mxFont;
}




void RendererPaneStyle::UpdateBorderSizes (void)
{
    maTotalBorderSize.mnLeft = maInnerBorderSize.mnLeft + maOuterBorderSize.mnLeft;
    maTotalBorderSize.mnTop = maInnerBorderSize.mnTop + maOuterBorderSize.mnTop;
    maTotalBorderSize.mnRight = maInnerBorderSize.mnRight + maOuterBorderSize.mnRight;
    maTotalBorderSize.mnBottom = maInnerBorderSize.mnBottom + maOuterBorderSize.mnBottom;
}




SharedBitmapDescriptor RendererPaneStyle::GetBitmap(
    const ::boost::shared_ptr<PresenterTheme>& rpTheme,
    const OUString& rsStyleName,
    const OUString& rsBitmapName)
{
    SharedBitmapDescriptor pDescriptor (rpTheme->GetBitmap(rsStyleName, rsBitmapName));
    if (pDescriptor.get() != NULL)
        return pDescriptor;
    else
        return mpEmpty;
}



} // end of anonymous namespace


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