/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#include <PropertyMap.hxx>
#include <ooxml/resourceids.hxx>
#include <DomainMapper_Impl.hxx>
#include <ConversionHelper.hxx>
#include <i18npool/paper.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/style/BreakType.hpp>
#include <com/sun/star/text/RelOrientation.hpp>
#include <com/sun/star/text/WritingMode.hpp>
#include <com/sun/star/text/XTextColumns.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/text/TextGridMode.hpp>
#include <com/sun/star/text/XTextCopy.hpp>
#include "dmapperLoggers.hxx"
#include "PropertyMapHelper.hxx"

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

namespace writerfilter {
namespace dmapper{

/*-- 21.06.2006 09:30:56---------------------------------------------------

  -----------------------------------------------------------------------*/
PropertyMap::PropertyMap() :
    m_cFootnoteSymbol( 0 ),
    m_nFootnoteFontId( -1 )
{
}
/*-- 21.06.2006 09:30:56---------------------------------------------------

  -----------------------------------------------------------------------*/
PropertyMap::~PropertyMap()
{
}
/*-- 20.06.2006 10:23:55---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Sequence< beans::PropertyValue > PropertyMap::GetPropertyValues()
{
    if(!m_aValues.getLength() && size())
    {
        m_aValues.realloc( size() );
        ::com::sun::star::beans::PropertyValue* pValues = m_aValues.getArray();
        //style names have to be the first elements within the property sequence
        //otherwise they will overwrite 'hard' attributes
        sal_Int32 nValue = 0;
        PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
        PropertyMap::iterator aParaStyleIter = find(PropertyDefinition( PROP_PARA_STYLE_NAME, false ) );
        if( aParaStyleIter != end())
        {
            pValues[nValue].Name = rPropNameSupplier.GetName( aParaStyleIter->first.eId );
            pValues[nValue].Value = aParaStyleIter->second;
            ++nValue;
        }

        PropertyMap::iterator aCharStyleIter = find(PropertyDefinition( PROP_CHAR_STYLE_NAME, false ));
        if( aCharStyleIter != end())
        {
            pValues[nValue].Name = rPropNameSupplier.GetName( aCharStyleIter->first.eId );
            pValues[nValue].Value = aCharStyleIter->second;
            ++nValue;
        }
        PropertyMap::iterator aNumRuleIter = find(PropertyDefinition( PROP_NUMBERING_RULES, false ) );
        if( aNumRuleIter != end())
        {
            pValues[nValue].Name = rPropNameSupplier.GetName( aNumRuleIter->first.eId );
            pValues[nValue].Value = aNumRuleIter->second;
            ++nValue;
        }
        PropertyMap::iterator aMapIter = begin();
        for( ; nValue < m_aValues.getLength(); ++aMapIter )
        {
            if( aMapIter != aParaStyleIter && aMapIter != aCharStyleIter && aMapIter != aNumRuleIter )
            {
                pValues[nValue].Name = rPropNameSupplier.GetName( aMapIter->first.eId );
                pValues[nValue].Value = aMapIter->second;
                ++nValue;
            }
        }
    }
    return m_aValues;
}
/*-------------------------------------------------------------------------

  -----------------------------------------------------------------------*/
void PropertyMap::Insert( PropertyIds eId, bool bIsTextProperty, const uno::Any& rAny, bool bOverwrite )
{
//    const ::rtl::OUString& rInsert = PropertyNameSupplier::
//                           GetPropertyNameSupplier().GetName(eId);
    PropertyMap::iterator aElement = find(PropertyDefinition( eId, bIsTextProperty ) );
    if( aElement != end())
    {
        if(!bOverwrite)
            return;
        erase( aElement );
    }
    _PropertyMap::insert( PropertyMap::value_type
                          (PropertyDefinition( eId, bIsTextProperty),
                           rAny ));
    Invalidate();
}

#ifdef DEBUG_DOMAINMAPPER
XMLTag::Pointer_t PropertyMap::toTag() const
{
    XMLTag::Pointer_t pResult(new XMLTag("PropertyMap"));
        
    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
    PropertyMap::const_iterator aMapIter = begin();
    while (aMapIter != end())
    {
        XMLTag::Pointer_t pTag(new XMLTag("property"));
        
        pTag->addAttr("name", rPropNameSupplier.GetName( aMapIter->first.eId ));
        
        switch (aMapIter->first.eId)
        {
            case PROP_TABLE_COLUMN_SEPARATORS:
                pTag->addTag(lcl_TableColumnSeparatorsToTag(aMapIter->second));
                break;
            default:
            {
                try {
                    sal_Int32 aInt;
                    aMapIter->second >>= aInt;
                    pTag->addAttr("value", aInt);

                    sal_uInt32 auInt;
                    aMapIter->second >>= auInt;
                    pTag->addAttr("unsignedValue", auInt);
                    
                    float aFloat;
                    aMapIter->second >>= aFloat;
                    pTag->addAttr("floatValue", aFloat);
                    
                    ::rtl::OUString aStr;
                    aMapIter->second >>= auInt;
                    pTag->addAttr("stringValue", aStr);                    
                }
                catch (...) {
                }
            }
                break;
        }
        
        pResult->addTag(pTag);
        
        ++aMapIter;
    }
    
    return pResult;
}
#endif

/*-- 13.12.2006 10:46:42---------------------------------------------------

  -----------------------------------------------------------------------*/
template<class T>
    struct removeExistingElements : public ::std::unary_function<T, void>
{
  PropertyMap& rMap;

