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

#include <vcl/bitmap.hxx>
#include <editeng/frmdiritem.hxx>
#include <svx/pageitem.hxx>
#include <svx/pagectrl.hxx>
#include <editeng/boxitem.hxx>
#include <algorithm>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <drawinglayer/processor2d/processor2dtools.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

// STATIC DATA -----------------------------------------------------------

#define CELL_WIDTH		1600L
#define CELL_HEIGHT		 800L

// class SvxPageWindow ---------------------------------------------------

SvxPageWindow::SvxPageWindow(Window* pParent,const ResId& rId)
: Window(pParent,rId),
    aWinSize(),
    aSize(),

    nTop(0),
    nBottom(0),
    nLeft(0),
    nRight(0),

    //UUUU
    pBorder(0),
    bResetBackground(sal_False),
    bFrameDirection(sal_False),
    nFrameDirection(0),

    nHdLeft(0),
    nHdRight(0),
    nHdDist(0),
    nHdHeight(0),

    pHdBorder(0),
    nFtLeft(0),
    nFtRight(0),
    nFtDist(0),
    nFtHeight(0),

    pFtBorder(0),

    maHeaderFillAttributes(),
    maFooterFillAttributes(),
    maPageFillAttributes(),

    bFooter(sal_False),
    bHeader(sal_False),
    bTable(sal_False),
    bHorz(sal_False),
    bVert(sal_False),
    eUsage(SVX_PAGE_ALL),

    aLeftText(),
    aRightText()

{
    // defaultmaessing in Twips rechnen
    SetMapMode(MapMode(MAP_TWIP));
    aWinSize = GetOutputSizePixel();
    aWinSize.Height() -= 4;
    aWinSize.Width() -= 4;

    aWinSize = PixelToLogic(aWinSize);
    SetBackground();
}

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

SvxPageWindow::~SvxPageWindow()
{
    delete pHdBorder;
    delete pFtBorder;
}

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

void __EXPORT SvxPageWindow::Paint(const Rectangle&)
{
    Fraction aXScale(aWinSize.Width(),std::max((long)(aSize.Width() * 2 + aSize.Width() / 8),1L));
    Fraction aYScale(aWinSize.Height(),std::max(aSize.Height(),1L));
    MapMode aMapMode(GetMapMode());

    if(aYScale < aXScale)
    {
        aMapMode.SetScaleX(aYScale);
        aMapMode.SetScaleY(aYScale);
    }
    else
    {
        aMapMode.SetScaleX(aXScale);
        aMapMode.SetScaleY(aXScale);
    }
    SetMapMode(aMapMode);
    Size aSz(PixelToLogic(GetSizePixel()));
    long nYPos = (aSz.Height() - aSize.Height()) / 2;

    if(eUsage == SVX_PAGE_ALL)
    {
        // alle Seiten gleich -> eine Seite malen
        if(aSize.Width() > aSize.Height())
        {
            // Querformat in gleicher Gr"osse zeichnen
            Fraction aX = aMapMode.GetScaleX();
            Fraction aY = aMapMode.GetScaleY();
            Fraction a2(1.5);
            aX *= a2;
            aY *= a2;
            aMapMode.SetScaleX(aX);
            aMapMode.SetScaleY(aY);
            SetMapMode(aMapMode);
            aSz = PixelToLogic(GetSizePixel());
            nYPos = (aSz.Height() - aSize.Height()) / 2;
            long nXPos = (aSz.Width() - aSize.Width()) / 2;
            DrawPage(Point(nXPos,nYPos),sal_True,sal_True);
        }
        else
            // Hochformat
            DrawPage(Point((aSz.Width() - aSize.Width()) / 2,nYPos),sal_True,sal_True);
    }
    else
    {
        // Linke und rechte Seite unterschiedlich -> ggf. zwei Seiten malen
        DrawPage(Point(0,nYPos),sal_False,(sal_Bool)(eUsage & SVX_PAGE_LEFT));
        DrawPage(Point(aSize.Width() + aSize.Width() / 8,nYPos),sal_True,
            (sal_Bool)(eUsage & SVX_PAGE_RIGHT));
    }
}

