/**************************************************************
 *
 * 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 <tools/debug.hxx>
#include <tools/stream.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/window.hxx>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <com/sun/star/awt/XBitmap.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XDevice.hpp>
#include <com/sun/star/awt/XPointer.hpp>
#include <com/sun/star/awt/SimpleFontMetric.hpp>
#include <com/sun/star/awt/FontDescriptor.hpp>
#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/awt/FontWidth.hpp>
#include <com/sun/star/awt/KeyModifier.hpp>
#include <com/sun/star/awt/MouseButton.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/embed/EmbedMapUnits.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/convert.hxx>
#include <toolkit/awt/vclxbitmap.hxx>
#include <toolkit/awt/vclxregion.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#include <toolkit/awt/vclxgraphics.hxx>
#include <toolkit/awt/vclxpointer.hxx>
#include <toolkit/awt/vclxfont.hxx>
#include <toolkit/controls/unocontrolcontainer.hxx>
#include <toolkit/controls/unocontrolcontainermodel.hxx>
#include <vcl/graph.hxx>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/Point.hpp>
#include <vcl/dibtools.hxx>

using namespace ::com::sun::star;

//	----------------------------------------------------
//	class VCLUnoHelper
//	----------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> VCLUnoHelper::CreateToolkit()
{
	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
	::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface > xI = xMSF->createInstance( ::rtl::OUString::createFromAscii( szServiceName2_Toolkit ) );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit> xToolkit;
	if ( xI.is() )
		xToolkit = ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit>( xI, ::com::sun::star::uno::UNO_QUERY );

	return xToolkit;
}

BitmapEx VCLUnoHelper::GetBitmap( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap>& rxBitmap )
{
	BitmapEx aBmp;

	::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > xGraphic( rxBitmap, ::com::sun::star::uno::UNO_QUERY );
	if( xGraphic.is() )
	{
		Graphic aGraphic( xGraphic );
		aBmp = aGraphic.GetBitmapEx();
	}
	else if ( rxBitmap.is() )
	{
		VCLXBitmap* pVCLBitmap = VCLXBitmap::GetImplementation( rxBitmap );
		if ( pVCLBitmap )
			aBmp = pVCLBitmap->GetBitmap();
		else
		{
			Bitmap aDIB, aMask;
			{
				::com::sun::star::uno::Sequence<sal_Int8> aBytes = rxBitmap->getDIB();
				SvMemoryStream aMem( (char*) aBytes.getArray(), aBytes.getLength(), STREAM_READ );
                ReadDIB(aDIB, aMem, true);
			}
			{
				::com::sun::star::uno::Sequence<sal_Int8> aBytes = rxBitmap->getMaskDIB();
				SvMemoryStream aMem( (char*) aBytes.getArray(), aBytes.getLength(), STREAM_READ );
                ReadDIB(aMask, aMem, true);
			}
			aBmp = BitmapEx( aDIB, aMask );
		}
	}
	return aBmp;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap> VCLUnoHelper::CreateBitmap( const BitmapEx& rBitmap )
{
	Graphic aGraphic( rBitmap );
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap> xBmp( aGraphic.GetXGraphic(), ::com::sun::star::uno::UNO_QUERY );
	return xBmp;
}

Window* VCLUnoHelper::GetWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow>& rxWindow )
{
	VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( rxWindow );
	return pVCLXWindow ? pVCLXWindow->GetWindow() : NULL;
}

Window* VCLUnoHelper::GetWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow2>& rxWindow )
{
	VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( rxWindow );
	return pVCLXWindow ? pVCLXWindow->GetWindow() : NULL;
}

Window* VCLUnoHelper::GetWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer>& rxWindow )
{
	VCLXWindow* pVCLXWindow = VCLXWindow::GetImplementation( rxWindow );
	return pVCLXWindow ? pVCLXWindow->GetWindow() : NULL;
}

Region VCLUnoHelper::GetRegion( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >& rxRegion )
{
	Region aRegion;
	VCLXRegion* pVCLRegion = VCLXRegion::GetImplementation( rxRegion );
	if ( pVCLRegion )
		aRegion = pVCLRegion->GetRegion();
	else
	{
		::com::sun::star::uno::Sequence< ::com::sun::star::awt::Rectangle > aRects = rxRegion->getRectangles();
		sal_Int32 nRects = aRects.getLength();
		for ( sal_Int32 n = 0; n < nRects; n++ )
			aRegion.Union( VCLRectangle( aRects.getArray()[n] ) );
	}
	return aRegion;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> VCLUnoHelper::GetInterface( Window* pWindow )
{
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > xWin;
	if ( pWindow )
	{
		::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer> xPeer = pWindow->GetComponentInterface();
		xWin = xWin.query( xPeer );
	}
	return xWin;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XPointer> VCLUnoHelper::CreatePointer()
{
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XPointer> xPointer = new VCLXPointer;
	return xPointer;
}

OutputDevice* VCLUnoHelper::GetOutputDevice( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice>& rxDevice )
{
	OutputDevice* pOutDev = NULL;
	VCLXDevice* pDev = VCLXDevice::GetImplementation( rxDevice );
	if ( pDev )
		pOutDev = pDev->GetOutputDevice();
	return pOutDev;
}

OutputDevice* VCLUnoHelper::GetOutputDevice( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics>& rxGraphics )
{
	OutputDevice* pOutDev = NULL;
	VCLXGraphics* pGrf = VCLXGraphics::GetImplementation( rxGraphics );
	if ( pGrf )
		pOutDev = pGrf->GetOutputDevice();
	return pOutDev;
}

Polygon VCLUnoHelper::CreatePolygon( const ::com::sun::star::uno::Sequence< sal_Int32 >& DataX, const ::com::sun::star::uno::Sequence< sal_Int32 >& DataY )
{
	sal_uInt32 nLen = DataX.getLength();
	const sal_Int32* pDataX = DataX.getConstArray();
	const sal_Int32* pDataY = DataY.getConstArray();
	Polygon aPoly( (sal_uInt16) nLen );
	for ( sal_uInt16 n = 0; n < nLen; n++ )
	{
		Point aPnt;
		aPnt.X() = pDataX[n];
		aPnt.Y() = pDataY[n];
		aPoly[n] = aPnt;
	}
	return aPoly;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer> VCLUnoHelper::CreateControlContainer( Window* pWindow )
{
    const uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
	UnoControlContainer* pContainer = new UnoControlContainer( xFactory, pWindow->GetComponentInterface( sal_True ) );
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > x = pContainer;

    UnoControlModel* pContainerModel = new UnoControlContainerModel( xFactory );
	pContainer->setModel( (::com::sun::star::awt::XControlModel*)pContainerModel );

	return x;
}

float VCLUnoHelper::ConvertFontWidth( FontWidth eWidth )
{
	if( eWidth == WIDTH_DONTKNOW )
		return ::com::sun::star::awt::FontWidth::DONTKNOW;
	else if( eWidth == WIDTH_ULTRA_CONDENSED )
		return ::com::sun::star::awt::FontWidth::ULTRACONDENSED;
	else if( eWidth == WIDTH_EXTRA_CONDENSED )
		return ::com::sun::star::awt::FontWidth::EXTRACONDENSED;
	else if( eWidth == WIDTH_CONDENSED )
		return ::com::sun::star::awt::FontWidth::CONDENSED;
	else if( eWidth == WIDTH_SEMI_CONDENSED )
		return ::com::sun::star::awt::FontWidth::SEMICONDENSED;
	else if( eWidth == WIDTH_NORMAL )
		return ::com::sun::star::awt::FontWidth::NORMAL;
	else if( eWidth == WIDTH_SEMI_EXPANDED )
		return ::com::sun::star::awt::FontWidth::SEMIEXPANDED;
	else if( eWidth == WIDTH_EXPANDED )
		return ::com::sun::star::awt::FontWidth::EXPANDED;
	else if( eWidth == WIDTH_EXTRA_EXPANDED )
		return ::com::sun::star::awt::FontWidth::EXTRAEXPANDED;
	else if( eWidth == WIDTH_ULTRA_EXPANDED )
		return ::com::sun::star::awt::FontWidth::ULTRAEXPANDED;

	DBG_ERROR( "Unknown FontWidth" );
	return ::com::sun::star::awt::FontWidth::DONTKNOW;
}

FontWidth VCLUnoHelper::ConvertFontWidth( float f )
{
	if( f <= ::com::sun::star::awt::FontWidth::DONTKNOW )
		return WIDTH_DONTKNOW;
	else if( f <= ::com::sun::star::awt::FontWidth::ULTRACONDENSED )
		return WIDTH_ULTRA_CONDENSED;
	else if( f <= ::com::sun::star::awt::FontWidth::EXTRACONDENSED )
		return WIDTH_EXTRA_CONDENSED;
	else if( f <= ::com::sun::star::awt::FontWidth::CONDENSED )
		return WIDTH_CONDENSED;
	else if( f <= ::com::sun::star::awt::FontWidth::SEMICONDENSED )
		return WIDTH_SEMI_CONDENSED;
	else if( f <= ::com::sun::star::awt::FontWidth::NORMAL )
		return WIDTH_NORMAL;
	else if( f <= ::com::sun::star::awt::FontWidth::SEMIEXPANDED )
		return WIDTH_SEMI_EXPANDED;
	else if( f <= ::com::sun::star::awt::FontWidth::EXPANDED )
		return WIDTH_EXPANDED;
	else if( f <= ::com::sun::star::awt::FontWidth::EXTRAEXPANDED )
		return WIDTH_EXTRA_EXPANDED;
	else if( f <= ::com::sun::star::awt::FontWidth::ULTRAEXPANDED )
		return WIDTH_ULTRA_EXPANDED;

	DBG_ERROR( "Unknown FontWidth" );
	return WIDTH_DONTKNOW;
}

float VCLUnoHelper::ConvertFontWeight( FontWeight eWeight )
{
	if( eWeight == WEIGHT_DONTKNOW )
		return ::com::sun::star::awt::FontWeight::DONTKNOW;
	else if( eWeight == WEIGHT_THIN )
		return ::com::sun::star::awt::FontWeight::THIN;
	else if( eWeight == WEIGHT_ULTRALIGHT )
		return ::com::sun::star::awt::FontWeight::ULTRALIGHT;
	else if( eWeight == WEIGHT_LIGHT )
		return ::com::sun::star::awt::FontWeight::LIGHT;
	else if( eWeight == WEIGHT_SEMILIGHT )
		return ::com::sun::star::awt::FontWeight::SEMILIGHT;
	else if( ( eWeight == WEIGHT_NORMAL ) || ( eWeight == WEIGHT_MEDIUM ) )
		return ::com::sun::star::awt::FontWeight::NORMAL;
	else if( eWeight == WEIGHT_SEMIBOLD )
		return ::com::sun::star::awt::FontWeight::SEMIBOLD;
	else if( eWeight == WEIGHT_BOLD )
		return ::com::sun::star::awt::FontWeight::BOLD;
	else if( eWeight == WEIGHT_ULTRABOLD )
		return ::com::sun::star::awt::FontWeight::ULTRABOLD;
	else if( eWeight == WEIGHT_BLACK )
		return ::com::sun::star::awt::FontWeight::BLACK;

	DBG_ERROR( "Unknown FontWeigth" );
	return ::com::sun::star::awt::FontWeight::DONTKNOW;
}

FontWeight VCLUnoHelper::ConvertFontWeight( float f )
{
	if( f <= ::com::sun::star::awt::FontWeight::DONTKNOW )
		return WEIGHT_DONTKNOW;
	else if( f <= ::com::sun::star::awt::FontWeight::THIN )
		return WEIGHT_THIN;
	else if( f <= ::com::sun::star::awt::FontWeight::ULTRALIGHT )
		return WEIGHT_ULTRALIGHT;
	else if( f <= ::com::sun::star::awt::FontWeight::LIGHT )
		return WEIGHT_LIGHT;
	else if( f <= ::com::sun::star::awt::FontWeight::SEMILIGHT )
		return WEIGHT_SEMILIGHT;
	else if( f <= ::com::sun::star::awt::FontWeight::NORMAL )
		return WEIGHT_NORMAL;
	else if( f <= ::com::sun::star::awt::FontWeight::SEMIBOLD )
		return WEIGHT_SEMIBOLD;
	else if( f <= ::com::sun::star::awt::FontWeight::BOLD )
		return WEIGHT_BOLD;
	else if( f <= ::com::sun::star::awt::FontWeight::ULTRABOLD )
		return WEIGHT_ULTRABOLD;
	else if( f <= ::com::sun::star::awt::FontWeight::BLACK )
		return WEIGHT_BLACK;

	DBG_ERROR( "Unknown FontWeigth" );
	return WEIGHT_DONTKNOW;
}


::com::sun::star::awt::FontDescriptor VCLUnoHelper::CreateFontDescriptor( const Font& rFont )
{
	::com::sun::star::awt::FontDescriptor aFD;
    aFD.Name = rFont.GetName();
    aFD.StyleName = rFont.GetStyleName();
    aFD.Height = (sal_Int16)rFont.GetSize().Height();
    aFD.Width = (sal_Int16)rFont.GetSize().Width();
    aFD.Family = sal::static_int_cast< sal_Int16 >(rFont.GetFamily());
    aFD.CharSet = rFont.GetCharSet();
    aFD.Pitch = sal::static_int_cast< sal_Int16 >(rFont.GetPitch());
    aFD.CharacterWidth = VCLUnoHelper::ConvertFontWidth( rFont.GetWidthType() );
    aFD.Weight= VCLUnoHelper::ConvertFontWeight( rFont.GetWeight() );
    aFD.Slant = (::com::sun::star::awt::FontSlant)rFont.GetItalic();
    aFD.Underline = sal::static_int_cast< sal_Int16 >(rFont.GetUnderline());
    aFD.Strikeout = sal::static_int_cast< sal_Int16 >(rFont.GetStrikeout());
    aFD.Orientation = rFont.GetOrientation();
    aFD.Kerning = rFont.IsKerning();
    aFD.WordLineMode = rFont.IsWordLineMode();
    aFD.Type = 0;	// ??? => Nur an Metric...
	return aFD;
}

Font VCLUnoHelper::CreateFont( const ::com::sun::star::awt::FontDescriptor& rDescr, const Font& rInitFont )
{
	Font aFont( rInitFont );
	if ( rDescr.Name.getLength() )
		aFont.SetName( rDescr.Name );
	if ( rDescr.StyleName.getLength() )
    	aFont.SetStyleName( rDescr.StyleName );
	if ( rDescr.Height )
    	aFont.SetSize( Size( rDescr.Width, rDescr.Height ) );
	if ( (FontFamily)rDescr.Family != FAMILY_DONTKNOW )
    	aFont.SetFamily( (FontFamily)rDescr.Family );
	if ( (CharSet)rDescr.CharSet != RTL_TEXTENCODING_DONTKNOW )
    	aFont.SetCharSet( (CharSet)rDescr.CharSet );
	if ( (FontPitch)rDescr.Pitch != PITCH_DONTKNOW )
    	aFont.SetPitch( (FontPitch)rDescr.Pitch );
	if ( rDescr.CharacterWidth )
    	aFont.SetWidthType( VCLUnoHelper::ConvertFontWidth( rDescr.CharacterWidth ) );
	if ( rDescr.Weight )
    	aFont.SetWeight( VCLUnoHelper::ConvertFontWeight( rDescr.Weight ) );
	if ( (FontItalic)rDescr.Slant != ITALIC_DONTKNOW )
    	aFont.SetItalic( (FontItalic)rDescr.Slant );
	if ( (FontUnderline)rDescr.Underline != UNDERLINE_DONTKNOW )
    	aFont.SetUnderline( (FontUnderline)rDescr.Underline );
	if ( (FontStrikeout)rDescr.Strikeout != STRIKEOUT_DONTKNOW )
    	aFont.SetStrikeout( (FontStrikeout)rDescr.Strikeout );

	// Kein DONTKNOW
    aFont.SetOrientation( (short)rDescr.Orientation );
	aFont.SetKerning( rDescr.Kerning );
    aFont.SetWordLineMode( rDescr.WordLineMode );

	return aFont;
}

Font VCLUnoHelper::CreateFont( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont >& rxFont )
{
	Font aFont;
	VCLXFont* pVCLXFont = VCLXFont::GetImplementation( rxFont );
	if ( pVCLXFont )
		aFont = pVCLXFont->GetFont();
	return aFont;
}


::com::sun::star::awt::SimpleFontMetric VCLUnoHelper::CreateFontMetric( const FontMetric& rFontMetric )
{
	::com::sun::star::awt::SimpleFontMetric aFM;
	aFM.Ascent = (sal_Int16)rFontMetric.GetAscent();
    aFM.Descent = (sal_Int16)rFontMetric.GetDescent();
    aFM.Leading = (sal_Int16)rFontMetric.GetIntLeading();
    aFM.Slant = (sal_Int16)rFontMetric.GetSlant();
    aFM.FirstChar = 0x0020;
    aFM.LastChar = 0xFFFD;
	return aFM;
}

sal_Bool VCLUnoHelper::IsZero( ::com::sun::star::awt::Rectangle rRect )
{
	return ( !rRect.X && !rRect.Y && !rRect.Width && !rRect.Height );
}

MapUnit VCLUnoHelper::UnoEmbed2VCLMapUnit( sal_Int32 nUnoEmbedMapUnit )
{
	switch( nUnoEmbedMapUnit )
	{
		case ::com::sun::star::embed::EmbedMapUnits::ONE_100TH_MM:
			return MAP_100TH_MM;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_10TH_MM:
			return MAP_10TH_MM;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_MM:
			return MAP_MM;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_CM:
			return MAP_CM;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_1000TH_INCH:
			return MAP_1000TH_INCH;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_100TH_INCH:
			return MAP_100TH_INCH;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_10TH_INCH:
			return MAP_10TH_INCH;
		case ::com::sun::star::embed::EmbedMapUnits::ONE_INCH:
			return MAP_INCH;
		case ::com::sun::star::embed::EmbedMapUnits::POINT:
			return MAP_POINT;
		case ::com::sun::star::embed::EmbedMapUnits::TWIP:
			return MAP_TWIP;
		case ::com::sun::star::embed::EmbedMapUnits::PIXEL:
			return MAP_PIXEL;
	}

	OSL_ENSURE( sal_False, "Unexpected UNO map mode is provided!\n" );
	return MAP_LASTENUMDUMMY;
}

sal_Int32 VCLUnoHelper::VCL2UnoEmbedMapUnit( MapUnit nVCLMapUnit )
{
	switch( nVCLMapUnit )
	{
		case MAP_100TH_MM:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_100TH_MM;
		case MAP_10TH_MM:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_10TH_MM;
		case MAP_MM:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_MM;
		case MAP_CM:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_CM;
		case MAP_1000TH_INCH:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_1000TH_INCH;
		case MAP_100TH_INCH:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_100TH_INCH;
		case MAP_10TH_INCH:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_10TH_INCH;
		case MAP_INCH:
			return ::com::sun::star::embed::EmbedMapUnits::ONE_INCH;
		case MAP_POINT:
			return ::com::sun::star::embed::EmbedMapUnits::POINT;
		case MAP_TWIP:
			return ::com::sun::star::embed::EmbedMapUnits::TWIP;
		case MAP_PIXEL:
			return ::com::sun::star::embed::EmbedMapUnits::PIXEL;
		default: ; // avoid compiler warning
	}

	OSL_ENSURE( sal_False, "Unexpected VCL map mode is provided!\n" );
	return -1;
}

using namespace ::com::sun::star::util;

//====================================================================
//= file-local helpers
//====================================================================
namespace
{
    enum UnitConversionDirection
    {
        FieldUnitToMeasurementUnit,
        MeasurementUnitToFieldUnit
    };

    sal_Int16 convertMeasurementUnit( sal_Int16 _nUnit, UnitConversionDirection eDirection, sal_Int16& _rFieldToUNOValueFactor )
    {
        static struct _unit_table
        {
            FieldUnit eFieldUnit;
            sal_Int16 nMeasurementUnit;
            sal_Int16 nFieldToMeasureFactor;
        } aUnits[] = {
            { FUNIT_NONE,       -1 , -1},
            { FUNIT_MM,         MeasureUnit::MM,            1 },    // must precede MM_10TH
            { FUNIT_MM,         MeasureUnit::MM_10TH,       10 },
            { FUNIT_100TH_MM,   MeasureUnit::MM_100TH,      1 },
            { FUNIT_CM,         MeasureUnit::CM,            1 },
            { FUNIT_M,          MeasureUnit::M,             1 },
            { FUNIT_KM,         MeasureUnit::KM,            1 },
            { FUNIT_TWIP,       MeasureUnit::TWIP,          1 },
            { FUNIT_POINT,      MeasureUnit::POINT,         1 },
            { FUNIT_PICA,       MeasureUnit::PICA,          1 },
            { FUNIT_INCH,       MeasureUnit::INCH,          1 },    // must precede INCH_*TH
            { FUNIT_INCH,       MeasureUnit::INCH_10TH,     10 },
            { FUNIT_INCH,       MeasureUnit::INCH_100TH,    100 },
            { FUNIT_INCH,       MeasureUnit::INCH_1000TH,   1000 },
            { FUNIT_FOOT,       MeasureUnit::FOOT,          1 },
            { FUNIT_MILE,       MeasureUnit::MILE,          1 },
        };
        for ( size_t i = 0; i < sizeof( aUnits ) / sizeof( aUnits[0] ); ++i )
        {
            if ( eDirection == FieldUnitToMeasurementUnit )
            {
                if ( ( aUnits[ i ].eFieldUnit == (FieldUnit)_nUnit ) && ( aUnits[ i ].nFieldToMeasureFactor == _rFieldToUNOValueFactor ) )
                    return aUnits[ i ].nMeasurementUnit;
            }
            else
            {
                if ( aUnits[ i ].nMeasurementUnit == _nUnit )
                {
                    _rFieldToUNOValueFactor = aUnits[ i ].nFieldToMeasureFactor;
                    return (sal_Int16)aUnits[ i ].eFieldUnit;
                }
            }
        }
        if ( eDirection == FieldUnitToMeasurementUnit )
            return -1;

        _rFieldToUNOValueFactor = 1;
        return (sal_Int16)FUNIT_NONE;
    }
}
//========================================================================
//= MeasurementUnitConversion
//========================================================================
//------------------------------------------------------------------------
sal_Int16 VCLUnoHelper::ConvertToMeasurementUnit( FieldUnit _nFieldUnit, sal_Int16 _nUNOToFieldValueFactor )
{
    return convertMeasurementUnit( (sal_Int16)_nFieldUnit, FieldUnitToMeasurementUnit, _nUNOToFieldValueFactor );
}

//------------------------------------------------------------------------
FieldUnit VCLUnoHelper::ConvertToFieldUnit( sal_Int16 _nMeasurementUnit, sal_Int16& _rFieldToUNOValueFactor )
{
    return (FieldUnit)convertMeasurementUnit( _nMeasurementUnit, MeasurementUnitToFieldUnit, _rFieldToUNOValueFactor );
}


MapUnit /* MapModeUnit */ VCLUnoHelper::ConvertToMapModeUnit(sal_Int16 /* com.sun.star.util.MeasureUnit.* */ _nMeasureUnit) throw (::com::sun::star::lang::IllegalArgumentException)
{
    MapUnit eMode;
    switch(_nMeasureUnit)
    {
    case com::sun::star::util::MeasureUnit::MM_100TH:
        eMode = MAP_100TH_MM;
        break;


    case com::sun::star::util::MeasureUnit::MM_10TH:
        eMode = MAP_10TH_MM;
        break;

    case com::sun::star::util::MeasureUnit::MM:
        eMode = MAP_MM;
        break;

    case com::sun::star::util::MeasureUnit::CM:
        eMode = MAP_CM;
        break;

    case com::sun::star::util::MeasureUnit::INCH_1000TH:
        eMode = MAP_1000TH_INCH;
        break;

    case com::sun::star::util::MeasureUnit::INCH_100TH:
        eMode = MAP_100TH_INCH;
        break;

    case com::sun::star::util::MeasureUnit::INCH_10TH:
        eMode = MAP_10TH_INCH;
        break;

    case com::sun::star::util::MeasureUnit::INCH:
        eMode = MAP_INCH;
        break;

    case com::sun::star::util::MeasureUnit::POINT:
        eMode = MAP_POINT;
        break;

    case com::sun::star::util::MeasureUnit::TWIP:
        eMode = MAP_TWIP;
        break;

    case com::sun::star::util::MeasureUnit::PIXEL:
        eMode = MAP_PIXEL;
        break;

/*
    case com::sun::star::util::MeasureUnit::M:
        break;
    case com::sun::star::util::MeasureUnit::KM:
        break;
    case com::sun::star::util::MeasureUnit::PICA:
        break;
    case com::sun::star::util::MeasureUnit::FOOT:
        break;
    case com::sun::star::util::MeasureUnit::MILE:
        break;
    case com::sun::star::util::MeasureUnit::PERCENT:
        break;
*/
    case com::sun::star::util::MeasureUnit::APPFONT:
        eMode = MAP_APPFONT;
        break;

    case com::sun::star::util::MeasureUnit::SYSFONT:
        eMode = MAP_SYSFONT;
        break;

/*
    case com::sun::star::util::MeasureUnit::RELATIVE:
        eMode = MAP_RELATIVE;
        break;
    case com::sun::star::util::MeasureUnit::REALAPPFONT:
        eMode = MAP_REALAPPFONT;
        break;
*/

    default:
        throw ::com::sun::star::lang::IllegalArgumentException(::rtl::OUString::createFromAscii("Unsupported measure unit."), NULL, 1 );
    }
    return eMode;
}