  removeExistingElements(PropertyMap& _rMap ) : rMap(_rMap) {}
  void operator() (T x)
  {
    PropertyMap::iterator aElement = rMap.find(x.first);
    if( aElement != rMap.end())
        rMap.erase( aElement );
  }
};
/*-- 13.12.2006 10:46:42---------------------------------------------------

  -----------------------------------------------------------------------*/
void PropertyMap::insert( const PropertyMapPtr pMap, bool bOverwrite )
{
    if( pMap.get() )
    {
        if( bOverwrite )
            ::std::for_each( pMap->begin(), pMap->end(), removeExistingElements<PropertyMap::value_type>(*this) );
        _PropertyMap::insert(pMap->begin(), pMap->end());
        insertTableProperties(pMap.get());
        
        Invalidate();
    }
}
/*-- 06.06.2007 15:49:09---------------------------------------------------

  -----------------------------------------------------------------------*/
const uno::Reference< text::XFootnote>&  PropertyMap::GetFootnote() const 
{
    return m_xFootnote;
}
/*-- 18.02.2008 11:23:28---------------------------------------------------

  -----------------------------------------------------------------------*/
void PropertyMap::insertTableProperties( const PropertyMap* )
{
#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->element("PropertyMap.insertTableProperties");
#endif
}
/*-- 24.07.2006 08:29:01---------------------------------------------------

  -----------------------------------------------------------------------*/
SectionPropertyMap::SectionPropertyMap(bool bIsFirstSection) :
    m_bIsFirstSection( bIsFirstSection )
    ,m_nBorderParams( 0 )
    ,m_bTitlePage( false )
    ,m_nColumnCount( 0 )
    ,m_nColumnDistance( 1249 )
    ,m_bSeparatorLineIsOn( false )
    ,m_bEvenlySpaced( false )
    ,m_bIsLandscape( false )
    ,m_bPageNoRestart( false )
    ,m_nPageNumber( -1 )
    ,m_nBreakType( -1 )
    ,m_nPaperBin( -1 )
    ,m_nFirstPaperBin( -1 )
    ,m_nLeftMargin( 3175 ) //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm
    ,m_nRightMargin( 3175 )//page right margin, default 0x708 (1800) twip -> 3175 1/100 mm
    ,m_nTopMargin( 2540 )
    ,m_nBottomMargin( 2540 )
    ,m_nHeaderTop( 1270 ) //720 twip
    ,m_nHeaderBottom( 1270 )//720 twip
    ,m_nDzaGutter( 0 )
    ,m_bGutterRTL( false )
    ,m_bSFBiDi( false )
    ,m_nGridType(0)
    ,m_nGridLinePitch( 1 )
    ,m_nDxtCharSpace( 0 )
    ,m_nLnnMod( 0 )
    ,m_nLnc( 0 )
    ,m_ndxaLnn( 0 )
    ,m_nLnnMin( 0 )
{
    static sal_Int32 nNumber = 0;
    nSectionNumber = nNumber++;
    memset(&m_pBorderLines, 0x00, sizeof(m_pBorderLines));
    for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder )
        m_nBorderDistances[ nBorder ] = -1;
    //todo: set defaults in ApplyPropertiesToPageStyles
    //initialize defaults
    PaperInfo aLetter(PAPER_LETTER);
    //page height, 1/100mm
    Insert( PROP_HEIGHT, false, uno::makeAny( (sal_Int32) aLetter.getHeight() ) );
    //page width, 1/100mm
    Insert( PROP_WIDTH, false, uno::makeAny( (sal_Int32) aLetter.getWidth() ) );
    //page left margin, default 0x708 (1800) twip -> 3175 1/100 mm
    Insert( PROP_LEFT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) );
    //page right margin, default 0x708 (1800) twip -> 3175 1/100 mm
    Insert( PROP_RIGHT_MARGIN, false, uno::makeAny( (sal_Int32) 3175 ) );
    //page top margin, default 0x5a0 (1440) twip -> 2540 1/100 mm
    Insert( PROP_TOP_MARGIN, false, uno::makeAny( (sal_Int32)2540 ) );
    //page bottom margin, default 0x5a0 (1440) twip -> 2540 1/100 mm
    Insert( PROP_BOTTOM_MARGIN, false, uno::makeAny( (sal_Int32) 2540 ) );
    uno::Any aFalse( ::uno::makeAny( false ) );
    Insert( PROP_GRID_DISPLAY, false, aFalse);
    Insert( PROP_GRID_PRINT, false, aFalse);
    Insert( PROP_GRID_MODE, false, uno::makeAny(text::TextGridMode::NONE));


    if( m_bIsFirstSection )
    {
        PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
        m_sFirstPageStyleName = rPropNameSupplier.GetName( PROP_FIRST_PAGE );
        m_sFollowPageStyleName = rPropNameSupplier.GetName( PROP_STANDARD );
    }
}
/*-- 24.07.2006 08:29:02---------------------------------------------------

  -----------------------------------------------------------------------*/
SectionPropertyMap::~SectionPropertyMap()
{
    for( sal_Int16 ePos = BORDER_LEFT; ePos <= BORDER_BOTTOM; ++ePos)
        delete m_pBorderLines[ePos];
}
/*-- 24.07.2006 08:31:07---------------------------------------------------

  -----------------------------------------------------------------------*/
const ::rtl::OUString&  SectionPropertyMap::GetPageStyleName( bool bFirst )
{
    return bFirst ? m_sFirstPageStyleName : m_sFollowPageStyleName;
}
/*-- 24.07.2006 08:31:07---------------------------------------------------

  -----------------------------------------------------------------------*/
void  SectionPropertyMap::SetPageStyleName( bool bFirst, const ::rtl::OUString& rName)
{
    if( bFirst )
        m_sFirstPageStyleName = rName;
    else
        m_sFollowPageStyleName = rName;
}
/*-- 24.07.2006 09:41:20---------------------------------------------------

  -----------------------------------------------------------------------*/
::rtl::OUString lcl_FindUnusedPageStyleName(const uno::Sequence< ::rtl::OUString >& rPageStyleNames)
{
    static const sal_Char cDefaultStyle[] = "Converted";
    //find the hightest number x in each style with the name "cDefaultStyle+x" and
    //return an incremented name
    sal_Int32 nMaxIndex = 0;
    const sal_Int32 nDefaultLength = sizeof(cDefaultStyle)/sizeof(sal_Char) - 1;
    const ::rtl::OUString sDefaultStyle( cDefaultStyle, nDefaultLength, RTL_TEXTENCODING_ASCII_US );

    const ::rtl::OUString* pStyleNames = rPageStyleNames.getConstArray();
    for( sal_Int32 nStyle = 0; nStyle < rPageStyleNames.getLength(); ++nStyle)
    {
        if( pStyleNames[nStyle].getLength() > nDefaultLength &&
                !rtl_ustr_compare_WithLength( sDefaultStyle, nDefaultLength, pStyleNames[nStyle], nDefaultLength))
        {
            sal_Int32 nIndex = pStyleNames[nStyle].copy( nDefaultLength ).toInt32();
            if( nIndex > nMaxIndex)
                nMaxIndex = nIndex;
        }
    }
    ::rtl::OUString sRet( sDefaultStyle );
    sRet += rtl::OUString::valueOf( nMaxIndex + 1);
    return sRet;
}

