/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "oox/xls/pagesettings.hxx"

#include <algorithm>
#include <set>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/sheet/XHeaderFooterContent.hpp>
#include <com/sun/star/style/GraphicLocation.hpp>
#include <com/sun/star/text/FilenameDisplayFormat.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/text/XTextContent.hpp>
#include <com/sun/star/text/XTextCursor.hpp>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include "oox/core/xmlfilterbase.hxx"
#include "oox/helper/attributelist.hxx"
#include "oox/helper/graphichelper.hxx"
#include "oox/helper/propertymap.hxx"
#include "oox/helper/propertyset.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/excelhandlers.hxx"
#include "oox/xls/stylesbuffer.hxx"
#include "oox/xls/unitconverter.hxx"

namespace oox {
namespace xls {

// ============================================================================

using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::uno;

using ::oox::core::Relations;
using ::rtl::OString;
using ::rtl::OStringBuffer;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;

// ============================================================================

namespace {

const double OOX_MARGIN_DEFAULT_LR                  = 0.748;    /// Left/right default margin in inches.
const double OOX_MARGIN_DEFAULT_TB                  = 0.984;    /// Top/bottom default margin in inches.
const double OOX_MARGIN_DEFAULT_HF                  = 0.512;    /// Header/footer default margin in inches.

const sal_uInt16 BIFF12_PRINTOPT_HORCENTER          = 0x0001;
const sal_uInt16 BIFF12_PRINTOPT_VERCENTER          = 0x0002;
const sal_uInt16 BIFF12_PRINTOPT_PRINTHEADING       = 0x0004;
const sal_uInt16 BIFF12_PRINTOPT_PRINTGRID          = 0x0008;

const sal_uInt16 BIFF12_HEADERFOOTER_DIFFEVEN       = 0x0001;
const sal_uInt16 BIFF12_HEADERFOOTER_DIFFFIRST      = 0x0002;
const sal_uInt16 BIFF12_HEADERFOOTER_SCALEDOC       = 0x0004;
const sal_uInt16 BIFF12_HEADERFOOTER_ALIGNMARGIN    = 0x0008;

const sal_uInt16 BIFF12_PAGESETUP_INROWS            = 0x0001;
const sal_uInt16 BIFF12_PAGESETUP_LANDSCAPE         = 0x0002;
const sal_uInt16 BIFF12_PAGESETUP_INVALID           = 0x0004;
const sal_uInt16 BIFF12_PAGESETUP_BLACKWHITE        = 0x0008;
const sal_uInt16 BIFF12_PAGESETUP_DRAFTQUALITY      = 0x0010;
const sal_uInt16 BIFF12_PAGESETUP_PRINTNOTES        = 0x0020;
const sal_uInt16 BIFF12_PAGESETUP_DEFAULTORIENT     = 0x0040;
const sal_uInt16 BIFF12_PAGESETUP_USEFIRSTPAGE      = 0x0080;
const sal_uInt16 BIFF12_PAGESETUP_NOTES_END         = 0x0100;   // different to BIFF flag

const sal_uInt16 BIFF12_CHARTPAGESETUP_LANDSCAPE    = 0x0001;
const sal_uInt16 BIFF12_CHARTPAGESETUP_INVALID      = 0x0002;
const sal_uInt16 BIFF12_CHARTPAGESETUP_BLACKWHITE   = 0x0004;
const sal_uInt16 BIFF12_CHARTPAGESETUP_DEFAULTORIENT= 0x0008;
const sal_uInt16 BIFF12_CHARTPAGESETUP_USEFIRSTPAGE = 0x0010;
const sal_uInt16 BIFF12_CHARTPAGESETUP_DRAFTQUALITY = 0x0020;

const sal_uInt16 BIFF_PAGESETUP_INROWS              = 0x0001;
const sal_uInt16 BIFF_PAGESETUP_PORTRAIT            = 0x0002;
const sal_uInt16 BIFF_PAGESETUP_INVALID             = 0x0004;
const sal_uInt16 BIFF_PAGESETUP_BLACKWHITE          = 0x0008;
const sal_uInt16 BIFF_PAGESETUP_DRAFTQUALITY        = 0x0010;
const sal_uInt16 BIFF_PAGESETUP_PRINTNOTES          = 0x0020;
const sal_uInt16 BIFF_PAGESETUP_DEFAULTORIENT       = 0x0040;
const sal_uInt16 BIFF_PAGESETUP_USEFIRSTPAGE        = 0x0080;
const sal_uInt16 BIFF_PAGESETUP_NOTES_END           = 0x0200;

} // namespace

// ============================================================================

PageSettingsModel::PageSettingsModel() :
    mfLeftMargin( OOX_MARGIN_DEFAULT_LR ),
    mfRightMargin( OOX_MARGIN_DEFAULT_LR ),
    mfTopMargin( OOX_MARGIN_DEFAULT_TB ),
    mfBottomMargin( OOX_MARGIN_DEFAULT_TB ),
    mfHeaderMargin( OOX_MARGIN_DEFAULT_HF ),
    mfFooterMargin( OOX_MARGIN_DEFAULT_HF ),
    mnPaperSize( 1 ),
    mnCopies( 1 ),
    mnScale( 100 ),
    mnFirstPage( 1 ),
    mnFitToWidth( 1 ),
    mnFitToHeight( 1 ),
    mnHorPrintRes( 600 ),
    mnVerPrintRes( 600 ),
    mnOrientation( XML_default ),
    mnPageOrder( XML_downThenOver ),
    mnCellComments( XML_none ),
    mnPrintErrors( XML_displayed ),
    mbUseEvenHF( false ),
    mbUseFirstHF( false ),
    mbValidSettings( true ),
    mbUseFirstPage( false ),
    mbBlackWhite( false ),
    mbDraftQuality( false ),
    mbFitToPages( false ),
    mbHorCenter( false ),
    mbVerCenter( false ),
    mbPrintGrid( false ),
    mbPrintHeadings( false )
{
}

void PageSettingsModel::setBiffPrintErrors( sal_uInt8 nPrintErrors )
{
    static const sal_Int32 spnErrorIds[] = { XML_displayed, XML_none, XML_dash, XML_NA };
    mnPrintErrors = STATIC_ARRAY_SELECT( spnErrorIds, nPrintErrors, XML_none );
}

// ============================================================================

PageSettings::PageSettings( const WorksheetHelper& rHelper ) :
    WorksheetHelper( rHelper )
{
}

void PageSettings::importPrintOptions( const AttributeList& rAttribs )
{
    maModel.mbHorCenter     = rAttribs.getBool( XML_horizontalCentered, false );
    maModel.mbVerCenter     = rAttribs.getBool( XML_verticalCentered, false );
    maModel.mbPrintGrid     = rAttribs.getBool( XML_gridLines, false );
    maModel.mbPrintHeadings = rAttribs.getBool( XML_headings, false );
}

void PageSettings::importPageMargins( const AttributeList& rAttribs )
{
    maModel.mfLeftMargin   = rAttribs.getDouble( XML_left,   OOX_MARGIN_DEFAULT_LR );
    maModel.mfRightMargin  = rAttribs.getDouble( XML_right,  OOX_MARGIN_DEFAULT_LR );
    maModel.mfTopMargin    = rAttribs.getDouble( XML_top,    OOX_MARGIN_DEFAULT_TB );
    maModel.mfBottomMargin = rAttribs.getDouble( XML_bottom, OOX_MARGIN_DEFAULT_TB );
    maModel.mfHeaderMargin = rAttribs.getDouble( XML_header, OOX_MARGIN_DEFAULT_HF );
    maModel.mfFooterMargin = rAttribs.getDouble( XML_footer, OOX_MARGIN_DEFAULT_HF );
}

void PageSettings::importPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
{
    maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
    maModel.mnPaperSize     = rAttribs.getInteger( XML_paperSize, 1 );
    maModel.mnCopies        = rAttribs.getInteger( XML_copies, 1 );
    maModel.mnScale         = rAttribs.getInteger( XML_scale, 100 );
    maModel.mnFirstPage     = rAttribs.getInteger( XML_firstPageNumber, 1 );
    maModel.mnFitToWidth    = rAttribs.getInteger( XML_fitToWidth, 1 );
    maModel.mnFitToHeight   = rAttribs.getInteger( XML_fitToHeight, 1 );
    maModel.mnHorPrintRes   = rAttribs.getInteger( XML_horizontalDpi, 600 );
    maModel.mnVerPrintRes   = rAttribs.getInteger( XML_verticalDpi, 600 );
    maModel.mnOrientation   = rAttribs.getToken( XML_orientation, XML_default );
    maModel.mnPageOrder     = rAttribs.getToken( XML_pageOrder, XML_downThenOver );
    maModel.mnCellComments  = rAttribs.getToken( XML_cellComments, XML_none );
    maModel.mnPrintErrors   = rAttribs.getToken( XML_errors, XML_displayed );
    maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
    maModel.mbUseFirstPage  = rAttribs.getBool( XML_useFirstPageNumber, false );
    maModel.mbBlackWhite    = rAttribs.getBool( XML_blackAndWhite, false );
    maModel.mbDraftQuality  = rAttribs.getBool( XML_draft, false );
}

void PageSettings::importChartPageSetup( const Relations& rRelations, const AttributeList& rAttribs )
{
    maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
    maModel.mnPaperSize     = rAttribs.getInteger( XML_paperSize, 1 );
    maModel.mnCopies        = rAttribs.getInteger( XML_copies, 1 );
    maModel.mnFirstPage     = rAttribs.getInteger( XML_firstPageNumber, 1 );
    maModel.mnHorPrintRes   = rAttribs.getInteger( XML_horizontalDpi, 600 );
    maModel.mnVerPrintRes   = rAttribs.getInteger( XML_verticalDpi, 600 );
    maModel.mnOrientation   = rAttribs.getToken( XML_orientation, XML_default );
    maModel.mbValidSettings = rAttribs.getBool( XML_usePrinterDefaults, true );
    maModel.mbUseFirstPage  = rAttribs.getBool( XML_useFirstPageNumber, false );
    maModel.mbBlackWhite    = rAttribs.getBool( XML_blackAndWhite, false );
    maModel.mbDraftQuality  = rAttribs.getBool( XML_draft, false );
}

void PageSettings::importHeaderFooter( const AttributeList& rAttribs )
{
    maModel.mbUseEvenHF  = rAttribs.getBool( XML_differentOddEven, false );
    maModel.mbUseFirstHF = rAttribs.getBool( XML_differentFirst, false );
}

void PageSettings::importHeaderFooterCharacters( const OUString& rChars, sal_Int32 nElement )
{
    switch( nElement )
    {
        case XLS_TOKEN( oddHeader ):    maModel.maOddHeader += rChars;      break;
        case XLS_TOKEN( oddFooter ):    maModel.maOddFooter += rChars;      break;
        case XLS_TOKEN( evenHeader ):   maModel.maEvenHeader += rChars;     break;
        case XLS_TOKEN( evenFooter ):   maModel.maEvenFooter += rChars;     break;
        case XLS_TOKEN( firstHeader ):  maModel.maFirstHeader += rChars;    break;
        case XLS_TOKEN( firstFooter ):  maModel.maFirstFooter += rChars;    break;
    }
}

void PageSettings::importPicture( const Relations& rRelations, const AttributeList& rAttribs )
{
    importPictureData( rRelations, rAttribs.getString( R_TOKEN( id ), OUString() ) );
}

void PageSettings::importPageMargins( SequenceInputStream& rStrm )
{
    rStrm   >> maModel.mfLeftMargin   >> maModel.mfRightMargin
            >> maModel.mfTopMargin    >> maModel.mfBottomMargin
            >> maModel.mfHeaderMargin >> maModel.mfFooterMargin;
}

void PageSettings::importPrintOptions( SequenceInputStream& rStrm )
{
    sal_uInt16 nFlags;
    rStrm >> nFlags;
    maModel.mbHorCenter     = getFlag( nFlags, BIFF12_PRINTOPT_HORCENTER );
    maModel.mbVerCenter     = getFlag( nFlags, BIFF12_PRINTOPT_VERCENTER );
    maModel.mbPrintGrid     = getFlag( nFlags, BIFF12_PRINTOPT_PRINTGRID );
    maModel.mbPrintHeadings = getFlag( nFlags, BIFF12_PRINTOPT_PRINTHEADING );
}

void PageSettings::importPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
{
    OUString aRelId;
    sal_uInt16 nFlags;
    rStrm   >> maModel.mnPaperSize >> maModel.mnScale
            >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
            >> maModel.mnCopies >> maModel.mnFirstPage
            >> maModel.mnFitToWidth >> maModel.mnFitToHeight
            >> nFlags >> aRelId;
    maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 9, 2 ) );
    maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( aRelId );
    maModel.mnOrientation   = getFlagValue( nFlags, BIFF12_PAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_PAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
    maModel.mnPageOrder     = getFlagValue( nFlags, BIFF12_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
    maModel.mnCellComments  = getFlagValue( nFlags, BIFF12_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF12_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
    maModel.mbValidSettings = !getFlag( nFlags, BIFF12_PAGESETUP_INVALID );
    maModel.mbUseFirstPage  = getFlag( nFlags, BIFF12_PAGESETUP_USEFIRSTPAGE );
    maModel.mbBlackWhite    = getFlag( nFlags, BIFF12_PAGESETUP_BLACKWHITE );
    maModel.mbDraftQuality  = getFlag( nFlags, BIFF12_PAGESETUP_DRAFTQUALITY );
}

void PageSettings::importChartPageSetup( const Relations& rRelations, SequenceInputStream& rStrm )
{
    OUString aRelId;
    sal_uInt16 nFirstPage, nFlags;
    rStrm   >> maModel.mnPaperSize >> maModel.mnHorPrintRes >> maModel.mnVerPrintRes
            >> maModel.mnCopies >> nFirstPage >> nFlags >> aRelId;
    maModel.maBinSettPath   = rRelations.getFragmentPathFromRelId( aRelId );
    maModel.mnFirstPage     = nFirstPage; // 16-bit in CHARTPAGESETUP
    maModel.mnOrientation   = getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_DEFAULTORIENT, XML_default, getFlagValue( nFlags, BIFF12_CHARTPAGESETUP_LANDSCAPE, XML_landscape, XML_portrait ) );
    maModel.mbValidSettings = !getFlag( nFlags, BIFF12_CHARTPAGESETUP_INVALID );
    maModel.mbUseFirstPage  = getFlag( nFlags, BIFF12_CHARTPAGESETUP_USEFIRSTPAGE );
    maModel.mbBlackWhite    = getFlag( nFlags, BIFF12_CHARTPAGESETUP_BLACKWHITE );
    maModel.mbDraftQuality  = getFlag( nFlags, BIFF12_CHARTPAGESETUP_DRAFTQUALITY );
}

void PageSettings::importHeaderFooter( SequenceInputStream& rStrm )
{
    sal_uInt16 nFlags;
    rStrm   >> nFlags
            >> maModel.maOddHeader   >> maModel.maOddFooter
            >> maModel.maEvenHeader  >> maModel.maEvenFooter
            >> maModel.maFirstHeader >> maModel.maFirstFooter;
    maModel.mbUseEvenHF  = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFEVEN );
    maModel.mbUseFirstHF = getFlag( nFlags, BIFF12_HEADERFOOTER_DIFFFIRST );
}

void PageSettings::importPicture( const Relations& rRelations, SequenceInputStream& rStrm )
{
    importPictureData( rRelations, BiffHelper::readString( rStrm ) );
}

void PageSettings::importLeftMargin( BiffInputStream& rStrm )
{
    rStrm >> maModel.mfLeftMargin;
}

void PageSettings::importRightMargin( BiffInputStream& rStrm )
{
    rStrm >> maModel.mfRightMargin;
}

void PageSettings::importTopMargin( BiffInputStream& rStrm )
{
    rStrm >> maModel.mfTopMargin;
}

void PageSettings::importBottomMargin( BiffInputStream& rStrm )
{
    rStrm >> maModel.mfBottomMargin;
}

void PageSettings::importPageSetup( BiffInputStream& rStrm )
{
    sal_uInt16 nPaperSize, nScale, nFirstPage, nFitToWidth, nFitToHeight, nFlags;
    rStrm >> nPaperSize >> nScale >> nFirstPage >> nFitToWidth >> nFitToHeight >> nFlags;

    maModel.mnPaperSize      = nPaperSize;   // equal in BIFF and OOX
    maModel.mnScale          = nScale;
    maModel.mnFirstPage      = nFirstPage;
    maModel.mnFitToWidth     = nFitToWidth;
    maModel.mnFitToHeight    = nFitToHeight;
    maModel.mnOrientation    = getFlagValue( nFlags, BIFF_PAGESETUP_PORTRAIT, XML_portrait, XML_landscape );
    maModel.mnPageOrder      = getFlagValue( nFlags, BIFF_PAGESETUP_INROWS, XML_overThenDown, XML_downThenOver );
    maModel.mbValidSettings  = !getFlag( nFlags, BIFF_PAGESETUP_INVALID );
    maModel.mbUseFirstPage   = true;
    maModel.mbBlackWhite     = getFlag( nFlags, BIFF_PAGESETUP_BLACKWHITE );

    if( getBiff() >= BIFF5 )
    {
        sal_uInt16 nHorPrintRes, nVerPrintRes, nCopies;
        rStrm >> nHorPrintRes >> nVerPrintRes >> maModel.mfHeaderMargin >> maModel.mfFooterMargin >> nCopies;

        maModel.mnCopies       = nCopies;
        maModel.mnOrientation  = getFlagValue( nFlags, BIFF_PAGESETUP_DEFAULTORIENT, XML_default, maModel.mnOrientation );
        maModel.mnHorPrintRes  = nHorPrintRes;
        maModel.mnVerPrintRes  = nVerPrintRes;
        maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, XML_asDisplayed, XML_none );
        maModel.mbUseFirstPage = getFlag( nFlags, BIFF_PAGESETUP_USEFIRSTPAGE );
        maModel.mbDraftQuality = getFlag( nFlags, BIFF_PAGESETUP_DRAFTQUALITY );

        if( getBiff() == BIFF8 )
        {
            maModel.setBiffPrintErrors( extractValue< sal_uInt8 >( nFlags, 10, 2 ) );
            maModel.mnCellComments = getFlagValue( nFlags, BIFF_PAGESETUP_PRINTNOTES, getFlagValue( nFlags, BIFF_PAGESETUP_NOTES_END, XML_atEnd, XML_asDisplayed ), XML_none );
        }
    }
}

