/**************************************************************
 *
 * 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 <svl/cntnrsrt.hxx>
#include <tools/fontenum.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include "fonthdl.hxx"
#include <xmloff/xmlexp.hxx>
#include <xmloff/XMLFontAutoStylePool.hxx>


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

using namespace ::com::sun::star::uno;
using namespace ::xmloff::token;

int XMLFontAutoStylePoolNameCmp_Impl( const OUString& r1,
									  const OUString& r2 )
{
	return (int)r1.compareTo( r2 );
}

DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePoolNames_Impl,
							OUString )
IMPL_CONTAINER_SORT( XMLFontAutoStylePoolNames_Impl,
					 OUString,
				     XMLFontAutoStylePoolNameCmp_Impl )

class XMLFontAutoStylePoolEntry_Impl
{
	OUString	sName;
	OUString	sFamilyName;
	OUString	sStyleName;
	sal_Int16	nFamily;
	sal_Int16	nPitch;
	rtl_TextEncoding eEnc;

public:

	inline XMLFontAutoStylePoolEntry_Impl(
			const ::rtl::OUString& rName,
			const ::rtl::OUString& rFamilyName,
			const ::rtl::OUString& rStyleName,
			sal_Int16 nFamily,
			sal_Int16 nPitch,
			rtl_TextEncoding eEnc );

	inline XMLFontAutoStylePoolEntry_Impl(
			const ::rtl::OUString& rFamilyName,
			const ::rtl::OUString& rStyleName,
			sal_Int16 nFamily,
			sal_Int16 nPitch,
			rtl_TextEncoding eEnc );

	const OUString&	GetName() const { return sName; }
	const OUString&	GetFamilyName() const { return sFamilyName; }
	const OUString&	GetStyleName() const { return sStyleName; }
	sal_Int16 GetFamily() const {	return nFamily; }
	sal_Int16 GetPitch() const { return nPitch; }
	rtl_TextEncoding GetEncoding() const { return eEnc; }
};


inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
		const ::rtl::OUString& rName,
		const ::rtl::OUString& rFamilyName,
		const ::rtl::OUString& rStyleName,
		sal_Int16 nFam,
		sal_Int16 nP,
		rtl_TextEncoding eE ) :
	sName( rName ),
	sFamilyName( rFamilyName ),
	sStyleName( rStyleName ),
	nFamily( nFam ),
	nPitch( nP ),
	eEnc( eE )
{
}

inline XMLFontAutoStylePoolEntry_Impl::XMLFontAutoStylePoolEntry_Impl(
		const ::rtl::OUString& rFamilyName,
		const ::rtl::OUString& rStyleName,
		sal_Int16 nFam,
		sal_Int16 nP,
		rtl_TextEncoding eE ) :
	sFamilyName( rFamilyName ),
	sStyleName( rStyleName ),
	nFamily( nFam ),
	nPitch( nP ),
	eEnc( eE )
{
}
int XMLFontAutoStylePoolEntryCmp_Impl(
		const XMLFontAutoStylePoolEntry_Impl& r1,
		const XMLFontAutoStylePoolEntry_Impl& r2 )
{
	sal_Int8 nEnc1(r1.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
	sal_Int8 nEnc2(r2.GetEncoding() != RTL_TEXTENCODING_SYMBOL);
	if( nEnc1 != nEnc2 )
		return nEnc1 - nEnc2;
	else if( r1.GetPitch() != r2.GetPitch() )
		return (int)r1.GetPitch() - (int)r2.GetPitch();
	else if( r1.GetFamily() != r2.GetFamily() )
		return (int)r1.GetFamily() - (int)r2.GetFamily();
	else
	{
		sal_Int32 nCmp = r1.GetFamilyName().compareTo( r2.GetFamilyName() );
		if( 0 == nCmp )
			return (int)r1.GetStyleName().compareTo( r2.GetStyleName() );
		else
			return (int)nCmp;
	}
}

typedef XMLFontAutoStylePoolEntry_Impl *XMLFontAutoStylePoolEntryPtr;
DECLARE_CONTAINER_SORT_DEL( XMLFontAutoStylePool_Impl,
							XMLFontAutoStylePoolEntry_Impl )
IMPL_CONTAINER_SORT( XMLFontAutoStylePool_Impl,
					 XMLFontAutoStylePoolEntry_Impl,
					 XMLFontAutoStylePoolEntryCmp_Impl )

XMLFontAutoStylePool::XMLFontAutoStylePool( SvXMLExport& rExp ) :
	rExport( rExp ),
	pPool( new XMLFontAutoStylePool_Impl( 5, 5 ) ),
	pNames( new XMLFontAutoStylePoolNames_Impl( 5, 5 ) )
{
}

XMLFontAutoStylePool::~XMLFontAutoStylePool()
{
	delete pPool;
	delete pNames;
}

OUString XMLFontAutoStylePool::Add(
			const OUString& rFamilyName,
			const OUString& rStyleName,
			sal_Int16 nFamily,
			sal_Int16 nPitch,
			rtl_TextEncoding eEnc )
{
	OUString sPoolName;
	XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
									 	 nPitch, eEnc );
	sal_uLong nPos;
	if( pPool->Seek_Entry( &aTmp, &nPos ) )
	{
		sPoolName = pPool->GetObject( nPos )->GetName();
	}
	else
	{
		OUString sName;
		sal_Int32 nLen = rFamilyName.indexOf( sal_Unicode(';'), 0 );
		if( -1 == nLen )
		{
			sName = rFamilyName;
		}
		else if( nLen > 0 )
		{
			sName = rFamilyName.copy( 0, nLen );
			sName.trim();
		}

		if( !sName.getLength() )
			sName = OUString::valueOf( sal_Unicode( 'F' ) );

		if( pNames->Seek_Entry( &sName, 0 ) )
		{
			sal_Int32 nCount = 1;
			OUString sPrefix( sName );
			sName += OUString::valueOf( nCount );
			while( pNames->Seek_Entry( &sName, 0 ) )
			{
				sName = sPrefix;
				sName += OUString::valueOf( ++nCount );
			}
		}

		XMLFontAutoStylePoolEntry_Impl *pEntry =
			new XMLFontAutoStylePoolEntry_Impl( sName, rFamilyName, rStyleName,
												nFamily, nPitch, eEnc );
		pPool->Insert( pEntry );
		pNames->Insert( new OUString( sName ) );
	}

	return sPoolName;
}

::rtl::OUString XMLFontAutoStylePool::Find(
			const OUString& rFamilyName,
			const OUString& rStyleName,
			sal_Int16 nFamily,
			sal_Int16 nPitch,
			rtl_TextEncoding eEnc ) const
{
	OUString sName;
	XMLFontAutoStylePoolEntry_Impl aTmp( rFamilyName, rStyleName, nFamily,
									 	 nPitch, eEnc );
	sal_uLong nPos;
	if( pPool->Seek_Entry( &aTmp, &nPos ) )
	{
		sName = pPool->GetObject( nPos )->GetName();
	}

	return sName;
}


void XMLFontAutoStylePool::exportXML()
{
	SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_OFFICE,
							  XML_FONT_FACE_DECLS,
							  sal_True, sal_True );
	Any aAny;
	OUString sTmp;
	XMLFontFamilyNamePropHdl aFamilyNameHdl;
	XMLFontFamilyPropHdl aFamilyHdl;
	XMLFontPitchPropHdl aPitchHdl;
	XMLFontEncodingPropHdl aEncHdl;
	const SvXMLUnitConverter& rUnitConv = GetExport().GetMM100UnitConverter();

	sal_uInt32 nCount = pPool->Count();
	for( sal_uInt32 i=0; i<nCount; i++ )
	{
		const XMLFontAutoStylePoolEntry_Impl *pEntry = pPool->GetObject( i );

		GetExport().AddAttribute( XML_NAMESPACE_STYLE,
								  XML_NAME, pEntry->GetName() );

		aAny <<= pEntry->GetFamilyName();
		if( aFamilyNameHdl.exportXML( sTmp, aAny, rUnitConv ) )
			GetExport().AddAttribute( XML_NAMESPACE_SVG,
									  XML_FONT_FAMILY, sTmp );

		const OUString& rStyleName = pEntry->GetStyleName();
		if( rStyleName.getLength() )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
									  XML_FONT_ADORNMENTS,
									  rStyleName );

		aAny <<= (sal_Int16)pEntry->GetFamily();
		if( aFamilyHdl.exportXML( sTmp, aAny, rUnitConv  ) )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
									  XML_FONT_FAMILY_GENERIC, sTmp );

		aAny <<= (sal_Int16)pEntry->GetPitch();
		if( aPitchHdl.exportXML( sTmp, aAny, rUnitConv  ) )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
									  XML_FONT_PITCH, sTmp );

		aAny <<= (sal_Int16)pEntry->GetEncoding();
		if( aEncHdl.exportXML( sTmp, aAny, rUnitConv  ) )
			GetExport().AddAttribute( XML_NAMESPACE_STYLE,
									  XML_FONT_CHARSET, sTmp );

		SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
								  XML_FONT_FACE,
								  sal_True, sal_True );
	}
}