/*-- 28.07.2006 13:00:43---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< beans::XPropertySet > SectionPropertyMap::GetPageStyle(
        const uno::Reference< container::XNameContainer >& xPageStyles,
        const uno::Reference < lang::XMultiServiceFactory >& xTextFactory,
        bool bFirst )
{
    uno::Reference< beans::XPropertySet > xRet;
    try
    {
        if( bFirst )
        {
            if( !m_sFirstPageStyleName.getLength() )
            {
                uno::Sequence< ::rtl::OUString > aPageStyleNames = xPageStyles->getElementNames();
                m_sFirstPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames);
                m_aFirstPageStyle = uno::Reference< beans::XPropertySet > (
                        xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.PageStyle") )),
                        uno::UNO_QUERY);
                xPageStyles->insertByName( m_sFirstPageStyleName, uno::makeAny(m_aFirstPageStyle) );
            }
            else if( !m_aFirstPageStyle.is() )
            {
                xPageStyles->getByName(m_sFirstPageStyleName) >>= m_aFirstPageStyle;
            }
            xRet = m_aFirstPageStyle;
        }
        else
        {
            if( !m_sFollowPageStyleName.getLength() )
            {
                uno::Sequence< ::rtl::OUString > aPageStyleNames = xPageStyles->getElementNames();
                m_sFollowPageStyleName = lcl_FindUnusedPageStyleName(aPageStyleNames);
                m_aFollowPageStyle = uno::Reference< beans::XPropertySet > (
                        xTextFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.style.PageStyle") )),
                        uno::UNO_QUERY);
                xPageStyles->insertByName( m_sFollowPageStyleName, uno::makeAny(m_aFollowPageStyle) );
            }
            else if(!m_aFollowPageStyle.is() )
            {
                xPageStyles->getByName(m_sFollowPageStyleName) >>= m_aFollowPageStyle;
            }
            xRet = m_aFollowPageStyle;
        }

    }
    catch( const uno::Exception& )
    {
    }

    return xRet;
}
/*-- 28.07.2006 10:56:26---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::SetBorder( BorderPosition ePos, sal_Int32 nLineDistance, const table::BorderLine2& rBorderLine )
{
    delete m_pBorderLines[ePos];
    m_pBorderLines[ePos] = new table::BorderLine2( rBorderLine );
    m_nBorderDistances[ePos] = nLineDistance;
}
/*-- 28.07.2006 10:56:27---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::ApplyBorderToPageStyles(
            const uno::Reference< container::XNameContainer >& xPageStyles,
            const uno::Reference < lang::XMultiServiceFactory >& xTextFactory,
        sal_Int32 nValue )
{
            /*
            page border applies to:
            nIntValue & 0x07 ->
            0 all pages in this section
            1 first page in this section
            2 all pages in this section but first
            3 whole document (all sections)
            nIntValue & 0x18 -> page border depth 0 - in front 1- in back
            nIntValue & 0xe0 ->
            page border offset from:
            0 offset from text
            1 offset from edge of page
            */
    uno::Reference< beans::XPropertySet >  xFirst;
    uno::Reference< beans::XPropertySet >  xSecond;
    sal_Int32 nOffsetFrom = (nValue & 0x00E0) >> 5;
    //sal_Int32 bPageDepth = (nValue & 0x0018) >> 3; //unused infromation: 0 - in front 1 - in back
    //todo: negative spacing (from ww8par6.cxx)
    switch( nValue & 0x07)
    {
        case 0: /*all styles*/
            if ( m_sFollowPageStyleName.getLength( ) > 0 )
                xFirst = GetPageStyle( xPageStyles, xTextFactory, false );
            if ( m_sFirstPageStyleName.getLength( ) > 0 )
                xSecond = GetPageStyle( xPageStyles, xTextFactory, true );
        break;
        case 1: /*first page*/
            if ( m_sFirstPageStyleName.getLength( ) > 0 )
                xFirst = GetPageStyle( xPageStyles, xTextFactory, true );
        break;
        case 2: /*left and right*/
            if ( m_sFollowPageStyleName.getLength( ) > 0 )
                xFirst  = GetPageStyle( xPageStyles, xTextFactory, false );
        break;
        case 3: //whole document?
            //todo: how to apply a border to the whole document - find all sections or access all page styles?
        default:
            return;
    }
    //has to be sorted like enum BorderPosition: l-r-t-b
    static const PropertyIds aBorderIds[4] =
    {
        PROP_LEFT_BORDER,
        PROP_RIGHT_BORDER,
        PROP_TOP_BORDER,
        PROP_BOTTOM_BORDER
    };
    static const PropertyIds aBorderDistanceIds[4] =
    {
        PROP_LEFT_BORDER_DISTANCE,
        PROP_RIGHT_BORDER_DISTANCE,
        PROP_TOP_BORDER_DISTANCE,
        PROP_BOTTOM_BORDER_DISTANCE
    };
    static const PropertyIds aMarginIds[4] = 
    {
        PROP_LEFT_MARGIN,
        PROP_RIGHT_MARGIN,
        PROP_TOP_MARGIN,
        PROP_BOTTOM_MARGIN
    };

    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
    for( sal_Int32 nBorder = 0; nBorder < 4; ++nBorder)
    {
        if( m_pBorderLines[nBorder] )
        {
            const ::rtl::OUString sBorderName = rPropNameSupplier.GetName( aBorderIds[nBorder] );
            xFirst->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] ));
            if(xSecond.is())
                xSecond->setPropertyValue( sBorderName, uno::makeAny( *m_pBorderLines[nBorder] ));
        }
        if( m_nBorderDistances[nBorder] >= 0 )
        {
            SetBorderDistance( xFirst, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
                  m_nBorderDistances[nBorder], nOffsetFrom );
            if(xSecond.is())
                SetBorderDistance( xSecond, aMarginIds[nBorder], aBorderDistanceIds[nBorder],
                      m_nBorderDistances[nBorder], nOffsetFrom );
        }
    }
}

