/**************************************************************
 * 
 * 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_toolkit.hxx"


#include <toolkit/awt/vclxfont.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/macros.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <rtl/memory.h>
#include <rtl/uuid.h>
#include <rtl/ustring.h>

#include <vcl/outdev.hxx>

//	----------------------------------------------------
//	class VCLXFont
//	----------------------------------------------------
VCLXFont::VCLXFont()
{
	mpFontMetric = NULL;
}

VCLXFont::~VCLXFont()
{
	delete mpFontMetric;
}

void VCLXFont::Init( ::com::sun::star::awt::XDevice& rxDev, const Font& rFont )
{
	mxDevice = &rxDev;

	delete mpFontMetric;
	mpFontMetric = NULL;

	maFont = rFont;
}

sal_Bool VCLXFont::ImplAssertValidFontMetric()
{
	if ( !mpFontMetric && mxDevice.is() )
	{
		OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
		if ( pOutDev )
		{
			Font aOldFont = pOutDev->GetFont();
			pOutDev->SetFont( maFont );
			mpFontMetric = new FontMetric( pOutDev->GetFontMetric() );
			pOutDev->SetFont( aOldFont );
		}
	}
	return mpFontMetric ? sal_True : sal_False;
}


// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXFont::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException)
{
	::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType,
										SAL_STATIC_CAST( ::com::sun::star::awt::XFont*, this ),
                                        SAL_STATIC_CAST( ::com::sun::star::awt::XFont2*, this ),
										SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ),
										SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ) );
	return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
}

// ::com::sun::star::lang::XUnoTunnel
IMPL_XUNOTUNNEL( VCLXFont )

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXFont )
    getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont2>* ) NULL )
IMPL_XTYPEPROVIDER_END


::com::sun::star::awt::FontDescriptor VCLXFont::getFontDescriptor(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	return VCLUnoHelper::CreateFontDescriptor( maFont );

}

::com::sun::star::awt::SimpleFontMetric VCLXFont::getFontMetric(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::awt::SimpleFontMetric aFM;
	if ( ImplAssertValidFontMetric() ) 
		aFM = VCLUnoHelper::CreateFontMetric( *mpFontMetric );
	return aFM;
}

sal_Int16 VCLXFont::getCharWidth( sal_Unicode c ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_Int16 nRet = -1;
	OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
	if ( pOutDev )
	{
		Font aOldFont = pOutDev->GetFont();
		pOutDev->SetFont( maFont );
		
		nRet = sal::static_int_cast< sal_Int16 >(
            pOutDev->GetTextWidth( String(c) ));

		pOutDev->SetFont( aOldFont );
	}
	return nRet;
}

::com::sun::star::uno::Sequence< sal_Int16 > VCLXFont::getCharWidths( sal_Unicode nFirst, sal_Unicode nLast ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	::com::sun::star::uno::Sequence<sal_Int16> aSeq;
	OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
	if ( pOutDev )
	{
		Font aOldFont = pOutDev->GetFont();
		pOutDev->SetFont( maFont );
		
		sal_Int16 nCount = nLast-nFirst + 1;
		aSeq = ::com::sun::star::uno::Sequence<sal_Int16>( nCount );
		for ( sal_uInt16 n = 0; n < nCount; n++ )
		{
			aSeq.getArray()[n] = sal::static_int_cast< sal_Int16 >(
                pOutDev->GetTextWidth(
                    String(static_cast< sal_Unicode >(nFirst+n)) ));
		}

		pOutDev->SetFont( aOldFont );
	}
	return aSeq;
}

sal_Int32 VCLXFont::getStringWidth( const ::rtl::OUString& str ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_Int32 nRet = -1;
	OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
	if ( pOutDev )
	{
		Font aOldFont = pOutDev->GetFont();
		pOutDev->SetFont( maFont );
		nRet = pOutDev->GetTextWidth( str );
		pOutDev->SetFont( aOldFont );
	}
	return nRet;
}

sal_Int32 VCLXFont::getStringWidthArray( const ::rtl::OUString& str, ::com::sun::star::uno::Sequence< sal_Int32 >& rDXArray ) throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_Int32 nRet = -1;
	OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
	if ( pOutDev )
	{
		Font aOldFont = pOutDev->GetFont();
		pOutDev->SetFont( maFont );
		rDXArray = ::com::sun::star::uno::Sequence<sal_Int32>( str.getLength() );
		nRet = pOutDev->GetTextArray( str, rDXArray.getArray() );
		pOutDev->SetFont( aOldFont );
	}
	return nRet;
}

void VCLXFont::getKernPairs( ::com::sun::star::uno::Sequence< sal_Unicode >& /*rnChars1*/, ::com::sun::star::uno::Sequence< sal_Unicode >& /*rnChars2*/, ::com::sun::star::uno::Sequence< sal_Int16 >& /*rnKerns*/ ) throw(::com::sun::star::uno::RuntimeException)
{
	// NOTE: this empty method is just used for keeping the related UNO-API stable
}

// ::com::sun::star::awt::XFont2
sal_Bool VCLXFont::hasGlyphs( const ::rtl::OUString& aText )
    throw(::com::sun::star::uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    OutputDevice* pOutDev = VCLUnoHelper::GetOutputDevice( mxDevice );
    if ( pOutDev )
    {
        String aStr( aText );
        if ( pOutDev->HasGlyphs( maFont, aStr, 0, aStr.Len() ) == STRING_LEN )
        {
            return sal_True;
        }
    }

    return sal_False;
}