sal_Int16 /* com.sun.star.util.MeasureUnit.* */ VCLUnoHelper::ConvertToMeasurementUnit(MapUnit /* MapModeUnit */ _eMapModeUnit)  throw (::com::sun::star::lang::IllegalArgumentException)
{
    sal_Int16 nMeasureUnit = 0;
    switch (_eMapModeUnit)
    {
    case MAP_100TH_MM:
        nMeasureUnit = com::sun::star::util::MeasureUnit::MM_100TH;
        break;

    case MAP_10TH_MM:
        nMeasureUnit = com::sun::star::util::MeasureUnit::MM_10TH;
        break;

    case MAP_MM:
        nMeasureUnit = com::sun::star::util::MeasureUnit::MM;
        break;

    case MAP_CM:
        nMeasureUnit = com::sun::star::util::MeasureUnit::CM;
        break;

    case MAP_1000TH_INCH:
        nMeasureUnit = com::sun::star::util::MeasureUnit::INCH_1000TH;
        break;

    case MAP_100TH_INCH:
        nMeasureUnit = com::sun::star::util::MeasureUnit::INCH_100TH;
        break;

    case MAP_10TH_INCH:
        nMeasureUnit = com::sun::star::util::MeasureUnit::INCH_10TH;
        break;

    case MAP_INCH:
        nMeasureUnit = com::sun::star::util::MeasureUnit::INCH;
        break;

    case MAP_POINT:
        nMeasureUnit = com::sun::star::util::MeasureUnit::POINT;
        break;

    case MAP_TWIP:
        nMeasureUnit = com::sun::star::util::MeasureUnit::TWIP;
        break;

    case MAP_PIXEL:
        nMeasureUnit = com::sun::star::util::MeasureUnit::PIXEL;
        break;

    case MAP_APPFONT:
        nMeasureUnit = com::sun::star::util::MeasureUnit::APPFONT;
        break;

    case MAP_SYSFONT:
        nMeasureUnit = com::sun::star::util::MeasureUnit::SYSFONT;
        break;

/*
    case MAP_RELATIVE:
        break;

    case MAP_REALAPPFONT:
        break;
*/
    default:
        throw ::com::sun::star::lang::IllegalArgumentException(::rtl::OUString::createFromAscii("Unsupported MapMode unit."), NULL, 1 );
    }
    return nMeasureUnit;
}