void SectionPropertyMap::SetBorderDistance( uno::Reference< beans::XPropertySet > xStyle, 
        PropertyIds eMarginId, PropertyIds eDistId, sal_Int32 nDistance, sal_Int32 nOffsetFrom )
{ 
    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();

    sal_Int32 nDist = nDistance;
    if( nOffsetFrom == 1 )
    {
        const ::rtl::OUString sMarginName = rPropNameSupplier.GetName( eMarginId );
        uno::Any aMargin = xStyle->getPropertyValue( sMarginName );
        sal_Int32 nMargin = 0;
        aMargin >>= nMargin;
    
        // Change the margins with the border distance
        xStyle->setPropertyValue( sMarginName, uno::makeAny( nDistance ) );
    
        // Set the distance to ( Margin - distance )
        nDist = nMargin - nDistance;
    }
    const ::rtl::OUString sBorderDistanceName = rPropNameSupplier.GetName( eDistId );
    xStyle->setPropertyValue( sBorderDistanceName, uno::makeAny( nDist ));
}

/*-- 14.12.2006 12:50:06---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< text::XTextColumns > SectionPropertyMap::ApplyColumnProperties(
                            uno::Reference< beans::XPropertySet > xColumnContainer )
{
    uno::Reference< text::XTextColumns > xColumns;
    try
    {
        PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
        const ::rtl::OUString sTextColumns = rPropNameSupplier.GetName( PROP_TEXT_COLUMNS );
        xColumnContainer->getPropertyValue(sTextColumns) >>= xColumns;
        uno::Reference< beans::XPropertySet > xColumnPropSet( xColumns, uno::UNO_QUERY_THROW );
        if( !m_bEvenlySpaced &&
                (sal_Int32(m_aColWidth.size()) == (m_nColumnCount + 1 )) &&
                (sal_Int32(m_aColDistance.size()) == m_nColumnCount))
        {
            //the column width in word is an absolute value, in OOo it's relative
            //the distances are both absolute
            sal_Int32 nColSum = 0;
            for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol)
            {
                nColSum += m_aColWidth[nCol];
                if(nCol)
                    nColSum += m_aColDistance[nCol -1];
            }

            sal_Int32 nRefValue = xColumns->getReferenceValue();
            double fRel = double( nRefValue ) / double( nColSum );
            uno::Sequence< text::TextColumn > aColumns( m_nColumnCount + 1 );
            text::TextColumn* pColumn = aColumns.getArray();

            nColSum = 0;
            for( sal_Int32 nCol = 0; nCol <= m_nColumnCount; ++nCol)
            {
                //nColSum : nRefValue == (nAbsColWidth + colDist /2) : nRelColWidth;
                pColumn[nCol].LeftMargin = nCol ? m_aColDistance[nCol - 1 ] / 2 : 0;
                pColumn[nCol].RightMargin = nCol == m_nColumnCount ? 0 : m_aColDistance[nCol] / 2;
                pColumn[nCol].Width = sal_Int32((double( m_aColWidth[nCol] + pColumn[nCol].RightMargin + pColumn[nCol].LeftMargin ) + 0.5 ) * fRel );
                nColSum += pColumn[nCol].Width;
            }
            if( nColSum != nRefValue )
                pColumn[m_nColumnCount].Width -= ( nColSum - nRefValue );
            xColumns->setColumns( aColumns );
        }
        else
        {
            xColumns->setColumnCount( m_nColumnCount + 1 );
            xColumnPropSet->setPropertyValue( rPropNameSupplier.GetName( PROP_AUTOMATIC_DISTANCE ), uno::makeAny( m_nColumnDistance ));
        }

        if(m_bSeparatorLineIsOn)
            xColumnPropSet->setPropertyValue(
                rPropNameSupplier.GetName( PROP_SEPARATOR_LINE_IS_ON ),
                uno::makeAny( m_bSeparatorLineIsOn ));
        xColumnContainer->setPropertyValue( sTextColumns, uno::makeAny( xColumns ) );
    }
    catch( const uno::Exception& )
    {
        OSL_ENSURE( false, "Exception in SectionPropertyMap::ApplyColumnProperties");
    }
    return xColumns;
}

/*-- 20.12.2006 09:44:16---------------------------------------------------

  -----------------------------------------------------------------------*/
bool SectionPropertyMap::HasHeader(bool bFirstPage) const
{
    bool bRet = false;
    if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) )
    {
        if( bFirstPage )
            m_aFirstPageStyle->getPropertyValue(
                    PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet;
        else
            m_aFollowPageStyle->getPropertyValue(
                    PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_HEADER_IS_ON) ) >>= bRet;
    }
    return bRet;
}
/*-- 20.12.2006 09:44:16---------------------------------------------------

  -----------------------------------------------------------------------*/