void PageSettings::importHorCenter( BiffInputStream& rStrm )
{
    maModel.mbHorCenter = rStrm.readuInt16() != 0;
}

void PageSettings::importVerCenter( BiffInputStream& rStrm )
{
    maModel.mbVerCenter = rStrm.readuInt16() != 0;
}

void PageSettings::importPrintHeaders( BiffInputStream& rStrm )
{
    maModel.mbPrintHeadings = rStrm.readuInt16() != 0;
}

void PageSettings::importPrintGridLines( BiffInputStream& rStrm )
{
    maModel.mbPrintGrid = rStrm.readuInt16() != 0;
}

void PageSettings::importHeader( BiffInputStream& rStrm )
{
    if( rStrm.getRemaining() > 0 )
        maModel.maOddHeader = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
    else
        maModel.maOddHeader = OUString();
}

void PageSettings::importFooter( BiffInputStream& rStrm )
{
    if( rStrm.getRemaining() > 0 )
        maModel.maOddFooter = (getBiff() == BIFF8) ? rStrm.readUniString() : rStrm.readByteStringUC( false, getTextEncoding() );
    else
        maModel.maOddFooter = OUString();
}

void PageSettings::importPicture( BiffInputStream& rStrm )
{
    StreamDataSequence aPictureData;
    BiffHelper::importImgData( aPictureData, rStrm, getBiff() );
    maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importGraphicObject( aPictureData );
}

