/**************************************************************
 * 
 * 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();

}