bool SectionPropertyMap::HasFooter(bool bFirstPage) const
{
    bool bRet = false;
    if( (bFirstPage && m_aFirstPageStyle.is()) ||( !bFirstPage && m_aFollowPageStyle.is()) )
    {
        if( bFirstPage )
            m_aFirstPageStyle->getPropertyValue(
                    PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet;
        else
            m_aFollowPageStyle->getPropertyValue(
                    PropertyNameSupplier::GetPropertyNameSupplier().GetName(PROP_FOOTER_IS_ON) ) >>= bRet;
    }
    return bRet;
}
/*-- 20.12.2006 09:41:56---------------------------------------------------

  -----------------------------------------------------------------------*/
#define MIN_HEAD_FOOT_HEIGHT 100 //minimum header/footer height

void SectionPropertyMap::CopyLastHeaderFooter( bool bFirstPage, DomainMapper_Impl& rDM_Impl )
{
#if DEBUG
    clog << "START>>> SectionPropertyMap::CopyLastHeaderFooter()" << endl;
#endif
    SectionPropertyMap* pLastContext = rDM_Impl.GetLastSectionContext( );
    if ( pLastContext )
    {
        uno::Reference< beans::XPropertySet > xPrevStyle = pLastContext->GetPageStyle(
                rDM_Impl.GetPageStyles(),
                rDM_Impl.GetTextFactory(),
                bFirstPage );
        uno::Reference< beans::XPropertySet > xStyle = GetPageStyle(
                rDM_Impl.GetPageStyles(),
                rDM_Impl.GetTextFactory(),
                bFirstPage );

        PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();

        try {
            // Loop over the Header and Footer properties to copy them
            static PropertyIds aProperties[] =
            {
                PROP_HEADER_TEXT,
                PROP_FOOTER_TEXT,
            };

            bool bHasPrevHeader = false;
            bool bHasHeader = false;

            rtl::OUString sHeaderIsOn = rPropNameSupplier.GetName( PROP_HEADER_IS_ON );
            xPrevStyle->getPropertyValue( sHeaderIsOn ) >>= bHasPrevHeader;
            xStyle->getPropertyValue( sHeaderIsOn ) >>= bHasHeader;
            bool bCopyHeader = bHasPrevHeader && !bHasHeader;

            if ( bCopyHeader )
                xStyle->setPropertyValue( sHeaderIsOn, uno::makeAny( sal_True ) );

            bool bHasPrevFooter = false;
            bool bHasFooter = false;

            rtl::OUString sFooterIsOn = rPropNameSupplier.GetName( PROP_FOOTER_IS_ON );
            xPrevStyle->getPropertyValue( sFooterIsOn ) >>= bHasPrevFooter;
            xStyle->getPropertyValue( sFooterIsOn ) >>= bHasFooter;
            bool bCopyFooter = bHasPrevFooter && !bHasFooter;

            if ( bCopyFooter )
                xStyle->setPropertyValue( sFooterIsOn, uno::makeAny( sal_True ) );

            // Copying the text properties
            for ( int i = 0, nNbProps = 2; i < nNbProps; i++ )
            {
                bool bIsHeader = ( i < nNbProps / 2 );
                PropertyIds aPropId = aProperties[i];
                rtl::OUString sName = rPropNameSupplier.GetName( aPropId );

                if ( ( bIsHeader && bCopyHeader ) || ( !bIsHeader && bCopyFooter ) )
                {
#if DEBUG
                    clog << "Copying ";
                    clog << rtl::OUStringToOString( sName, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl;
#endif
                    // TODO has to be copied
                    uno::Reference< text::XTextCopy > xTxt(
                            xStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW );

                    uno::Reference< text::XTextCopy > xPrevTxt(
                            xPrevStyle->getPropertyValue( sName ), uno::UNO_QUERY_THROW );

                    xTxt->copyText( xPrevTxt );
                }
            }
        }
        catch ( const uno::Exception& e )
        {
#if DEBUG
            clog << "An exception occured in SectionPropertyMap::CopyLastHeaderFooter( ) - ";
            clog << rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr( ) << endl;
#endif
        }
    }
#if DEBUG
    clog << "END>>> SectionPropertyMap::CopyLastHeaderFooter()" << endl;
#endif
}

void SectionPropertyMap::PrepareHeaderFooterProperties( bool bFirstPage )
{
    sal_Int32 nTopMargin = m_nTopMargin;
    if(HasHeader(bFirstPage))
    {
        m_nTopMargin = m_nHeaderTop;
        if( nTopMargin > 0 && nTopMargin > m_nHeaderTop )
            m_nHeaderTop = nTopMargin - m_nHeaderTop;
        else
            m_nHeaderTop = 0;

        //minimum header height 1mm
        if( m_nHeaderTop < MIN_HEAD_FOOT_HEIGHT )
            m_nHeaderTop = MIN_HEAD_FOOT_HEIGHT;
    }


    if( nTopMargin >= 0 ) //fixed height header -> see WW8Par6.hxx
    {
        operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true );
        operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false )) = uno::makeAny( true );
        operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderTop - MIN_HEAD_FOOT_HEIGHT );// ULSpace.Top()
        operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) =  uno::makeAny( m_nHeaderTop );

    }
    else
    {
        //todo: old filter fakes a frame into the header/footer to support overlapping
        //current setting is completely wrong!
        operator[]( PropertyDefinition( PROP_HEADER_HEIGHT, false )) =  uno::makeAny( m_nHeaderTop );
        operator[]( PropertyDefinition( PROP_HEADER_BODY_DISTANCE, false )) = uno::makeAny( nTopMargin - m_nHeaderTop );
        operator[]( PropertyDefinition( PROP_HEADER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false );
        operator[]( PropertyDefinition( PROP_HEADER_DYNAMIC_SPACING, false)) = uno::makeAny( false );
    }

    sal_Int32 nBottomMargin = m_nBottomMargin;
    if( HasFooter( bFirstPage ) )
    {
        m_nBottomMargin = m_nHeaderBottom;
        if( nBottomMargin > 0 && nBottomMargin > m_nHeaderBottom )
            m_nHeaderBottom = nBottomMargin - m_nHeaderBottom;
        else
            m_nHeaderBottom = 0;
        if( m_nHeaderBottom < MIN_HEAD_FOOT_HEIGHT )
            m_nHeaderBottom = MIN_HEAD_FOOT_HEIGHT;
    }

    if( nBottomMargin >= 0 ) //fixed height footer -> see WW8Par6.hxx
    {
        operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false )) = uno::makeAny( true );
        operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false )) = uno::makeAny( true );
        operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom - MIN_HEAD_FOOT_HEIGHT);
        operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) =  uno::makeAny( m_nHeaderBottom );
    }
    else
    {
        //todo: old filter fakes a frame into the header/footer to support overlapping
        //current setting is completely wrong!
        operator[]( PropertyDefinition( PROP_FOOTER_IS_DYNAMIC_HEIGHT, false)) = uno::makeAny( false );
        operator[]( PropertyDefinition( PROP_FOOTER_DYNAMIC_SPACING, false)) = uno::makeAny( false );
        operator[]( PropertyDefinition( PROP_FOOTER_HEIGHT, false )) =  uno::makeAny( nBottomMargin - m_nHeaderBottom );
        operator[]( PropertyDefinition( PROP_FOOTER_BODY_DISTANCE, false )) = uno::makeAny( m_nHeaderBottom );
    }

    //now set the top/bottom margin for the follow page style
    operator[]( PropertyDefinition( PROP_TOP_MARGIN, false )) = uno::makeAny( m_nTopMargin );
    operator[]( PropertyDefinition( PROP_BOTTOM_MARGIN, false )) = uno::makeAny( m_nBottomMargin );
}
/*-- 11.12.2006 08:31:46---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl )
{
    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
    if( m_nLnnMod )
    {
        bool bFirst = rDM_Impl.IsLineNumberingSet();
        rDM_Impl.SetLineNumbering( m_nLnnMod, m_nLnc, m_ndxaLnn );
        if( m_nLnnMin > 0 || (bFirst && m_nLnc == 1))
        {
            //set the starting value at the beginning of the section
            try
            {
                uno::Reference< beans::XPropertySet > xRangeProperties;
                if( m_xStartingRange.is() )
                {
                    xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW );
                }
                else
                {
                    //set the start value at the beginning of the document
                    xRangeProperties = uno::Reference< beans::XPropertySet >( rDM_Impl.GetTextDocument()->getText()->getStart(), uno::UNO_QUERY_THROW );
                }
                xRangeProperties->setPropertyValue( rPropNameSupplier.GetName( PROP_PARA_LINE_NUMBER_START_VALUE ), uno::makeAny( m_nLnnMin + 1 ));
            }
            catch( const uno::Exception& )
            {
                OSL_ENSURE( false, "Exception in SectionPropertyMap::CloseSectionGroup");
            }
        }
    }

    //depending on the break type no page styles should be created
    if(m_nBreakType == 0)
    {
        //todo: insert a section or access the already inserted section
        //-->debug
//        ::rtl::OUString sSelection = m_xStartingRange->getString();
//        sSelection.getLength();
        //-->debug
        uno::Reference< beans::XPropertySet > xSection =
                                    rDM_Impl.appendTextSectionAfter( m_xStartingRange );
        if( m_nColumnCount > 0 && xSection.is())
            ApplyColumnProperties( xSection );
    }
    else
    {
        //get the properties and create appropriate page styles
        uno::Reference< beans::XPropertySet > xFollowPageStyle = GetPageStyle( rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), false );

        if( m_nDzaGutter > 0 )
        {
            //todo: iGutterPos from DocProperties are missing
            // if( m_iGutterPos > 0 ) m_nTopMargin += m_nDzaGutter; else
            if( m_bGutterRTL )
                m_nRightMargin += m_nDzaGutter;
            else
                m_nLeftMargin += m_nDzaGutter;
        }
        operator[]( PropertyDefinition( PROP_LEFT_MARGIN, false )) =  uno::makeAny( m_nLeftMargin  );
        operator[]( PropertyDefinition( PROP_RIGHT_MARGIN, false )) = uno::makeAny( m_nRightMargin );

//        if( iGutterPos && fRTLGutter )
//        m_nTopMargin += nGutter

        /*** if headers/footers are available then the top/bottom margins of the
            header/footer are copied to the top/bottom margin of the page
          */
        CopyLastHeaderFooter( false, rDM_Impl );
        PrepareHeaderFooterProperties( false );

        const ::rtl::OUString sTrayIndex = rPropNameSupplier.GetName( PROP_PRINTER_PAPER_TRAY_INDEX );
        if( m_nPaperBin >= 0 )
            xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( m_nPaperBin ) );
        uno::Reference< text::XTextColumns > xColumns;
        if( m_nColumnCount > 0 )
            xColumns = ApplyColumnProperties( xFollowPageStyle );

        //prepare text grid properties
        sal_Int32 nHeight = 1;
        PropertyMap::iterator aElement = find(PropertyDefinition( PROP_HEIGHT, false ));
        if( aElement != end())
            aElement->second >>= nHeight;

        sal_Int32 nWidth = 1;
        aElement = find(PropertyDefinition( PROP_WIDTH, false ));
        if( aElement != end())
            aElement->second >>= nWidth;

        text::WritingMode eWritingMode = text::WritingMode_LR_TB;
        aElement = find(PropertyDefinition( PROP_WRITING_MODE, false ));
        if( aElement != end())
            aElement->second >>= eWritingMode;



        sal_Int32 nTextAreaHeight = eWritingMode == text::WritingMode_LR_TB ?
            nHeight - m_nTopMargin - m_nBottomMargin :
            nWidth - m_nLeftMargin - m_nRightMargin;

        operator[]( PropertyDefinition( PROP_GRID_LINES, false )) =
                uno::makeAny( static_cast<sal_Int16>(nTextAreaHeight/m_nGridLinePitch));

        sal_Int32 nCharWidth = 423; //240 twip/ 12 pt
        //todo: is '0' the right index here?
        const StyleSheetEntryPtr pEntry = rDM_Impl.GetStyleSheetTable()->FindStyleSheetByISTD(::rtl::OUString::valueOf(static_cast<sal_Int32>(0), 16));
        if( pEntry.get( ) )
        {
            PropertyMap::iterator aElement_ = pEntry->pProperties->find(PropertyDefinition( PROP_CHAR_HEIGHT_ASIAN, false ));
            if( aElement_ != pEntry->pProperties->end())
            {
                double fHeight = 0;
                if( aElement_->second >>= fHeight )
                    nCharWidth = ConversionHelper::convertTwipToMM100( (long)( fHeight * 20.0 + 0.5 ));
            }
        }

        //dxtCharSpace
        if(m_nDxtCharSpace)
        {
            sal_Int32 nCharSpace = m_nDxtCharSpace;
            //main lives in top 20 bits, and is signed.
            sal_Int32 nMain = (nCharSpace & 0xFFFFF000);
            nMain /= 0x1000;
            nCharWidth += ConversionHelper::convertTwipToMM100( nMain * 20 );

            sal_Int32 nFraction = (nCharSpace & 0x00000FFF);
            nFraction = (nFraction * 20)/0xFFF;
            nCharWidth += ConversionHelper::convertTwipToMM100( nFraction );
        }
        operator[]( PropertyDefinition( PROP_GRID_BASE_HEIGHT, false )) = uno::makeAny( nCharWidth );
        sal_Int32 nRubyHeight = m_nGridLinePitch - nCharWidth;
        if(nRubyHeight < 0 )
            nRubyHeight = 0;
        operator[]( PropertyDefinition( PROP_GRID_RUBY_HEIGHT, false )) = uno::makeAny( nRubyHeight );

        sal_Int16 nGridMode = text::TextGridMode::NONE;
        
        switch (m_nGridType)
        {
            case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_lines:
                nGridMode = text::TextGridMode::LINES;
                break;
            case NS_ooxml::LN_Value_wordprocessingml_ST_DocGrid_linesAndChars:
                nGridMode = text::TextGridMode::LINES_AND_CHARS;
                break;
            default:
                break;
        }
        
        operator[](PropertyDefinition(PROP_GRID_MODE, false)) = uno::makeAny(nGridMode);
        
        _ApplyProperties( xFollowPageStyle );

        //todo: creating a "First Page" style depends on HasTitlePage und _fFacingPage_
        if( m_bTitlePage )
        {
            CopyLastHeaderFooter( true, rDM_Impl );
            PrepareHeaderFooterProperties( true );
            uno::Reference< beans::XPropertySet > xFirstPageStyle = GetPageStyle(
                                rDM_Impl.GetPageStyles(), rDM_Impl.GetTextFactory(), true );
            _ApplyProperties( xFirstPageStyle );

            sal_Int32 nPaperBin = m_nFirstPaperBin >= 0 ? m_nFirstPaperBin : m_nPaperBin >= 0 ? m_nPaperBin : 0;
            if( nPaperBin )
                xFollowPageStyle->setPropertyValue( sTrayIndex, uno::makeAny( nPaperBin ) );
            if( xColumns.is() )
                xFollowPageStyle->setPropertyValue(
                    rPropNameSupplier.GetName( PROP_TEXT_COLUMNS ), uno::makeAny( xColumns ));
        }
            
        ApplyBorderToPageStyles( rDM_Impl.GetPageStyles( ), rDM_Impl.GetTextFactory( ), m_nBorderParams );

        try
        {
//            if( m_xStartingRange.is() )
            {
                //now apply this break at the first paragraph of this section
                uno::Reference< beans::XPropertySet > xRangeProperties;
                if( m_bIsFirstSection )
                {
                    uno::Reference< container::XEnumerationAccess > xEnumAccess( rDM_Impl.GetBodyText( ), uno::UNO_QUERY_THROW );
                    uno::Reference< container::XEnumeration >  xEnum = xEnumAccess->createEnumeration( );
                    xRangeProperties = uno::Reference< beans::XPropertySet >( xEnum->nextElement( ), uno::UNO_QUERY_THROW );
                }
                else
                    xRangeProperties = uno::Reference< beans::XPropertySet >( m_xStartingRange, uno::UNO_QUERY_THROW );
            /* break type
            0 - No break 1 - New Colunn 2 - New page 3 - Even page 4 - odd page */
                xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_DESC_NAME ),
                    uno::makeAny( m_bTitlePage ? m_sFirstPageStyleName : m_sFollowPageStyleName ));
    //  todo: page breaks with odd/even page numbering are not available - find out current page number to check how to change the number
    //  or add even/odd page break types
                if(m_bPageNoRestart || m_nPageNumber >= 0)
                {
                    sal_Int16 nPageNumber = m_nPageNumber >= 0 ? static_cast< sal_Int16 >(m_nPageNumber) : 1;
                    xRangeProperties->setPropertyValue(rPropNameSupplier.GetName( PROP_PAGE_NUMBER_OFFSET ),
                        uno::makeAny( nPageNumber ));
                }
            }
        }
        catch( const uno::Exception& rEx)
        {
            OSL_ENSURE( false, "Exception in SectionPropertyMap::CloseSectionGroup");
            (void)rEx;
       }
    }
}
/*-- 11.12.2006 08:31:46---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::_ApplyProperties( uno::Reference< beans::XPropertySet > xStyle )
{
    PropertyNameSupplier& rPropNameSupplier = PropertyNameSupplier::GetPropertyNameSupplier();
    PropertyMap::iterator aMapIter = begin();
    while( aMapIter != end())
    {
        try
        {
            xStyle->setPropertyValue( rPropNameSupplier.GetName( aMapIter->first.eId ), aMapIter->second );
        }
        catch( const uno::Exception& )
        {
            OSL_ENSURE( false, "Exception in <PageStyle>::setPropertyValue");
        }
        ++aMapIter;
    }
}
sal_Int32 lcl_AlignPaperBin( sal_Int32 nSet )
{
    //default tray numbers are above 0xff
    if( nSet > 0xff )
        nSet = nSet >> 8;
    //there are some special numbers which can't be handled easily
    //1, 4, 15, manual tray, upper tray, auto select? see ww8atr.cxx
    //todo: find out appropriate conversion
    return nSet;
}
/*-- 13.12.2006 15:34:01---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::SetPaperBin( sal_Int32 nSet )
{
    m_nPaperBin = lcl_AlignPaperBin( nSet );
}
/*-- 13.12.2006 15:34:01---------------------------------------------------

  -----------------------------------------------------------------------*/