void PageSettings::setFitToPagesMode( bool bFitToPages )
{
    maModel.mbFitToPages = bFitToPages;
}

void PageSettings::finalizeImport()
{
    OUStringBuffer aStyleNameBuffer( CREATE_OUSTRING( "PageStyle_" ) );
    Reference< XNamed > xSheetName( getSheet(), UNO_QUERY );
    if( xSheetName.is() )
        aStyleNameBuffer.append( xSheetName->getName() );
    else
        aStyleNameBuffer.append( static_cast< sal_Int32 >( getSheetIndex() + 1 ) );
    OUString aStyleName = aStyleNameBuffer.makeStringAndClear();

    Reference< XStyle > xStyle = createStyleObject( aStyleName, true );
    PropertySet aStyleProps( xStyle );
    getPageSettingsConverter().writePageSettingsProperties( aStyleProps, maModel, getSheetType() );

    PropertySet aSheetProps( getSheet() );
    aSheetProps.setProperty( PROP_PageStyle, aStyleName );
}

void PageSettings::importPictureData( const Relations& rRelations, const OUString& rRelId )
{
    OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId );
    if( aPicturePath.getLength() > 0 )
        maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importEmbeddedGraphicObject( aPicturePath );
}

// ============================================================================
// ============================================================================

enum HFPortionId
{
    HF_LEFT,
    HF_CENTER,
    HF_RIGHT,
    HF_COUNT
};

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