::Size VCLUnoHelper::ConvertToVCLSize(com::sun::star::awt::Size const& _aSize)
{
    ::Size aVCLSize(_aSize.Width, _aSize.Height);
    return aVCLSize;
}

com::sun::star::awt::Size VCLUnoHelper::ConvertToAWTSize(::Size /* VCLSize */ const& _aSize)
{
    com::sun::star::awt::Size aAWTSize(_aSize.Width(), _aSize.Height());
    return aAWTSize;
}


::Point VCLUnoHelper::ConvertToVCLPoint(com::sun::star::awt::Point const& _aPoint)
{
    ::Point aVCLPoint(_aPoint.X, _aPoint.Y);
    return aVCLPoint;
}

com::sun::star::awt::Point VCLUnoHelper::ConvertToAWTPoint(::Point /* VCLPoint */ const& _aPoint)
{
    com::sun::star::awt::Point aAWTPoint(_aPoint.X(), _aPoint.Y());
    return aAWTPoint;
}

::Rectangle VCLUnoHelper::ConvertToVCLRect( ::com::sun::star::awt::Rectangle const & _rRect )
{
    return ::Rectangle( _rRect.X, _rRect.Y, _rRect.X + _rRect.Width - 1, _rRect.Y + _rRect.Height - 1 );
}