void SectionPropertyMap::SetFirstPaperBin( sal_Int32 nSet )
{
    m_nFirstPaperBin = lcl_AlignPaperBin( nSet );
}
/*-- 14.06.2007 13:57:42---------------------------------------------------

  -----------------------------------------------------------------------*/
StyleSheetPropertyMap::StyleSheetPropertyMap() :
//    mnCT_Spacing_after( 0 ),
    mnCT_Spacing_line( 0 ),
    mnCT_Spacing_lineRule( 0 ),
    mbCT_TrPrBase_tblHeader( false ),
    mnCT_TrPrBase_jc( 0 ),
    mnCT_TcPrBase_vAlign( 0 ),
    mnCT_TblWidth_w( 0 ),
    mnCT_TblWidth_type( 0 ),
//    mbCT_Spacing_afterSet( false ),
    mbCT_Spacing_lineSet( false ),
    mbCT_Spacing_lineRuleSet( false ),
    mbCT_TrPrBase_tblHeaderSet( false ),
    mbCT_TrPrBase_jcSet( false ),
    mbCT_TcPrBase_vAlignSet( false ),
    mbCT_TblWidth_wSet( false ),
    mbCT_TblWidth_typeSet( false ),
    mnListId( -1 ),
    mnListLevel( -1 ),
    mnOutlineLevel( -1 )
{
}
/*-- 14.06.2007 13:57:43---------------------------------------------------

  -----------------------------------------------------------------------*/