struct HFPortionInfo
{
    Reference< XText >  mxText;                 /// XText interface of this portion.
    Reference< XTextCursor > mxStart;           /// Start position of current text range for formatting.
    Reference< XTextCursor > mxEnd;             /// End position of current text range for formatting.
    double              mfTotalHeight;          /// Sum of heights of previous lines in points.
    double              mfCurrHeight;           /// Height of the current text line in points.

    bool                initialize( const Reference< XText >& rxText );
};

bool HFPortionInfo::initialize( const Reference< XText >& rxText )
{
    mfTotalHeight = mfCurrHeight = 0.0;
    mxText = rxText;
    if( mxText.is() )
    {
        mxStart = mxText->createTextCursor();
        mxEnd = mxText->createTextCursor();
    }
    bool bRet = mxText.is() && mxStart.is() && mxEnd.is();
    OSL_ENSURE( bRet, "HFPortionInfo::initialize - missing interfaces" );
    return bRet;
}

// ============================================================================

class HeaderFooterParser : public WorkbookHelper
{
public:
    explicit            HeaderFooterParser( const WorkbookHelper& rHelper );

    /** Parses the passed string and creates the header/footer contents.
        @returns  The total height of the converted header or footer in points. */
    double              parse(
                            const Reference< XHeaderFooterContent >& rxContext,
                            const OUString& rData );

private:
    /** Returns the current edit engine text object. */
    inline HFPortionInfo& getPortion() { return maPortions[ meCurrPortion ]; }
    /** Returns the start cursor of the current text range. */
    inline const Reference< XTextCursor >& getStartPos() { return getPortion().mxStart; }
    /** Returns the end cursor of the current text range. */
    inline const Reference< XTextCursor >& getEndPos() { return getPortion().mxEnd; }

    /** Returns the current line height of the specified portion. */
    double              getCurrHeight( HFPortionId ePortion ) const;
    /** Returns the current line height. */
    double              getCurrHeight() const;

    /** Updates the current line height of the specified portion, using the current font size. */
    void                updateCurrHeight( HFPortionId ePortion );
    /** Updates the current line height, using the current font size. */
    void                updateCurrHeight();

    /** Sets the font attributes at the current selection. */
    void                setAttributes();
    /** Appends and clears internal string buffer. */
    void                appendText();
    /** Appends a line break and adjusts internal text height data. */
    void                appendLineBreak();

    /** Creates a text field from the passed service name. */
    Reference< XTextContent > createField( const OUString& rServiceName ) const;
    /** Appends the passed text field. */
    void                appendField( const Reference< XTextContent >& rxContent );

    /** Sets the passed font name if it is valid. */
    void                convertFontName( const OUString& rStyle );
    /** Converts a font style given as string. */
    void                convertFontStyle( const OUString& rStyle );
    /** Converts a font color given as string. */
    void                convertFontColor( const OUString& rColor );

    /** Finalizes current portion: sets font attributes and updates text height data. */
    void                finalizePortion();
    /** Changes current header/footer portion. */
    void                setNewPortion( HFPortionId ePortion );

private:
    typedef ::std::vector< HFPortionInfo >  HFPortionInfoVec;
    typedef ::std::set< OString >           OStringSet;

    const OUString      maPageNumberService;
    const OUString      maPageCountService;
    const OUString      maSheetNameService;
    const OUString      maFileNameService;
    const OUString      maDateTimeService;
    const OStringSet    maBoldNames;            /// All names for bold font style in lowercase UTF-8.
    const OStringSet    maItalicNames;          /// All names for italic font style in lowercase UTF-8.
    HFPortionInfoVec    maPortions;
    HFPortionId         meCurrPortion;          /// Identifier of current H/F portion.
    OUStringBuffer      maBuffer;               /// Text data to append to current text range.
    FontModel           maFontModel;            /// Font attributes of current text range.
};

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

namespace {

// different names for bold font style (lowercase)
static const sal_Char* const sppcBoldNames[] =
{
    "bold",
    "fett",             // German 'bold'
    "demibold",
    "halbfett",         // German 'demibold'
    "black",
    "heavy"
};

// different names for italic font style (lowercase)
static const sal_Char* const sppcItalicNames[] =
{
    "italic",
    "kursiv",           // German 'italic'
    "oblique",
    "schr\303\204g",    // German 'oblique' with uppercase A umlaut
    "schr\303\244g"     // German 'oblique' with lowercase A umlaut
};

} // namespace

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

HeaderFooterParser::HeaderFooterParser( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper ),
    maPageNumberService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageNumber" ) ),
    maPageCountService( CREATE_OUSTRING( "com.sun.star.text.TextField.PageCount" ) ),
    maSheetNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.SheetName" ) ),
    maFileNameService( CREATE_OUSTRING( "com.sun.star.text.TextField.FileName" ) ),
    maDateTimeService( CREATE_OUSTRING( "com.sun.star.text.TextField.DateTime" ) ),
    maBoldNames( sppcBoldNames, STATIC_ARRAY_END( sppcBoldNames ) ),
    maItalicNames( sppcItalicNames, STATIC_ARRAY_END( sppcItalicNames ) ),
    maPortions( static_cast< size_t >( HF_COUNT ) ),
    meCurrPortion( HF_CENTER )
{
}