::com::sun::star::awt::Rectangle VCLUnoHelper::ConvertToAWTRect( ::Rectangle const & _rRect )
{
    return ::com::sun::star::awt::Rectangle( _rRect.Left(), _rRect.Top(), _rRect.GetWidth(), _rRect.GetHeight() );
}

awt::MouseEvent VCLUnoHelper::createMouseEvent( const ::MouseEvent& _rVclEvent, const uno::Reference< uno::XInterface >& _rxContext )
{
    awt::MouseEvent aMouseEvent;
    aMouseEvent.Source = _rxContext;

	aMouseEvent.Modifiers = 0;
	if ( _rVclEvent.IsShift() )
		aMouseEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::SHIFT;
	if ( _rVclEvent.IsMod1() )
	aMouseEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD1;
	if ( _rVclEvent.IsMod2() )
		aMouseEvent.Modifiers |= ::com::sun::star::awt::KeyModifier::MOD2;

	aMouseEvent.Buttons = 0;
	if ( _rVclEvent.IsLeft() )
		aMouseEvent.Buttons |= ::com::sun::star::awt::MouseButton::LEFT;
	if ( _rVclEvent.IsRight() )
		aMouseEvent.Buttons |= ::com::sun::star::awt::MouseButton::RIGHT;
	if ( _rVclEvent.IsMiddle() )
		aMouseEvent.Buttons |= ::com::sun::star::awt::MouseButton::MIDDLE;

	aMouseEvent.X = _rVclEvent.GetPosPixel().X();
	aMouseEvent.Y = _rVclEvent.GetPosPixel().Y();
	aMouseEvent.ClickCount = _rVclEvent.GetClicks();
	aMouseEvent.PopupTrigger = sal_False;

    return aMouseEvent;
}

awt::KeyEvent VCLUnoHelper::createKeyEvent( const ::KeyEvent& _rVclEvent, const uno::Reference< uno::XInterface >& _rxContext )
{
    awt::KeyEvent aKeyEvent;
    aKeyEvent.Source = _rxContext;

	aKeyEvent.Modifiers = 0;
	if ( _rVclEvent.GetKeyCode().IsShift() )
		aKeyEvent.Modifiers |= awt::KeyModifier::SHIFT;
	if ( _rVclEvent.GetKeyCode().IsMod1() )
		aKeyEvent.Modifiers |= awt::KeyModifier::MOD1;
	if ( _rVclEvent.GetKeyCode().IsMod2() )
		aKeyEvent.Modifiers |= awt::KeyModifier::MOD2;
    if ( _rVclEvent.GetKeyCode().IsMod3() )
            aKeyEvent.Modifiers |= awt::KeyModifier::MOD3;

	aKeyEvent.KeyCode = _rVclEvent.GetKeyCode().GetCode();
	aKeyEvent.KeyChar = _rVclEvent.GetCharCode();
    aKeyEvent.KeyFunc = ::sal::static_int_cast< sal_Int16 >( _rVclEvent.GetKeyCode().GetFunction());

    return aKeyEvent;
}
