/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include <tools/debug.hxx>
#include <rtl/ustrbuf.hxx>


#include <com/sun/star/text/XTextColumns.hpp>
#include <com/sun/star/text/TextColumn.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>


#include <xmloff/xmltoken.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlexp.hxx>
#include "XMLTextColumnsExport.hxx"

using namespace ::com::sun::star::style;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::xmloff::token;


XMLTextColumnsExport::XMLTextColumnsExport( SvXMLExport& rExp ) :
	rExport( rExp ),
	sSeparatorLineIsOn(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineIsOn")),
	sSeparatorLineWidth(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineWidth")),
	sSeparatorLineColor(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineColor")),
	sSeparatorLineRelativeHeight(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineRelativeHeight")),
	sSeparatorLineVerticalAlignment(RTL_CONSTASCII_USTRINGPARAM("SeparatorLineVerticalAlignment")),
    sIsAutomatic(RTL_CONSTASCII_USTRINGPARAM("IsAutomatic")),
    sAutomaticDistance(RTL_CONSTASCII_USTRINGPARAM("AutomaticDistance"))
{
}

void XMLTextColumnsExport::exportXML( const Any& rAny )
{
	Reference < XTextColumns > xColumns;
	rAny >>= xColumns;

	Sequence < TextColumn > aColumns = xColumns->getColumns();
	const TextColumn *pColumns = aColumns.getArray();
	sal_Int32 nCount = aColumns.getLength();

	OUStringBuffer sValue;
	GetExport().GetMM100UnitConverter().convertNumber( sValue, nCount ? nCount : 1 );
	GetExport().AddAttribute( XML_NAMESPACE_FO, XML_COLUMN_COUNT,
							  sValue.makeStringAndClear() );

    // handle 'automatic' columns
	Reference < XPropertySet > xPropSet( xColumns, UNO_QUERY );
    if( xPropSet.is() )
    {
        Any aAny = xPropSet->getPropertyValue( sIsAutomatic );
        if ( *(sal_Bool*)aAny.getValue() )
        {
            aAny = xPropSet->getPropertyValue( sAutomaticDistance );
            sal_Int32 nDistance = 0;
            aAny >>= nDistance;
            OUStringBuffer aBuffer;
            GetExport().GetMM100UnitConverter().convertMeasure(
                aBuffer, nDistance );
            GetExport().AddAttribute( XML_NAMESPACE_FO,
                                      XML_COLUMN_GAP,
                                      aBuffer.makeStringAndClear() );
        }
    }

	SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_COLUMNS,
							  sal_True, sal_True );

	if( xPropSet.is() )
	{
		Any aAny = xPropSet->getPropertyValue( sSeparatorLineIsOn );
		if( *(sal_Bool *)aAny.getValue() )
		{
			// style:width
			aAny = xPropSet->getPropertyValue( sSeparatorLineWidth );
			sal_Int32 nWidth = 0;
			aAny >>= nWidth;
			GetExport().GetMM100UnitConverter().convertMeasure( sValue,
																nWidth );
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_WIDTH,
									  sValue.makeStringAndClear() );

			// style:color
			aAny = xPropSet->getPropertyValue( sSeparatorLineColor );
			sal_Int32 nColor = 0;
			aAny >>= nColor;
			GetExport().GetMM100UnitConverter().convertColor( sValue,
															  nColor );
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_COLOR,
									  sValue.makeStringAndClear() );

			// style:height
			aAny = xPropSet->getPropertyValue( sSeparatorLineRelativeHeight );
			sal_Int8 nHeight = 0;
			aAny >>= nHeight;
			GetExport().GetMM100UnitConverter().convertPercent( sValue,
																nHeight );
			GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_HEIGHT,
									  sValue.makeStringAndClear() );

			// style:vertical-align
			aAny = xPropSet->getPropertyValue( sSeparatorLineVerticalAlignment );
			VerticalAlignment eVertAlign;
			aAny >>= eVertAlign;

			enum XMLTokenEnum eStr = XML_TOKEN_INVALID;
			switch( eVertAlign )
			{
//			case VerticalAlignment_TOP: eStr = XML_TOP;
			case VerticalAlignment_MIDDLE: eStr = XML_MIDDLE; break;
			case VerticalAlignment_BOTTOM: eStr = XML_BOTTOM; break;
			default:
				break;
			}

			if( eStr != XML_TOKEN_INVALID)
				GetExport().AddAttribute( XML_NAMESPACE_STYLE,
                                          XML_VERTICAL_ALIGN, eStr );

			// style:column-sep
			SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
									  XML_COLUMN_SEP,
									  sal_True, sal_True );
		}
	}

	while( nCount-- )
	{
		// style:rel-width
		GetExport().GetMM100UnitConverter().convertNumber( sValue,
													   pColumns->Width );
		sValue.append( (sal_Unicode)'*' );
		GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_REL_WIDTH,
								  sValue.makeStringAndClear() );

		// fo:margin-left
		GetExport().GetMM100UnitConverter().convertMeasure( sValue,
													   pColumns->LeftMargin );
		GetExport().AddAttribute( XML_NAMESPACE_FO, XML_START_INDENT,
			   				  	  sValue.makeStringAndClear() );

		// fo:margin-right
		GetExport().GetMM100UnitConverter().convertMeasure( sValue,
													   pColumns->RightMargin );
		GetExport().AddAttribute( XML_NAMESPACE_FO, XML_END_INDENT,
				  				  sValue.makeStringAndClear() );

		// style:column
		SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE, XML_COLUMN,
								  sal_True, sal_True );
		pColumns++;
	}
}
