/**************************************************************
 * 
 * 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/awt/FontFamily.hpp>
#include <com/sun/star/awt/FontPitch.hpp>

#include <rtl/logfile.hxx>

#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include "fonthdl.hxx"
#include <xmloff/xmlimp.hxx>
#include <xmloff/maptype.hxx>
#include <xmloff/XMLFontStylesContext.hxx>


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

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::awt;
using namespace ::xmloff::token;


#define XML_STYLE_FAMILY_FONT 1

enum XMLFontStyleAttrTokens
{
	XML_TOK_FONT_STYLE_ATTR_FAMILY,
	XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC,
	XML_TOK_FONT_STYLE_ATTR_STYLENAME,
	XML_TOK_FONT_STYLE_ATTR_PITCH,
	XML_TOK_FONT_STYLE_ATTR_CHARSET,

	XML_TOK_FONT_STYLE_ATTR_END=XML_TOK_UNKNOWN
};

const SvXMLTokenMapEntry* lcl_getFontStyleAttrTokenMap()
{
    static __FAR_DATA SvXMLTokenMapEntry aFontStyleAttrTokenMap[] =
    {
	    { XML_NAMESPACE_SVG, XML_FONT_FAMILY,
			    XML_TOK_FONT_STYLE_ATTR_FAMILY },
	    { XML_NAMESPACE_STYLE, XML_FONT_FAMILY_GENERIC,
			    XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC },
	    { XML_NAMESPACE_STYLE, XML_FONT_ADORNMENTS,
			    XML_TOK_FONT_STYLE_ATTR_STYLENAME },
	    { XML_NAMESPACE_STYLE, XML_FONT_PITCH,
			    XML_TOK_FONT_STYLE_ATTR_PITCH },
	    { XML_NAMESPACE_STYLE, XML_FONT_CHARSET,
			    XML_TOK_FONT_STYLE_ATTR_CHARSET },

	    XML_TOKEN_MAP_END
    };
    return aFontStyleAttrTokenMap;
}

class XMLFontStyleContext_Impl : public SvXMLStyleContext
{
	Any aFamilyName;
	Any aStyleName;
	Any aFamily;
	Any aPitch;
	Any aEnc;

	SvXMLImportContextRef xStyles;

	XMLFontStylesContext *GetStyles()
	{
		return ((XMLFontStylesContext *)&xStyles);
	}

public:

	TYPEINFO();

	XMLFontStyleContext_Impl( SvXMLImport& rImport, sal_uInt16 nPrfx,
			const ::rtl::OUString& rLName,
			const ::com::sun::star::uno::Reference<
				::com::sun::star::xml::sax::XAttributeList > & xAttrList,
			XMLFontStylesContext& rStyles );
	virtual ~XMLFontStyleContext_Impl();

	void SetAttribute( sal_uInt16 nPrefixKey, const OUString& rLocalName,
					   const OUString& rValue );

	void FillProperties( ::std::vector< XMLPropertyState > &rProps,
						 sal_Int32 nFamilyNameIdx,
						 sal_Int32 nStyleNameIdx,
						 sal_Int32 nFamilyIdx,
						 sal_Int32 nPitchIdx,
						 sal_Int32 nCharsetIdx ) const;

};

TYPEINIT1( XMLFontStyleContext_Impl, SvXMLStyleContext );

XMLFontStyleContext_Impl::XMLFontStyleContext_Impl( SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & xAttrList,
		XMLFontStylesContext& rStyles ) :
	SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XML_STYLE_FAMILY_FONT ),
	xStyles( &rStyles )
{
	OUString sEmpty;
	aFamilyName <<= sEmpty;
	aStyleName <<= sEmpty;
	aFamily <<= (sal_Int16)FontFamily::DONTKNOW;
	aPitch <<= (sal_Int16)FontPitch::DONTKNOW;
	aEnc <<= (sal_Int16)rStyles.GetDfltCharset();
}

void XMLFontStyleContext_Impl::SetAttribute( sal_uInt16 nPrefixKey,
										const OUString& rLocalName,
										const OUString& rValue )
{
	SvXMLUnitConverter& rUnitConv = GetImport().GetMM100UnitConverter();
	const SvXMLTokenMap& rTokenMap = GetStyles()->GetFontStyleAttrTokenMap();
	Any aAny;

	switch( rTokenMap.Get( nPrefixKey, rLocalName ) )
	{
	case XML_TOK_FONT_STYLE_ATTR_FAMILY:
		if( GetStyles()->GetFamilyNameHdl().importXML( rValue, aAny,
														  rUnitConv ) )
			aFamilyName = aAny;
		break;
	case XML_TOK_FONT_STYLE_ATTR_STYLENAME:
		aStyleName <<= rValue;
		break;
	case XML_TOK_FONT_STYLE_ATTR_FAMILY_GENERIC:
		if( GetStyles()->GetFamilyHdl().importXML( rValue, aAny,
													  rUnitConv ) )
			aFamily = aAny;
		break;
	case XML_TOK_FONT_STYLE_ATTR_PITCH:
		if( GetStyles()->GetPitchHdl().importXML( rValue, aAny,
													  rUnitConv ) )
			aPitch = aAny;
		break;
	case XML_TOK_FONT_STYLE_ATTR_CHARSET:
		if( GetStyles()->GetEncodingHdl().importXML( rValue, aAny,
													  rUnitConv ) )
			aEnc = aAny;
		break;
	default:
		SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
		break;
	}
}

XMLFontStyleContext_Impl::~XMLFontStyleContext_Impl()
{
}

void XMLFontStyleContext_Impl::FillProperties(
		::std::vector< XMLPropertyState > &rProps,
		sal_Int32 nFamilyNameIdx,
		sal_Int32 nStyleNameIdx,
		sal_Int32 nFamilyIdx,
		sal_Int32 nPitchIdx,
		sal_Int32 nCharsetIdx ) const
{
	if( nFamilyNameIdx != -1 )
	{
		XMLPropertyState aPropState( nFamilyNameIdx, aFamilyName );
		rProps.push_back( aPropState );
	}
	if( nStyleNameIdx != -1 )
	{
		XMLPropertyState aPropState( nStyleNameIdx, aStyleName );
		rProps.push_back( aPropState );
	}
	if( nFamilyIdx != -1 )
	{
		XMLPropertyState aPropState( nFamilyIdx, aFamily );
		rProps.push_back( aPropState );
	}
	if( nPitchIdx != -1 )
	{
		XMLPropertyState aPropState( nPitchIdx, aPitch );
		rProps.push_back( aPropState );
	}
	if( nCharsetIdx != -1 )
	{
		XMLPropertyState aPropState( nCharsetIdx, aEnc );
		rProps.push_back( aPropState );
	}
}

SvXMLStyleContext *XMLFontStylesContext::CreateStyleChildContext(
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		const ::com::sun::star::uno::Reference<
			::com::sun::star::xml::sax::XAttributeList > & xAttrList )
{
	SvXMLStyleContext *pStyle;
	if( XML_NAMESPACE_STYLE == nPrefix &&
		IsXMLToken( rLocalName, XML_FONT_FACE ) )
	{
		pStyle = new XMLFontStyleContext_Impl( GetImport(), nPrefix,
											   rLocalName, xAttrList, *this );
	}
	else
	{
		pStyle = SvXMLStylesContext::CreateStyleChildContext( nPrefix,
											   rLocalName, xAttrList );
	}

	return pStyle;
}

TYPEINIT1( XMLFontStylesContext, SvXMLStylesContext );

XMLFontStylesContext::XMLFontStylesContext( SvXMLImport& rImport,
		sal_uInt16 nPrfx, const OUString& rLName,
		const Reference< XAttributeList > & xAttrList,
		rtl_TextEncoding eDfltEnc ) :
	SvXMLStylesContext( rImport, nPrfx, rLName, xAttrList ),
	pFamilyNameHdl( new XMLFontFamilyNamePropHdl ),
	pFamilyHdl( new XMLFontFamilyPropHdl ),
	pPitchHdl( new XMLFontPitchPropHdl ),
	pEncHdl( new XMLFontEncodingPropHdl ),
	pFontStyleAttrTokenMap( new SvXMLTokenMap(lcl_getFontStyleAttrTokenMap()) ),
	eDfltEncoding( eDfltEnc )
{
}

XMLFontStylesContext::~XMLFontStylesContext()
{
	delete pFamilyNameHdl;
	delete pFamilyHdl;
	delete pPitchHdl;
	delete pEncHdl;
	delete pFontStyleAttrTokenMap;
}

sal_Bool XMLFontStylesContext::FillProperties( const OUString& rName,
						 ::std::vector< XMLPropertyState > &rProps,
						 sal_Int32 nFamilyNameIdx,
						 sal_Int32 nStyleNameIdx,
						 sal_Int32 nFamilyIdx,
						 sal_Int32 nPitchIdx,
						 sal_Int32 nCharsetIdx ) const
{
    const SvXMLStyleContext* pStyle = FindStyleChildContext( XML_STYLE_FAMILY_FONT, rName, sal_True );
	const XMLFontStyleContext_Impl *pFontStyle = PTR_CAST( XMLFontStyleContext_Impl,pStyle);// use temp var, PTR_CAST is a bad macro, FindStyleChildContext will be called twice
	if( pFontStyle )
		pFontStyle->FillProperties( rProps, nFamilyNameIdx, nStyleNameIdx,
									nFamilyIdx, nPitchIdx, nCharsetIdx );
	return 0 != pFontStyle;
}