StyleSheetPropertyMap::~StyleSheetPropertyMap()
{
}
/*-- 28.12.2007 08:19:00---------------------------------------------------

  -----------------------------------------------------------------------*/
ParagraphProperties::ParagraphProperties() :
    m_bFrameMode( false ),
    m_nDropCap(NS_ooxml::LN_Value_wordprocessingml_ST_DropCap_none),
    m_nLines(0),
    m_w(-1),
    m_h(-1),
    m_nWrap(-1),
    m_hAnchor(-1),
    m_vAnchor(text::RelOrientation::FRAME),
    m_x(-1),
    m_bxValid( false ),
    m_y(-1),
    m_byValid( false ),
    m_hSpace(-1),
    m_vSpace(-1),
    m_hRule(-1),
    m_xAlign(-1),
    m_yAlign(-1),
    m_bAnchorLock(false),
    m_nDropCapLength(0)
{
}
/*-- 28.12.2007 08:28:24---------------------------------------------------

  -----------------------------------------------------------------------*/
ParagraphProperties::ParagraphProperties(const ParagraphProperties& rCopy) : 
    m_bFrameMode ( rCopy.m_bFrameMode),
    m_nDropCap   ( rCopy.m_nDropCap),
    m_nLines     ( rCopy.m_nLines),
    m_w          ( rCopy.m_w),
    m_h          ( rCopy.m_h),
    m_nWrap      ( rCopy.m_nWrap),
    m_hAnchor    ( rCopy.m_hAnchor),
    m_vAnchor    ( rCopy.m_vAnchor),
    m_x          ( rCopy.m_x),
    m_bxValid    ( rCopy.m_bxValid),
    m_y          ( rCopy.m_y),
    m_byValid    ( rCopy.m_byValid),
    m_hSpace     ( rCopy.m_hSpace),
    m_vSpace     ( rCopy.m_vSpace),
    m_hRule      ( rCopy.m_hRule),
    m_xAlign     ( rCopy.m_xAlign),
    m_yAlign     ( rCopy.m_yAlign),
    m_bAnchorLock( rCopy.m_bAnchorLock),
    m_nDropCapLength( rCopy.m_nDropCapLength ),
    m_sParaStyleName( rCopy.m_sParaStyleName),
    m_xStartingRange( rCopy.m_xStartingRange ),
    m_xEndingRange( rCopy.m_xEndingRange)
{
}
/*-- 28.12.2007 11:29:18---------------------------------------------------
    
  -----------------------------------------------------------------------*/