double HeaderFooterParser::parse( const Reference< XHeaderFooterContent >& rxContext, const OUString& rData )
{
    if( !rxContext.is() || (rData.getLength() == 0) ||
            !maPortions[ HF_LEFT ].initialize( rxContext->getLeftText() ) ||
            !maPortions[ HF_CENTER ].initialize( rxContext->getCenterText() ) ||
            !maPortions[ HF_RIGHT ].initialize( rxContext->getRightText() ) )
        return 0.0;

    meCurrPortion = HF_CENTER;
    maBuffer.setLength( 0 );
    maFontModel = getStyles().getDefaultFontModel();
    OUStringBuffer aFontName;           // current font name
    OUStringBuffer aFontStyle;          // current font style
    sal_Int32 nFontHeight = 0;          // current font height

    /** State of the parser. */
    enum
    {
        STATE_TEXT,         /// Literal text data.
        STATE_TOKEN,        /// Control token following a '&' character.
        STATE_FONTNAME,     /// Font name ('&' is followed by '"', reads until next '"' or ',').
        STATE_FONTSTYLE,    /// Font style name (font part after ',', reads until next '"').
        STATE_FONTHEIGHT    /// Font height ('&' is followed by num. digits, reads until non-digit).
    }
    eState = STATE_TEXT;

    const sal_Unicode* pcChar = rData.getStr();
    const sal_Unicode* pcEnd = pcChar + rData.getLength();
    for( ; (pcChar != pcEnd) && (*pcChar != 0); ++pcChar )
    {
        sal_Unicode cChar = *pcChar;
        switch( eState )
        {
            case STATE_TEXT:
            {
                switch( cChar )
                {
                    case '&':           // new token
                        appendText();
                        eState = STATE_TOKEN;
                    break;
                    case '\n':          // line break
                        appendText();
                        appendLineBreak();
                    break;
                    default:
                        maBuffer.append( cChar );
                }
            }
            break;

            case STATE_TOKEN:
            {
                // default: back to text mode, may be changed in specific cases
                eState = STATE_TEXT;
                // ignore case of token codes
                if( ('a' <= cChar) && (cChar <= 'z') )
                    (cChar -= 'a') += 'A';
                switch( cChar )
                {
                    case '&':   maBuffer.append( cChar );   break;  // the '&' character

                    case 'L':   setNewPortion( HF_LEFT );   break;  // left portion
                    case 'C':   setNewPortion( HF_CENTER ); break;  // center portion
                    case 'R':   setNewPortion( HF_RIGHT );  break;  // right portion

                    case 'P':   // page number
                        appendField( createField( maPageNumberService ) );
                    break;
                    case 'N':   // total page count
                        appendField( createField( maPageCountService ) );
                    break;
                    case 'A':   // current sheet name
                        appendField( createField( maSheetNameService ) );
                    break;

                    case 'F':   // file name
                    {
                        Reference< XTextContent > xContent = createField( maFileNameService );
                        PropertySet aPropSet( xContent );
                        aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::NAME_AND_EXT );
                        appendField( xContent );
                    }
                    break;
                    case 'Z':   // file path (without file name), OOXML, BIFF12, and BIFF8 only
                        if( (getFilterType() == FILTER_OOXML) || ((getFilterType() == FILTER_BIFF) && (getBiff() == BIFF8)) )
                        {
                            Reference< XTextContent > xContent = createField( maFileNameService );
                            PropertySet aPropSet( xContent );
                            // FilenameDisplayFormat::PATH not supported by Calc
                            aPropSet.setProperty( PROP_FileFormat, ::com::sun::star::text::FilenameDisplayFormat::FULL );
                            appendField( xContent );
                            /*  path only is not supported -- if we find a '&Z&F'
                                combination for path/name, skip the '&F' part */
                            if( (pcChar + 2 < pcEnd) && (pcChar[ 1 ] == '&') && ((pcChar[ 2 ] == 'f') || (pcChar[ 2 ] == 'F')) )
                                pcChar += 2;
                        }
                    break;
                    case 'D':   // date
                    {
                        Reference< XTextContent > xContent = createField( maDateTimeService );
                        PropertySet aPropSet( xContent );
                        aPropSet.setProperty( PROP_IsDate, true );
                        appendField( xContent );
                    }
                    break;
                    case 'T':   // time
                    {
                        Reference< XTextContent > xContent = createField( maDateTimeService );
                        PropertySet aPropSet( xContent );
                        aPropSet.setProperty( PROP_IsDate, false );
                        appendField( xContent );
                    }
                    break;

                    case 'B':   // bold
                        setAttributes();
                        maFontModel.mbBold = !maFontModel.mbBold;
                    break;
                    case 'I':   // italic
                        setAttributes();
                        maFontModel.mbItalic = !maFontModel.mbItalic;
                    break;
                    case 'U':   // underline
                        setAttributes();
                        maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_single) ? XML_none : XML_single;
                    break;
                    case 'E':   // double underline
                        setAttributes();
                        maFontModel.mnUnderline = (maFontModel.mnUnderline == XML_double) ? XML_none : XML_double;
                    break;
                    case 'S':   // strikeout
                        setAttributes();
                        maFontModel.mbStrikeout = !maFontModel.mbStrikeout;
                    break;
                    case 'X':   // superscript
                        setAttributes();
                        maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_superscript) ? XML_baseline : XML_superscript;
                    break;
                    case 'Y':   // subsrcipt
                        setAttributes();
                        maFontModel.mnEscapement = (maFontModel.mnEscapement == XML_subscript) ? XML_baseline : XML_subscript;
                    break;
                    case 'O':   // outlined
                        setAttributes();
                        maFontModel.mbOutline = !maFontModel.mbOutline;
                    break;
                    case 'H':   // shadow
                        setAttributes();
                        maFontModel.mbShadow = !maFontModel.mbShadow;
                    break;

                    case 'K':   // text color (not in BIFF)
                        if( (getFilterType() == FILTER_OOXML) && (pcChar + 6 < pcEnd) )
                        {
                            setAttributes();
                            // eat the following 6 characters
                            convertFontColor( OUString( pcChar + 1, 6 ) );
                            pcChar += 6;
                        }
                    break;

                    case '\"':  // font name
                        aFontName.setLength( 0 );
                        aFontStyle.setLength( 0 );
                        eState = STATE_FONTNAME;
                    break;
                    default:
                        if( ('0' <= cChar) && (cChar <= '9') )    // font size
                        {
                            nFontHeight = cChar - '0';
                            eState = STATE_FONTHEIGHT;
                        }
                }
            }
            break;

            case STATE_FONTNAME:
            {
                switch( cChar )
                {
                    case '\"':
                        setAttributes();
                        convertFontName( aFontName.makeStringAndClear() );
                        eState = STATE_TEXT;
                    break;
                    case ',':
                        eState = STATE_FONTSTYLE;
                    break;
                    default:
                        aFontName.append( cChar );
                }
            }
            break;

            case STATE_FONTSTYLE:
            {
                switch( cChar )
                {
                    case '\"':
                        setAttributes();
                        convertFontName( aFontName.makeStringAndClear() );
                        convertFontStyle( aFontStyle.makeStringAndClear() );
                        eState = STATE_TEXT;
                    break;
                    default:
                        aFontStyle.append( cChar );
                }
            }
            break;

            case STATE_FONTHEIGHT:
            {
                if( ('0' <= cChar) && (cChar <= '9') )
                {
                    if( nFontHeight >= 0 )
                    {
                        nFontHeight *= 10;
                        nFontHeight += (cChar - '0');
                        if( nFontHeight > 1000 )
                            nFontHeight = -1;
                    }
                }
                else
                {
                    if( nFontHeight > 0 )
                    {
                        setAttributes();
                        maFontModel.mfHeight = nFontHeight;
                    }
                    --pcChar;
                    eState = STATE_TEXT;
                }
            }
            break;
        }
    }

    // finalize
    finalizePortion();
    maPortions[ HF_LEFT   ].mfTotalHeight += getCurrHeight( HF_LEFT );
    maPortions[ HF_CENTER ].mfTotalHeight += getCurrHeight( HF_CENTER );
    maPortions[ HF_RIGHT  ].mfTotalHeight += getCurrHeight( HF_RIGHT );

    return ::std::max( maPortions[ HF_LEFT ].mfTotalHeight,
        ::std::max( maPortions[ HF_CENTER ].mfTotalHeight, maPortions[ HF_RIGHT ].mfTotalHeight ) );
}

// private --------------------------------------------------------------------

double HeaderFooterParser::getCurrHeight( HFPortionId ePortion ) const
{
    double fMaxHt = maPortions[ ePortion ].mfCurrHeight;
    return (fMaxHt == 0.0) ? maFontModel.mfHeight : fMaxHt;
}

double HeaderFooterParser::getCurrHeight() const
{
    return getCurrHeight( meCurrPortion );
}

void HeaderFooterParser::updateCurrHeight( HFPortionId ePortion )
{
    double& rfMaxHt = maPortions[ ePortion ].mfCurrHeight;
    rfMaxHt = ::std::max( rfMaxHt, maFontModel.mfHeight );
}

void HeaderFooterParser::updateCurrHeight()
{
    updateCurrHeight( meCurrPortion );
}