// -----------------------------------------------------------------------
void SvxPageWindow::DrawPage(const Point& rOrg,const sal_Bool bSecond,const sal_Bool bEnabled)
{
    const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    const Color& rFieldColor = rStyleSettings.GetFieldColor();
    const Color& rFieldTextColor = rStyleSettings.GetFieldTextColor();
    const Color& rDisableColor = rStyleSettings.GetDisableColor();
    const Color& rDlgColor = rStyleSettings.GetDialogColor();

    // background
    if(!bSecond || bResetBackground)
    {
        SetLineColor(Color(COL_TRANSPARENT));
        SetFillColor(rDlgColor);
        Size winSize(GetOutputSize());
        DrawRect(Rectangle(Point(0,0),winSize));

        if(bResetBackground)
            bResetBackground = sal_False;
    }
    SetLineColor(rFieldTextColor);
    // Schatten
    Size aTempSize = aSize;
    // Seite
    if(!bEnabled)
    {
        SetFillColor(rDisableColor);
        DrawRect(Rectangle(rOrg,aTempSize));
        return;
    }
    SetFillColor(rFieldColor);
    DrawRect(Rectangle(rOrg,aTempSize));

    // Border Top Bottom Left Right
    Point aBegin(rOrg);
    Point aEnd(rOrg);

    long nL = nLeft;
    long nR = nRight;

    if(eUsage == SVX_PAGE_MIRROR && !bSecond)
    {
        // f"ur gespiegelt drehen
        nL = nRight;
        nR = nLeft;
    }

    Rectangle aRect;

    aRect.Left() = rOrg.X() + nL;
    aRect.Right() = rOrg.X() + aTempSize.Width() - nR;
    aRect.Top() = rOrg.Y() + nTop;
    aRect.Bottom() = rOrg.Y() + aTempSize.Height() - nBottom;

    Rectangle aHdRect(aRect);
    Rectangle aFtRect(aRect);

    if(bHeader || bFooter)
    {
        //UUUU Header and/or footer used
        const Color aLineColor(GetLineColor());

        //UUUU draw PageFill first and on the whole page, no outline
        SetLineColor();
        drawFillAttributes(maPageFillAttributes, aRect, aRect);
        SetLineColor(aLineColor);

        if(bHeader)
        {
            // ggf. Header anzeigen
            aHdRect.Left() += nHdLeft;
            aHdRect.Right() -= nHdRight;
            aHdRect.Bottom() = aRect.Top() + nHdHeight;
            aRect.Top() += nHdHeight + nHdDist;

            // draw header over PageFill, plus outline
            drawFillAttributes(maHeaderFillAttributes, aHdRect, aHdRect);
        }

        if(bFooter)
        {
            // ggf. Footer anzeigen
            aFtRect.Left() += nFtLeft;
            aFtRect.Right() -= nFtRight;
            aFtRect.Top() = aRect.Bottom() - nFtHeight;
            aRect.Bottom() -= nFtHeight + nFtDist;

            // draw footer over PageFill, plus outline
            drawFillAttributes(maFooterFillAttributes, aFtRect, aFtRect);
        }

        // draw page's reduced outline, only outline
        drawFillAttributes(drawinglayer::attribute::SdrAllFillAttributesHelperPtr(), aRect, aRect);
    }
    else
    {
        //UUUU draw PageFill and outline
        drawFillAttributes(maPageFillAttributes, aRect, aRect);
    }

    if(bFrameDirection && !bTable)
    {
        //pImpl->nFrameDirection
        Point aPos;
        Font aFont(GetFont());
        const Size aSaveSize = aFont.GetSize();
        Size aDrawSize(0,aRect.GetHeight() / 6);
        aFont.SetSize(aDrawSize);
        SetFont(aFont);
        String sText(String::CreateFromAscii("ABC"));
        Point aMove(1,GetTextHeight());
        sal_Unicode cArrow = 0x2193;
        long nAWidth = GetTextWidth(String(sText.GetChar(0)));
        switch(nFrameDirection)
        {
        case FRMDIR_HORI_LEFT_TOP:
            aPos = aRect.TopLeft();
            aPos.X() += PixelToLogic(Point(1,1)).X();
            aMove.Y() = 0;
            cArrow = 0x2192;
            break;
        case FRMDIR_HORI_RIGHT_TOP:
            aPos = aRect.TopRight();
            aPos.X() -= nAWidth;
            aMove.Y() = 0;
            aMove.X() *= -1;
            cArrow = 0x2190;
            break;
        case FRMDIR_VERT_TOP_LEFT:
            aPos = aRect.TopLeft();
            aPos.X() += PixelToLogic(Point(1,1)).X();
            aMove.X() = 0;
            break;
        case FRMDIR_VERT_TOP_RIGHT:
            aPos = aRect.TopRight();
            aPos.X() -= nAWidth;
            aMove.X() = 0;
            break;
        }
        sText.Append(cArrow);
        for(sal_uInt16 i = 0; i < sText.Len(); i++)
        {
            String sDraw(sText.GetChar(i));
            long nHDiff = 0;
            long nCharWidth = GetTextWidth(sDraw);
            sal_Bool bHorizontal = 0 == aMove.Y();
            if(!bHorizontal)
            {
                nHDiff = (nAWidth - nCharWidth) / 2;
                aPos.X() += nHDiff;
            }
            DrawText(aPos,sDraw);
            if(bHorizontal)
            {
                aPos.X() += aMove.X() < 0 ? -nCharWidth : nCharWidth;
            }
            else
            {
                aPos.X() -= nHDiff;
                aPos.Y() += aMove.Y();
            }
        }
        aFont.SetSize(aSaveSize);
        SetFont(aFont);

    }
    if(bTable)
    {
        // Tabelle malen, ggf. zentrieren
        SetLineColor(Color(COL_LIGHTGRAY));

        long nW = aRect.GetWidth(),nH = aRect.GetHeight();
        long nTW = CELL_WIDTH * 3,nTH = CELL_HEIGHT * 3;
        long _nLeft = bHorz ? aRect.Left() + ((nW - nTW) / 2) : aRect.Left();
        long _nTop = bVert ? aRect.Top() + ((nH - nTH) / 2) : aRect.Top();
        Rectangle aCellRect(Point(_nLeft,_nTop),Size(CELL_WIDTH,CELL_HEIGHT));

        for(sal_uInt16 i = 0; i < 3; ++i)
        {
            aCellRect.Left() = _nLeft;
            aCellRect.Right() = _nLeft + CELL_WIDTH;
            if(i > 0)
                aCellRect.Move(0,CELL_HEIGHT);

            for(sal_uInt16 j = 0; j < 3; ++j)
            {
                if(j > 0)
                    aCellRect.Move(CELL_WIDTH,0);
                DrawRect(aCellRect);
            }
        }
    }
}