ParagraphProperties::~ParagraphProperties()
{
}
/*-- 28.12.2007 09:05:45---------------------------------------------------

  -----------------------------------------------------------------------*/
int ParagraphProperties::operator==(const ParagraphProperties& rCompare)
{
    return 
        m_bFrameMode == rCompare.m_bFrameMode &&
        m_nDropCap   == rCompare.m_nDropCap &&
        m_nLines     == rCompare.m_nLines &&
        m_w          == rCompare.m_w &&
        m_h          == rCompare.m_h &&
        m_nWrap      == rCompare.m_nWrap &&
        m_hAnchor    == rCompare.m_hAnchor &&
        m_vAnchor    == rCompare.m_vAnchor &&
        m_x          == rCompare.m_x &&
        m_bxValid    == rCompare.m_bxValid &&
        m_y          == rCompare.m_y &&
        m_byValid    == rCompare.m_byValid &&
        m_hSpace     == rCompare.m_hSpace &&
        m_vSpace     == rCompare.m_vSpace &&
        m_hRule      == rCompare.m_hRule &&
        m_xAlign     == rCompare.m_xAlign &&
        m_yAlign     == rCompare.m_yAlign &&
        m_bAnchorLock== rCompare.m_bAnchorLock;
}
/*-- 27.12.2007 13:32:36---------------------------------------------------

  -----------------------------------------------------------------------*/
ParagraphPropertyMap::ParagraphPropertyMap()
{
}
/*-- 27.12.2007 13:32:36---------------------------------------------------

  -----------------------------------------------------------------------*/
ParagraphPropertyMap::~ParagraphPropertyMap()
{
}
/*-- 15.02.2008 16:10:39---------------------------------------------------

  -----------------------------------------------------------------------*/
TablePropertyMap::TablePropertyMap()
{
}
/*-- 15.02.2008 16:10:39---------------------------------------------------

  -----------------------------------------------------------------------*/
TablePropertyMap::~TablePropertyMap()
{
}
/*-- 18.02.2008 10:06:30---------------------------------------------------

  -----------------------------------------------------------------------*/
bool TablePropertyMap::getValue( TablePropertyMapTarget eWhich, sal_Int32& nFill )
{
    if( eWhich < TablePropertyMapTarget_MAX )
    {
        if(m_aValidValues[eWhich].bValid)
            nFill = m_aValidValues[eWhich].nValue;
        return m_aValidValues[eWhich].bValid;
    }
    else
    {
        OSL_ENSURE( false, "invalid TablePropertyMapTarget");
        return false;
    }
}                
/*-- 18.02.2008 10:07:11---------------------------------------------------

  -----------------------------------------------------------------------*/
void TablePropertyMap::setValue( TablePropertyMapTarget eWhich, sal_Int32 nSet )
{
    if( eWhich < TablePropertyMapTarget_MAX )
    {
        m_aValidValues[eWhich].bValid = true;
        m_aValidValues[eWhich].nValue = nSet;
    }
    else
        OSL_ENSURE( false, "invalid TablePropertyMapTarget");
}
/*-- 18.02.2008 11:23:28---------------------------------------------------

  -----------------------------------------------------------------------*/
void TablePropertyMap::insertTableProperties( const PropertyMap* pMap )
{
#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->startElement("TablePropertyMap.insertTableProperties");
    dmapper_logger->addTag(pMap->toTag());
#endif 
    
    const TablePropertyMap* pSource = dynamic_cast< const TablePropertyMap* >(pMap);
    if( pSource )
    {
        for( sal_Int32 eTarget = TablePropertyMapTarget_START; 
            eTarget < TablePropertyMapTarget_MAX; ++eTarget )
        {
            if( pSource->m_aValidValues[eTarget].bValid )
            {
                m_aValidValues[eTarget].bValid = true;
                m_aValidValues[eTarget].nValue = pSource->m_aValidValues[eTarget].nValue;
            }
        }    
    }
#ifdef DEBUG_DOMAINMAPPER
    dmapper_logger->addTag(toTag());
    dmapper_logger->endElement("TablePropertyMap.insertTableProperties");
#endif
}


}//namespace dmapper
}//namespace writerfilter

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