void HeaderFooterParser::setAttributes()
{
    Reference< XTextRange > xRange( getStartPos(), UNO_QUERY );
    getEndPos()->gotoRange( xRange, sal_False );
    getEndPos()->gotoEnd( sal_True );
    if( !getEndPos()->isCollapsed() )
    {
        Font aFont( *this, maFontModel );
        aFont.finalizeImport();
        PropertySet aPropSet( getEndPos() );
        aFont.writeToPropertySet( aPropSet, FONT_PROPTYPE_TEXT );
        getStartPos()->gotoEnd( sal_False );
        getEndPos()->gotoEnd( sal_False );
    }
}

void HeaderFooterParser::appendText()
{
    if( maBuffer.getLength() > 0 )
    {
        getEndPos()->gotoEnd( sal_False );
        getEndPos()->setString( maBuffer.makeStringAndClear() );
        updateCurrHeight();
    }
}

void HeaderFooterParser::appendLineBreak()
{
    getEndPos()->gotoEnd( sal_False );
    getEndPos()->setString( OUString( sal_Unicode( '\n' ) ) );
    getPortion().mfTotalHeight += getCurrHeight();
    getPortion().mfCurrHeight = 0;
}

Reference< XTextContent > HeaderFooterParser::createField( const OUString& rServiceName ) const
{
    Reference< XTextContent > xContent;
    try
    {
        xContent.set( getBaseFilter().getModelFactory()->createInstance( rServiceName ), UNO_QUERY_THROW );
    }
    catch( Exception& )
    {
        OSL_ENSURE( false,
            OStringBuffer( "HeaderFooterParser::createField - error while creating text field \"" ).
            append( OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ) ).
            append( '"' ).getStr() );
    }
    return xContent;
}

void HeaderFooterParser::appendField( const Reference< XTextContent >& rxContent )
{
    getEndPos()->gotoEnd( sal_False );
    try
    {
        Reference< XTextRange > xRange( getEndPos(), UNO_QUERY_THROW );
        getPortion().mxText->insertTextContent( xRange, rxContent, sal_False );
        updateCurrHeight();
    }
    catch( Exception& )
    {
    }
}

void HeaderFooterParser::convertFontName( const OUString& rName )
{
    if( rName.getLength() > 0 )
    {
        // single dash is document default font
        if( (rName.getLength() == 1) && (rName[ 0 ] == '-') )
            maFontModel.maName = getStyles().getDefaultFontModel().maName;
        else
            maFontModel.maName = rName;
    }
}

void HeaderFooterParser::convertFontStyle( const OUString& rStyle )
{
    maFontModel.mbBold = maFontModel.mbItalic = false;
    sal_Int32 nPos = 0;
    sal_Int32 nLen = rStyle.getLength();
    while( (0 <= nPos) && (nPos < nLen) )
    {
        OString aToken = OUStringToOString( rStyle.getToken( 0, ' ', nPos ), RTL_TEXTENCODING_UTF8 ).toAsciiLowerCase();
        if( aToken.getLength() > 0 )
        {
            if( maBoldNames.count( aToken ) > 0 )
                maFontModel.mbBold = true;
            else if( maItalicNames.count( aToken ) > 0 )
                maFontModel.mbItalic = true;
        }
    }
}

void HeaderFooterParser::convertFontColor( const OUString& rColor )
{
    OSL_ENSURE( rColor.getLength() == 6, "HeaderFooterParser::convertFontColor - invalid font color code" );
    if( (rColor[ 2 ] == '+') || (rColor[ 2 ] == '-') )
        // theme color: TTSNNN (TT = decimal theme index, S = +/-, NNN = decimal tint/shade in percent)
        maFontModel.maColor.setTheme(
            rColor.copy( 0, 2 ).toInt32(),
            static_cast< double >( rColor.copy( 2 ).toInt32() ) / 100.0 );
    else
        // RGB color: RRGGBB
        maFontModel.maColor.setRgb( rColor.toInt32( 16 ) );
}

void HeaderFooterParser::finalizePortion()
{
    appendText();
    setAttributes();
}

void HeaderFooterParser::setNewPortion( HFPortionId ePortion )
{
    if( ePortion != meCurrPortion )
    {
        finalizePortion();
        meCurrPortion = ePortion;
        maFontModel = getStyles().getDefaultFontModel();
    }
}

// ============================================================================

