/**************************************************************
 *
 * 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 <com/sun/star/text/XTextColumns.hpp>
#include <com/sun/star/text/TextColumn.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <xmloff/xmltkmap.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmltoken.hxx>
#include "XMLTextColumnsContext.hxx"
#define _SVSTDARR_USHORTS
#include <svl/svstdarr.hxx>

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::beans;
using namespace ::xmloff::token;

enum SvXMLTokenMapAttrs
{
	XML_TOK_COLUMN_WIDTH,
	XML_TOK_COLUMN_MARGIN_LEFT,
	XML_TOK_COLUMN_MARGIN_RIGHT,
	XML_TOK_COLUMN_END=XML_TOK_UNKNOWN
};

enum SvXMLSepTokenMapAttrs
{
	XML_TOK_COLUMN_SEP_WIDTH,
	XML_TOK_COLUMN_SEP_HEIGHT,
	XML_TOK_COLUMN_SEP_COLOR,
	XML_TOK_COLUMN_SEP_ALIGN,
	XML_TOK_COLUMN_SEP_END=XML_TOK_UNKNOWN
};

static __FAR_DATA SvXMLTokenMapEntry aColAttrTokenMap[] =
{
	{ XML_NAMESPACE_STYLE,	XML_REL_WIDTH,		XML_TOK_COLUMN_WIDTH },
	{ XML_NAMESPACE_FO, 	XML_START_INDENT,	XML_TOK_COLUMN_MARGIN_LEFT },
	{ XML_NAMESPACE_FO,		XML_END_INDENT,		XML_TOK_COLUMN_MARGIN_RIGHT },
	XML_TOKEN_MAP_END
};

static __FAR_DATA SvXMLTokenMapEntry aColSepAttrTokenMap[] =
{
	{ XML_NAMESPACE_STYLE,	XML_WIDTH,			XML_TOK_COLUMN_SEP_WIDTH },
	{ XML_NAMESPACE_STYLE, 	XML_COLOR,			XML_TOK_COLUMN_SEP_COLOR },
	{ XML_NAMESPACE_STYLE, 	XML_HEIGHT,		    XML_TOK_COLUMN_SEP_HEIGHT },
	{ XML_NAMESPACE_STYLE, 	XML_VERTICAL_ALIGN, XML_TOK_COLUMN_SEP_ALIGN },
	XML_TOKEN_MAP_END
};

SvXMLEnumMapEntry __READONLY_DATA pXML_Sep_Align_Enum[] =
{
	{ XML_TOP,			VerticalAlignment_TOP	},
	{ XML_MIDDLE,		VerticalAlignment_MIDDLE },
	{ XML_BOTTOM,		VerticalAlignment_BOTTOM },
	{ XML_TOKEN_INVALID, 0 }
};

class XMLTextColumnContext_Impl: public SvXMLImportContext
{
	text::TextColumn aColumn;

public:
	TYPEINFO();

	XMLTextColumnContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
							   const OUString& rLName,
							   const uno::Reference<
							   		xml::sax::XAttributeList > & xAttrList,
							   const SvXMLTokenMap& rTokenMap );

	virtual ~XMLTextColumnContext_Impl();

	text::TextColumn& getTextColumn() { return aColumn; }
};

TYPEINIT1( XMLTextColumnContext_Impl, SvXMLImportContext );

XMLTextColumnContext_Impl::XMLTextColumnContext_Impl(
							   SvXMLImport& rImport, sal_uInt16 nPrfx,
							   const OUString& rLName,
							   const uno::Reference<
							   		xml::sax::XAttributeList > & xAttrList,
							   const SvXMLTokenMap& rTokenMap ) :
	SvXMLImportContext( rImport, nPrfx, rLName )
{
	aColumn.Width = 0;
	aColumn.LeftMargin = 0;
	aColumn.RightMargin = 0;

	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		sal_Int32 nVal;
		switch( rTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_COLUMN_WIDTH:
			{
				sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'*' );
				if( nPos != -1 && nPos+1 == rValue.getLength() )
				{
					OUString sTmp( rValue.copy( 0, nPos ) );
					if( GetImport().GetMM100UnitConverter().
										convertNumber( nVal, sTmp, 0, USHRT_MAX ) )
					aColumn.Width = nVal;
				}
			}
			break;
		case XML_TOK_COLUMN_MARGIN_LEFT:
			if( GetImport().GetMM100UnitConverter().
										convertMeasure( nVal, rValue ) )
				aColumn.LeftMargin = nVal;
			break;
		case XML_TOK_COLUMN_MARGIN_RIGHT:

			if( GetImport().GetMM100UnitConverter().
										convertMeasure( nVal, rValue ) )
				aColumn.RightMargin = nVal;
			break;
		default:
			break;
		}
	}
}

XMLTextColumnContext_Impl::~XMLTextColumnContext_Impl()
{
}

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

class XMLTextColumnSepContext_Impl: public SvXMLImportContext
{
	sal_Int32 nWidth;
	sal_Int32 nColor;
	sal_Int8 nHeight;
	VerticalAlignment eVertAlign;


public:
	TYPEINFO();

	XMLTextColumnSepContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
							   const OUString& rLName,
							   const uno::Reference<
							   		xml::sax::XAttributeList > & xAttrList,
							   const SvXMLTokenMap& rTokenMap );

	virtual ~XMLTextColumnSepContext_Impl();

	sal_Int32 GetWidth() const { return nWidth; }
	sal_Int32 GetColor() const { return  nColor; }
	sal_Int8 GetHeight() const { return nHeight; }
	VerticalAlignment GetVertAlign() const { return eVertAlign; }
};


TYPEINIT1( XMLTextColumnSepContext_Impl, SvXMLImportContext );

XMLTextColumnSepContext_Impl::XMLTextColumnSepContext_Impl(
							   SvXMLImport& rImport, sal_uInt16 nPrfx,
							   const OUString& rLName,
							   const uno::Reference<
							   		xml::sax::XAttributeList > & xAttrList,
							   const SvXMLTokenMap& rTokenMap ) :
	SvXMLImportContext( rImport, nPrfx, rLName ),
	nWidth( 2 ),
	nColor( 0 ),
	nHeight( 100 ),
	eVertAlign( VerticalAlignment_TOP )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		const OUString& rValue = xAttrList->getValueByIndex( i );

		sal_Int32 nVal;
		switch( rTokenMap.Get( nPrefix, aLocalName ) )
		{
		case XML_TOK_COLUMN_SEP_WIDTH:
			if( GetImport().GetMM100UnitConverter().
								convertMeasure( nVal, rValue ) )
				nWidth = nVal;
			break;
		case XML_TOK_COLUMN_SEP_HEIGHT:
			if( GetImport().GetMM100UnitConverter().
										convertPercent( nVal, rValue ) &&
			 	nVal >=1 && nVal <= 100 )
				nHeight = (sal_Int8)nVal;
			break;
		case XML_TOK_COLUMN_SEP_COLOR:
			{
				Color aColor;
				if( GetImport().GetMM100UnitConverter().
											convertColor( aColor, rValue ) )
					nColor = (sal_Int32)aColor.GetColor();
			}
			break;
		case XML_TOK_COLUMN_SEP_ALIGN:
			{
				sal_uInt16 nAlign;
				if( GetImport().GetMM100UnitConverter().
										convertEnum( nAlign, rValue,
												  	 pXML_Sep_Align_Enum ) )
					eVertAlign = (VerticalAlignment)nAlign;
			}
			break;
		}
	}
}

XMLTextColumnSepContext_Impl::~XMLTextColumnSepContext_Impl()
{
}

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

typedef XMLTextColumnContext_Impl *XMLTextColumnContext_ImplPtr;
SV_DECL_PTRARR( XMLTextColumnsArray_Impl, XMLTextColumnContext_ImplPtr,	5, 5 )

TYPEINIT1( XMLTextColumnsContext, XMLElementPropertyContext );

XMLTextColumnsContext::XMLTextColumnsContext(
								SvXMLImport& rImport, sal_uInt16 nPrfx,
								const OUString& rLName,
								const Reference< xml::sax::XAttributeList >&
									xAttrList,
								const XMLPropertyState& rProp,
				 				::std::vector< XMLPropertyState > &rProps )
:	XMLElementPropertyContext( rImport, nPrfx, rLName, rProp, rProps )
,	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"))
,	pColumns( 0 )
,	pColumnSep( 0 )
,	pColumnAttrTokenMap( new SvXMLTokenMap(aColAttrTokenMap) )
,	pColumnSepAttrTokenMap( new SvXMLTokenMap(aColSepAttrTokenMap) )
,	nCount( 0 )
,	bAutomatic( sal_False )
,	nAutomaticDistance( 0 )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	sal_Int32 nVal;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix =
			GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
															&aLocalName );
		const OUString& rValue = xAttrList->getValueByIndex( i );
		if( XML_NAMESPACE_FO == nPrefix )
        {
			if( IsXMLToken( aLocalName, XML_COLUMN_COUNT ) &&
                GetImport().GetMM100UnitConverter().
								convertNumber( nVal, rValue, 0, SHRT_MAX ) )
            {
                nCount = (sal_Int16)nVal;
            }
            else if( IsXMLToken( aLocalName, XML_COLUMN_GAP ) )
            {
                bAutomatic = GetImport().GetMM100UnitConverter().
                    convertMeasure( nAutomaticDistance, rValue );
            }
        }
	}
}

XMLTextColumnsContext::~XMLTextColumnsContext()
{
	if( pColumns )
	{
		sal_uInt16 nColCount = pColumns->Count();
		while( nColCount )
		{
			nColCount--;
			XMLTextColumnContext_Impl *pColumn = (*pColumns)[nColCount];
			pColumns->Remove( nColCount, 1 );
			pColumn->ReleaseRef();
		}
	}
	if( pColumnSep )
		pColumnSep->ReleaseRef();

	delete pColumns;
	delete pColumnAttrTokenMap;
    delete pColumnSepAttrTokenMap;
}

SvXMLImportContext *XMLTextColumnsContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const uno::Reference< xml::sax::XAttributeList > & xAttrList )
{
	SvXMLImportContext *pContext = 0;

	if( XML_NAMESPACE_STYLE == nPrefix &&
		IsXMLToken( rLocalName, XML_COLUMN ) )
	{
		XMLTextColumnContext_Impl *pColumn =
			new XMLTextColumnContext_Impl( GetImport(), nPrefix, rLocalName,
										   xAttrList, *pColumnAttrTokenMap );

		// add new tabstop to array of tabstops
		if( !pColumns )
			pColumns = new XMLTextColumnsArray_Impl;

		pColumns->Insert( pColumn, pColumns->Count() );
		pColumn->AddRef();

		pContext = pColumn;
	}
	else if( XML_NAMESPACE_STYLE == nPrefix &&
			 IsXMLToken( rLocalName, XML_COLUMN_SEP ) )
	{
		pColumnSep =
			new XMLTextColumnSepContext_Impl( GetImport(), nPrefix, rLocalName,
										   xAttrList, *pColumnSepAttrTokenMap );
		pColumnSep->AddRef();

		pContext = pColumnSep;
	}
	else
	{
		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
	}

	return pContext;
}

void XMLTextColumnsContext::EndElement( )
{
	Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
	if( !xFactory.is() )
		return;

	Reference<XInterface> xIfc = xFactory->createInstance(
		OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextColumns")));
	if( !xIfc.is() )
		return;

	Reference< XTextColumns > xColumns( xIfc, UNO_QUERY );
	if ( 0 == nCount )
	{
		// zero columns = no columns -> 1 column
		xColumns->setColumnCount( 1 );
	}
	else if( !bAutomatic && pColumns &&
             pColumns->Count() == (sal_uInt16)nCount )
	{
        // if we have column descriptions, one per column, and we don't use
        // automatic width, then set the column widths

		sal_Int32 nRelWidth = 0;
		sal_uInt16 nColumnsWithWidth = 0;
		sal_Int16 i;

		for( i = 0; i < nCount; i++ )
		{
			const TextColumn& rColumn =
				(*pColumns)[(sal_uInt16)i]->getTextColumn();
			if( rColumn.Width > 0 )
			{
				nRelWidth += rColumn.Width;
				nColumnsWithWidth++;
			}
		}
		if( nColumnsWithWidth < nCount )
		{
			sal_Int32 nColWidth = 0==nRelWidth
										? USHRT_MAX / nCount
										: nRelWidth / nColumnsWithWidth;

			for( i=0; i < nCount; i++ )
			{
				TextColumn& rColumn =
					(*pColumns)[(sal_uInt16)i]->getTextColumn();
				if( rColumn.Width == 0 )
				{
					rColumn.Width = nColWidth;
					nRelWidth += rColumn.Width;
					if( 0 == --nColumnsWithWidth )
						break;
				}
			}
		}

		Sequence< TextColumn > aColumns( (sal_Int32)nCount );
		TextColumn *pTextColumns = aColumns.getArray();
		for( i=0; i < nCount; i++ )
			*pTextColumns++ = (*pColumns)[(sal_uInt16)i]->getTextColumn();

		xColumns->setColumns( aColumns );
	}
	else
	{
        // only set column count (and let the columns be distributed
        // automatically)

		xColumns->setColumnCount( nCount );
	}

	Reference < XPropertySet > xPropSet( xColumns, UNO_QUERY );
	if( xPropSet.is() )
	{
		Any aAny;
		sal_Bool bOn = pColumnSep != 0;

		aAny.setValue( &bOn, ::getBooleanCppuType() );
		xPropSet->setPropertyValue( sSeparatorLineIsOn, aAny );

		if( pColumnSep )
		{
			if( pColumnSep->GetWidth() )
			{
				aAny <<= pColumnSep->GetWidth();
				xPropSet->setPropertyValue( sSeparatorLineWidth, aAny );
			}
			if( pColumnSep->GetHeight() )
			{
				aAny <<= pColumnSep->GetHeight();
				xPropSet->setPropertyValue( sSeparatorLineRelativeHeight,
											aAny );
			}


			aAny <<= pColumnSep->GetColor();
			xPropSet->setPropertyValue( sSeparatorLineColor, aAny );


			aAny <<= pColumnSep->GetVertAlign();
			xPropSet->setPropertyValue( sSeparatorLineVerticalAlignment, aAny );
		}

        // handle 'automatic columns': column distance
        if( bAutomatic )
        {
            aAny <<= nAutomaticDistance;
            xPropSet->setPropertyValue( sAutomaticDistance, aAny );
        }
	}

	aProp.maValue <<= xColumns;

	SetInsert( sal_True );
	XMLElementPropertyContext::EndElement();

}