//UUUU
void SvxPageWindow::drawFillAttributes(
    const drawinglayer::attribute::SdrAllFillAttributesHelperPtr& rFillAttributes,
    const Rectangle& rPaintRange,
    const Rectangle& rDefineRange)
{
    const basegfx::B2DRange aPaintRange(
        rPaintRange.Left(),
        rPaintRange.Top(),
        rPaintRange.Right(),
        rPaintRange.Bottom());

    if(!aPaintRange.isEmpty() &&
        !basegfx::fTools::equalZero(aPaintRange.getWidth()) &&
        !basegfx::fTools::equalZero(aPaintRange.getHeight()))
    {
        const basegfx::B2DRange aDefineRange(
            rDefineRange.Left(),
            rDefineRange.Top(),
            rDefineRange.Right(),
            rDefineRange.Bottom());

        // prepare primitive sequence
        drawinglayer::primitive2d::Primitive2DSequence aSequence;

        // create fill geometry if there is something to fill
        if(rFillAttributes.get() && rFillAttributes->isUsed())
        {
            aSequence = rFillAttributes->getPrimitive2DSequence(
                aPaintRange,
                aDefineRange);
        }

        // create line geometry if a LineColor is set at the target device
        if(IsLineColor())
        {
            const drawinglayer::primitive2d::Primitive2DReference xOutline(
                new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
                    basegfx::tools::createPolygonFromRect(aPaintRange),
                    GetLineColor().getBColor()));

            drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(
                aSequence,
                xOutline);
        }

        // draw that if we have something to draw
        if(aSequence.getLength())
        {
            const drawinglayer::geometry::ViewInformation2D aViewInformation2D(
                basegfx::B2DHomMatrix(),
                GetViewTransformation(),
                aPaintRange,
                0,
                0.0,
                com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >());
            drawinglayer::processor2d::BaseProcessor2D* pProcessor = drawinglayer::processor2d::createProcessor2DFromOutputDevice(
                *this,
                aViewInformation2D);

            if(pProcessor)
            {
                pProcessor->process(aSequence);

                delete pProcessor;
            }
        }
    }
}

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

void SvxPageWindow::SetBorder(const SvxBoxItem& rNew)
{
    delete pBorder;
    pBorder = new SvxBoxItem(rNew);
}

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

void SvxPageWindow::SetHdBorder(const SvxBoxItem& rNew)
{
    delete pHdBorder;
    pHdBorder = new SvxBoxItem(rNew);
}
// -----------------------------------------------------------------------

void SvxPageWindow::SetFtBorder(const SvxBoxItem& rNew)
{
    delete pFtBorder;
    pFtBorder = new SvxBoxItem(rNew);
}

void SvxPageWindow::EnableFrameDirection(sal_Bool bEnable)
{
    bFrameDirection = bEnable;
}

void SvxPageWindow::SetFrameDirection(sal_Int32 nDirection)
{
    nFrameDirection = nDirection;
}

void SvxPageWindow::ResetBackground()
{
    bResetBackground = sal_True;
}

//eof