namespace {

/** Paper size in 1/100 millimeters. */
struct ApiPaperSize
{
    sal_Int32           mnWidth;
    sal_Int32           mnHeight;
};

#define IN2MM100( v )    static_cast< sal_Int32 >( (v) * 2540.0 + 0.5 )
#define MM2MM100( v )    static_cast< sal_Int32 >( (v) * 100.0 + 0.5 )

static const ApiPaperSize spPaperSizeTable[] =
{
    { 0, 0 },                                                //  0 - (undefined)
    { IN2MM100( 8.5 ),       IN2MM100( 11 )      },          //  1 - Letter paper
    { IN2MM100( 8.5 ),       IN2MM100( 11 )      },          //  2 - Letter small paper
    { IN2MM100( 11 ),        IN2MM100( 17 )      },          //  3 - Tabloid paper
    { IN2MM100( 17 ),        IN2MM100( 11 )      },          //  4 - Ledger paper
    { IN2MM100( 8.5 ),       IN2MM100( 14 )      },          //  5 - Legal paper
    { IN2MM100( 5.5 ),       IN2MM100( 8.5 )     },          //  6 - Statement paper
    { IN2MM100( 7.25 ),      IN2MM100( 10.5 )    },          //  7 - Executive paper
    { MM2MM100( 297 ),       MM2MM100( 420 )     },          //  8 - A3 paper
    { MM2MM100( 210 ),       MM2MM100( 297 )     },          //  9 - A4 paper
    { MM2MM100( 210 ),       MM2MM100( 297 )     },          // 10 - A4 small paper
    { MM2MM100( 148 ),       MM2MM100( 210 )     },          // 11 - A5 paper
    { MM2MM100( 250 ),       MM2MM100( 353 )     },          // 12 - B4 paper
    { MM2MM100( 176 ),       MM2MM100( 250 )     },          // 13 - B5 paper
    { IN2MM100( 8.5 ),       IN2MM100( 13 )      },          // 14 - Folio paper
    { MM2MM100( 215 ),       MM2MM100( 275 )     },          // 15 - Quarto paper
    { IN2MM100( 10 ),        IN2MM100( 14 )      },          // 16 - Standard paper
    { IN2MM100( 11 ),        IN2MM100( 17 )      },          // 17 - Standard paper
    { IN2MM100( 8.5 ),       IN2MM100( 11 )      },          // 18 - Note paper
    { IN2MM100( 3.875 ),     IN2MM100( 8.875 )   },          // 19 - #9 envelope
    { IN2MM100( 4.125 ),     IN2MM100( 9.5 )     },          // 20 - #10 envelope
    { IN2MM100( 4.5 ),       IN2MM100( 10.375 )  },          // 21 - #11 envelope
    { IN2MM100( 4.75 ),      IN2MM100( 11 )      },          // 22 - #12 envelope
    { IN2MM100( 5 ),         IN2MM100( 11.5 )    },          // 23 - #14 envelope
    { IN2MM100( 17 ),        IN2MM100( 22 )      },          // 24 - C paper
    { IN2MM100( 22 ),        IN2MM100( 34 )      },          // 25 - D paper
    { IN2MM100( 34 ),        IN2MM100( 44 )      },          // 26 - E paper
    { MM2MM100( 110 ),       MM2MM100( 220 )     },          // 27 - DL envelope
    { MM2MM100( 162 ),       MM2MM100( 229 )     },          // 28 - C5 envelope
    { MM2MM100( 324 ),       MM2MM100( 458 )     },          // 29 - C3 envelope
    { MM2MM100( 229 ),       MM2MM100( 324 )     },          // 30 - C4 envelope
    { MM2MM100( 114 ),       MM2MM100( 162 )     },          // 31 - C6 envelope
    { MM2MM100( 114 ),       MM2MM100( 229 )     },          // 32 - C65 envelope
    { MM2MM100( 250 ),       MM2MM100( 353 )     },          // 33 - B4 envelope
    { MM2MM100( 176 ),       MM2MM100( 250 )     },          // 34 - B5 envelope
    { MM2MM100( 176 ),       MM2MM100( 125 )     },          // 35 - B6 envelope
    { MM2MM100( 110 ),       MM2MM100( 230 )     },          // 36 - Italy envelope
    { IN2MM100( 3.875 ),     IN2MM100( 7.5 )     },          // 37 - Monarch envelope
    { IN2MM100( 3.625 ),     IN2MM100( 6.5 )     },          // 38 - 6 3/4 envelope
    { IN2MM100( 14.875 ),    IN2MM100( 11 )      },          // 39 - US standard fanfold
    { IN2MM100( 8.5 ),       IN2MM100( 12 )      },          // 40 - German standard fanfold
    { IN2MM100( 8.5 ),       IN2MM100( 13 )      },          // 41 - German legal fanfold
    { MM2MM100( 250 ),       MM2MM100( 353 )     },          // 42 - ISO B4
    { MM2MM100( 200 ),       MM2MM100( 148 )     },          // 43 - Japanese double postcard
    { IN2MM100( 9 ),         IN2MM100( 11 )      },          // 44 - Standard paper
    { IN2MM100( 10 ),        IN2MM100( 11 )      },          // 45 - Standard paper
    { IN2MM100( 15 ),        IN2MM100( 11 )      },          // 46 - Standard paper
    { MM2MM100( 220 ),       MM2MM100( 220 )     },          // 47 - Invite envelope
    { 0, 0 },                                                // 48 - (undefined)
    { 0, 0 },                                                // 49 - (undefined)
    { IN2MM100( 9.275 ),     IN2MM100( 12 )      },          // 50 - Letter extra paper
    { IN2MM100( 9.275 ),     IN2MM100( 15 )      },          // 51 - Legal extra paper
    { IN2MM100( 11.69 ),     IN2MM100( 18 )      },          // 52 - Tabloid extra paper
    { MM2MM100( 236 ),       MM2MM100( 322 )     },          // 53 - A4 extra paper
    { IN2MM100( 8.275 ),     IN2MM100( 11 )      },          // 54 - Letter transverse paper
    { MM2MM100( 210 ),       MM2MM100( 297 )     },          // 55 - A4 transverse paper
    { IN2MM100( 9.275 ),     IN2MM100( 12 )      },          // 56 - Letter extra transverse paper
    { MM2MM100( 227 ),       MM2MM100( 356 )     },          // 57 - SuperA/SuperA/A4 paper
    { MM2MM100( 305 ),       MM2MM100( 487 )     },          // 58 - SuperB/SuperB/A3 paper
    { IN2MM100( 8.5 ),       IN2MM100( 12.69 )   },          // 59 - Letter plus paper
    { MM2MM100( 210 ),       MM2MM100( 330 )     },          // 60 - A4 plus paper
    { MM2MM100( 148 ),       MM2MM100( 210 )     },          // 61 - A5 transverse paper
    { MM2MM100( 182 ),       MM2MM100( 257 )     },          // 62 - JIS B5 transverse paper
    { MM2MM100( 322 ),       MM2MM100( 445 )     },          // 63 - A3 extra paper
    { MM2MM100( 174 ),       MM2MM100( 235 )     },          // 64 - A5 extra paper
    { MM2MM100( 201 ),       MM2MM100( 276 )     },          // 65 - ISO B5 extra paper
    { MM2MM100( 420 ),       MM2MM100( 594 )     },          // 66 - A2 paper
    { MM2MM100( 297 ),       MM2MM100( 420 )     },          // 67 - A3 transverse paper
    { MM2MM100( 322 ),       MM2MM100( 445 )     }           // 68 - A3 extra transverse paper
};

} // namespace

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

PageSettingsConverter::HFHelperData::HFHelperData( sal_Int32 nLeftPropId, sal_Int32 nRightPropId ) :
    mnLeftPropId( nLeftPropId ),
    mnRightPropId( nRightPropId ),
    mnHeight( 0 ),
    mnBodyDist( 0 ),
    mbHasContent( false ),
    mbShareOddEven( false ),
    mbDynamicHeight( false )
{
}

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

PageSettingsConverter::PageSettingsConverter( const WorkbookHelper& rHelper ) :
    WorkbookHelper( rHelper ),
    mxHFParser( new HeaderFooterParser( rHelper ) ),
    maHeaderData( PROP_LeftPageHeaderContent, PROP_RightPageHeaderContent ),
    maFooterData( PROP_LeftPageFooterContent, PROP_RightPageFooterContent )
{
}

PageSettingsConverter::~PageSettingsConverter()
{
}

void PageSettingsConverter::writePageSettingsProperties(
        PropertySet& rPropSet, const PageSettingsModel& rModel, WorksheetType eSheetType )
{
    // special handling for chart sheets
    bool bChartSheet = eSheetType == SHEETTYPE_CHARTSHEET;

    // printout scaling
    if( bChartSheet )
    {
        // always fit chart sheet to 1 page
        rPropSet.setProperty< sal_Int16 >( PROP_ScaleToPages, 1 );
    }
    else if( rModel.mbFitToPages )
    {
        // fit to number of pages
        rPropSet.setProperty( PROP_ScaleToPagesX, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToWidth, 0, 1000 ) );
        rPropSet.setProperty( PROP_ScaleToPagesY, getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnFitToHeight, 0, 1000 ) );
    }
    else
    {
        // scale may be 0 which indicates uninitialized
        sal_Int16 nScale = (rModel.mbValidSettings && (rModel.mnScale > 0)) ? getLimitedValue< sal_Int16, sal_Int32 >( rModel.mnScale, 10, 400 ) : 100;
        rPropSet.setProperty( PROP_PageScale, nScale );
    }

    // paper orientation
    bool bLandscape = rModel.mnOrientation == XML_landscape;
    // default orientation for current sheet type (chart sheets default to landscape)
    if( !rModel.mbValidSettings || (rModel.mnOrientation == XML_default) )
        bLandscape = bChartSheet;

    // paper size
    if( rModel.mbValidSettings && (0 < rModel.mnPaperSize) && (rModel.mnPaperSize < static_cast< sal_Int32 >( STATIC_ARRAY_SIZE( spPaperSizeTable ) )) )
    {
        const ApiPaperSize& rPaperSize = spPaperSizeTable[ rModel.mnPaperSize ];
        Size aSize( rPaperSize.mnWidth, rPaperSize.mnHeight );
        if( bLandscape )
            ::std::swap( aSize.Width, aSize.Height );
        rPropSet.setProperty( PROP_Size, aSize );
    }

    // header/footer
    convertHeaderFooterData( rPropSet, maHeaderData, rModel.maOddHeader, rModel.maEvenHeader, rModel.mbUseEvenHF, rModel.mfTopMargin,    rModel.mfHeaderMargin );
    convertHeaderFooterData( rPropSet, maFooterData, rModel.maOddFooter, rModel.maEvenFooter, rModel.mbUseEvenHF, rModel.mfBottomMargin, rModel.mfFooterMargin );

    // write all properties to property set
    const UnitConverter& rUnitConv = getUnitConverter();
    PropertyMap aPropMap;
    aPropMap[ PROP_IsLandscape ]           <<= bLandscape;
    aPropMap[ PROP_FirstPageNumber ]       <<= getLimitedValue< sal_Int16, sal_Int32 >( rModel.mbUseFirstPage ? rModel.mnFirstPage : 0, 0, 9999 );
    aPropMap[ PROP_PrintDownFirst ]        <<= (rModel.mnPageOrder == XML_downThenOver);
    aPropMap[ PROP_PrintAnnotations ]      <<= (rModel.mnCellComments == XML_asDisplayed);
    aPropMap[ PROP_CenterHorizontally ]    <<= rModel.mbHorCenter;
    aPropMap[ PROP_CenterVertically ]      <<= rModel.mbVerCenter;
    aPropMap[ PROP_PrintGrid ]             <<= (!bChartSheet && rModel.mbPrintGrid);     // no gridlines in chart sheets
    aPropMap[ PROP_PrintHeaders ]          <<= (!bChartSheet && rModel.mbPrintHeadings); // no column/row headings in chart sheets
    aPropMap[ PROP_LeftMargin ]            <<= rUnitConv.scaleToMm100( rModel.mfLeftMargin, UNIT_INCH );
    aPropMap[ PROP_RightMargin ]           <<= rUnitConv.scaleToMm100( rModel.mfRightMargin, UNIT_INCH );
    // #i23296# In Calc, "TopMargin" property is distance to top of header if enabled
    aPropMap[ PROP_TopMargin ]             <<= rUnitConv.scaleToMm100( maHeaderData.mbHasContent ? rModel.mfHeaderMargin : rModel.mfTopMargin, UNIT_INCH );
    // #i23296# In Calc, "BottomMargin" property is distance to bottom of footer if enabled
    aPropMap[ PROP_BottomMargin ]          <<= rUnitConv.scaleToMm100( maFooterData.mbHasContent ? rModel.mfFooterMargin : rModel.mfBottomMargin, UNIT_INCH );
    aPropMap[ PROP_HeaderIsOn ]            <<= maHeaderData.mbHasContent;
    aPropMap[ PROP_HeaderIsShared ]        <<= maHeaderData.mbShareOddEven;
    aPropMap[ PROP_HeaderIsDynamicHeight ] <<= maHeaderData.mbDynamicHeight;
    aPropMap[ PROP_HeaderHeight ]          <<= maHeaderData.mnHeight;
    aPropMap[ PROP_HeaderBodyDistance ]    <<= maHeaderData.mnBodyDist;
    aPropMap[ PROP_FooterIsOn ]            <<= maFooterData.mbHasContent;
    aPropMap[ PROP_FooterIsShared ]        <<= maFooterData.mbShareOddEven;
    aPropMap[ PROP_FooterIsDynamicHeight ] <<= maFooterData.mbDynamicHeight;
    aPropMap[ PROP_FooterHeight ]          <<= maFooterData.mnHeight;
    aPropMap[ PROP_FooterBodyDistance ]    <<= maFooterData.mnBodyDist;
    // background image
    if( rModel.maGraphicUrl.getLength() > 0 )
    {
        aPropMap[ PROP_BackGraphicURL ] <<= rModel.maGraphicUrl;
        aPropMap[ PROP_BackGraphicLocation ] <<= ::com::sun::star::style::GraphicLocation_TILED;
    }

    rPropSet.setProperties( aPropMap );
}

void PageSettingsConverter::convertHeaderFooterData(
        PropertySet& rPropSet, HFHelperData& orHFData,
        const OUString rOddContent, const OUString rEvenContent, bool bUseEvenContent,
        double fPageMargin, double fContentMargin )
{
    bool bHasOddContent  = rOddContent.getLength() > 0;
    bool bHasEvenContent = bUseEvenContent && (rEvenContent.getLength() > 0);

    sal_Int32 nOddHeight  = bHasOddContent  ? writeHeaderFooter( rPropSet, orHFData.mnRightPropId, rOddContent  ) : 0;
    sal_Int32 nEvenHeight = bHasEvenContent ? writeHeaderFooter( rPropSet, orHFData.mnLeftPropId,  rEvenContent ) : 0;

    orHFData.mnHeight = 750;
    orHFData.mnBodyDist = 250;
    orHFData.mbHasContent = bHasOddContent || bHasEvenContent;
    orHFData.mbShareOddEven = !bUseEvenContent;
    orHFData.mbDynamicHeight = true;

    if( orHFData.mbHasContent )
    {
        // use maximum height of odd/even header/footer
        orHFData.mnHeight = ::std::max( nOddHeight, nEvenHeight );
        /*  Calc contains distance between bottom of header and top of page
            body in "HeaderBodyDistance" property, and distance between bottom
            of page body and top of footer in "FooterBodyDistance" property */
        orHFData.mnBodyDist = getUnitConverter().scaleToMm100( fPageMargin - fContentMargin, UNIT_INCH ) - orHFData.mnHeight;
        /*  #i23296# Distance less than 0 means, header or footer overlays page
            body. As this is not possible in Calc, set fixed header or footer
            height (crop header/footer) to get correct top position of page body. */
        orHFData.mbDynamicHeight = orHFData.mnBodyDist >= 0;
        /*  "HeaderHeight" property is in fact distance from top of header to
            top of page body (including "HeaderBodyDistance").
            "FooterHeight" property is in fact distance from bottom of page
            body to bottom of footer (including "FooterBodyDistance"). */
        orHFData.mnHeight += orHFData.mnBodyDist;
        // negative body distance not allowed
        orHFData.mnBodyDist = ::std::max< sal_Int32 >( orHFData.mnBodyDist, 0 );
    }
}

sal_Int32 PageSettingsConverter::writeHeaderFooter(
        PropertySet& rPropSet, sal_Int32 nPropId, const OUString& rContent )
{
    OSL_ENSURE( rContent.getLength() > 0, "PageSettingsConverter::writeHeaderFooter - empty h/f string found" );
    sal_Int32 nHeight = 0;
    if( rContent.getLength() > 0 )
    {
        Reference< XHeaderFooterContent > xHFContent( rPropSet.getAnyProperty( nPropId ), UNO_QUERY );
        if( xHFContent.is() )
        {
            double fTotalHeight = mxHFParser->parse( xHFContent, rContent );
            rPropSet.setProperty( nPropId, xHFContent );
            nHeight = getUnitConverter().scaleToMm100( fTotalHeight, UNIT_POINT );
        }
    }
    return nHeight;
}

// ============================================================================

} // namespace xls
} // namespace oox
