/**************************************************************
 *
 * 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 <com/sun/star/awt/DeviceCapability.hpp>

#include <com/sun/star/util/MeasureUnit.hpp>

#include <toolkit/awt/vclxdevice.hxx>
#include <toolkit/awt/vclxfont.hxx>
#include <toolkit/awt/vclxbitmap.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/macros.hxx>
#include <cppuhelper/typeprovider.hxx>

#include <rtl/memory.h>
#include <rtl/uuid.h>

#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <vcl/window.hxx>
#include <vcl/print.hxx>
#include <vcl/virdev.hxx>
#include <vcl/bitmapex.hxx>
#include <vcl/font.hxx>

//	----------------------------------------------------
//	class VCLXDevice
//	----------------------------------------------------
VCLXDevice::VCLXDevice() : mrMutex( Application::GetSolarMutex() )
{
	mpOutputDevice = NULL;
	nFlags = 0;
}

VCLXDevice::~VCLXDevice()
{
// Was thought for #88347#, but didn't help, because the interface will not be released
// But would be a good idea anyway, check after 6.0, it's a little bit dangerous now
//    if( mpOutputDevice && IsCreatedWithToolkit() )
//    {
//        delete mpOutputDevice;
//    }
}

void VCLXDevice::DestroyOutputDevice()
{
    delete mpOutputDevice;
	mpOutputDevice = NULL;
}

void VCLXDevice::SetCreatedWithToolkit( sal_Bool bCreatedWithToolkit )
{
    if ( bCreatedWithToolkit )
        nFlags |= FLAGS_CREATEDWITHTOOLKIT;
    else
        nFlags &= ~FLAGS_CREATEDWITHTOOLKIT;
}

sal_Bool VCLXDevice::IsCreatedWithToolkit() const
{
    return ( nFlags & FLAGS_CREATEDWITHTOOLKIT ) != 0;
}

// ::com::sun::star::uno::XInterface
::com::sun::star::uno::Any VCLXDevice::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::XDevice*, this ),
										SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ),
										SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ),
										SAL_STATIC_CAST( ::com::sun::star::awt::XUnitConversion*, this ) );
	return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
}

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

// ::com::sun::star::lang::XTypeProvider
IMPL_XTYPEPROVIDER_START( VCLXDevice )
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice>* ) NULL ),
	getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XUnitConversion>* ) NULL )
IMPL_XTYPEPROVIDER_END


// ::com::sun::star::awt::XDevice,
::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > VCLXDevice::createGraphics(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > xRef;

	if ( mpOutputDevice )
		xRef = mpOutputDevice->CreateUnoGraphics();

	return xRef;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXDevice::createDevice( sal_Int32 nWidth, sal_Int32 nHeight ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice >  xRef;
	if ( GetOutputDevice() )
	{
		VCLXVirtualDevice* pVDev = new VCLXVirtualDevice;
		VirtualDevice* pVclVDev = new VirtualDevice( *GetOutputDevice() );
		pVclVDev->SetOutputSizePixel( Size( nWidth, nHeight ) );
		pVDev->SetVirtualDevice( pVclVDev );
		xRef = pVDev;
	}
	return xRef;
}

::com::sun::star::awt::DeviceInfo VCLXDevice::getInfo() throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::awt::DeviceInfo aInfo;

	if( mpOutputDevice )
	{
		Size aDevSz;
		OutDevType eDevType = mpOutputDevice->GetOutDevType();
		if ( eDevType == OUTDEV_WINDOW )
		{
			aDevSz = ((Window*)mpOutputDevice)->GetSizePixel();
			((Window*)mpOutputDevice)->GetBorder( aInfo.LeftInset, aInfo.TopInset, aInfo.RightInset, aInfo.BottomInset );
		}
		else if ( eDevType == OUTDEV_PRINTER )
		{
			aDevSz = ((Printer*)mpOutputDevice)->GetPaperSizePixel();
			Size aOutSz = mpOutputDevice->GetOutputSizePixel();
			Point aOffset = ((Printer*)mpOutputDevice)->GetPageOffset();
			aInfo.LeftInset = aOffset.X();
			aInfo.TopInset = aOffset.Y();
			aInfo.RightInset = aDevSz.Width() - aOutSz.Width() - aOffset.X();
			aInfo.BottomInset = aDevSz.Height() - aOutSz.Height() - aOffset.Y();
		}
		else // VirtualDevice
		{
			aDevSz = mpOutputDevice->GetOutputSizePixel();
			aInfo.LeftInset = 0;
			aInfo.TopInset = 0;
			aInfo.RightInset = 0;
			aInfo.BottomInset = 0;
		}

		aInfo.Width = aDevSz.Width();
		aInfo.Height = aDevSz.Height();

		Size aTmpSz = mpOutputDevice->LogicToPixel( Size( 1000, 1000 ), MapMode( MAP_CM ) );
		aInfo.PixelPerMeterX = aTmpSz.Width()/10;
		aInfo.PixelPerMeterY = aTmpSz.Height()/10;

		aInfo.BitsPerPixel = mpOutputDevice->GetBitCount();

		aInfo.Capabilities = 0;
		if ( mpOutputDevice->GetOutDevType() != OUTDEV_PRINTER )
			aInfo.Capabilities = ::com::sun::star::awt::DeviceCapability::RASTEROPERATIONS|::com::sun::star::awt::DeviceCapability::GETBITS;
	}

	return aInfo;
}

::com::sun::star::uno::Sequence< ::com::sun::star::awt::FontDescriptor > VCLXDevice::getFontDescriptors(  ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Sequence< ::com::sun::star::awt::FontDescriptor> aFonts;
	if( mpOutputDevice )
	{
		int nFonts = mpOutputDevice->GetDevFontCount();
		if ( nFonts )
		{
			aFonts = ::com::sun::star::uno::Sequence< ::com::sun::star::awt::FontDescriptor>( nFonts );
			::com::sun::star::awt::FontDescriptor* pFonts = aFonts.getArray();
			for ( int n = 0; n < nFonts; n++ )
				pFonts[n] = VCLUnoHelper::CreateFontDescriptor( mpOutputDevice->GetDevFont( n ) );
		}
	}
	return aFonts;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont > VCLXDevice::getFont( const ::com::sun::star::awt::FontDescriptor& rDescriptor ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont >  xRef;
	if( mpOutputDevice )
	{
		VCLXFont* pMetric = new VCLXFont;
		pMetric->Init( *this, VCLUnoHelper::CreateFont( rDescriptor, mpOutputDevice->GetFont() ) );
		xRef = pMetric;
	}
	return xRef;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > VCLXDevice::createBitmap( sal_Int32 nX, sal_Int32 nY, sal_Int32 nWidth, sal_Int32 nHeight ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >  xBmp;
	if( mpOutputDevice )
	{
		Bitmap aBmp = mpOutputDevice->GetBitmap( Point( nX, nY ), Size( nWidth, nHeight ) );

		VCLXBitmap* pBmp = new VCLXBitmap;
		pBmp->SetBitmap( BitmapEx( aBmp ) );
		xBmp = pBmp;
	}
	return xBmp;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XDisplayBitmap > VCLXDevice::createDisplayBitmap( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap >& rxBitmap ) throw(::com::sun::star::uno::RuntimeException)
{
	::vos::OGuard aGuard( GetMutex() );

	BitmapEx aBmp = VCLUnoHelper::GetBitmap( rxBitmap );
	VCLXBitmap* pBmp = new VCLXBitmap;
	pBmp->SetBitmap( aBmp );
	::com::sun::star::uno::Reference< ::com::sun::star::awt::XDisplayBitmap >  xDBmp = pBmp;
	return xDBmp;
}


VCLXVirtualDevice::~VCLXVirtualDevice()
{
	::vos::OGuard aGuard( GetMutex() );

    DestroyOutputDevice();
}


// -----------------------------------------------------------------------------
// ::com::sun::star::awt::XTextConstraints
// -----------------------------------------------------------------------------
// ::sal_Int32 SAL_CALL VCLXDevice::getTextWidth( const ::rtl::OUString& Text ) throw (::com::sun::star::uno::RuntimeException)
// {
// 	::vos::OGuard aGuard( GetMutex() );
//     if (Text.getLength() == 0)
//     {
//         return 0;
//     }
//
//     return 1;
// }
//
// ::sal_Int32 SAL_CALL VCLXDevice::getTextHeight(  ) throw (::com::sun::star::uno::RuntimeException)
// {
// 	::vos::OGuard aGuard( GetMutex() );
//     return 1;
// }


// -----------------------------------------------------------------------------
// Interface implementation of ::com::sun::star::awt::XUnitConversion
// -----------------------------------------------------------------------------

::com::sun::star::awt::Point SAL_CALL VCLXDevice::convertPointToLogic( const ::com::sun::star::awt::Point& aPoint, ::sal_Int16 TargetUnit ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    (void)aPoint;
	::vos::OGuard aGuard( GetMutex() );
    if (TargetUnit == com::sun::star::util::MeasureUnit::PERCENT )
    {
        // percentage not allowed here
        throw ::com::sun::star::lang::IllegalArgumentException();
    }

    ::com::sun::star::awt::Point aAWTPoint(0,0);
    // X,Y

	if( mpOutputDevice )
	{
        MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(TargetUnit));
		::Point aVCLPoint = VCLUnoHelper::ConvertToVCLPoint(aPoint);
		::Point aDevPoint = mpOutputDevice->PixelToLogic(aVCLPoint, aMode );
        aAWTPoint = VCLUnoHelper::ConvertToAWTPoint(aDevPoint);
    }

    return aAWTPoint;
}


::com::sun::star::awt::Point SAL_CALL VCLXDevice::convertPointToPixel( const ::com::sun::star::awt::Point& aPoint, ::sal_Int16 SourceUnit ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    (void)aPoint;
	::vos::OGuard aGuard( GetMutex() );
    if (SourceUnit == com::sun::star::util::MeasureUnit::PERCENT ||
        SourceUnit == com::sun::star::util::MeasureUnit::PIXEL )
    {
        // pixel or percentage not allowed here
        throw ::com::sun::star::lang::IllegalArgumentException();
    }

    ::com::sun::star::awt::Point aAWTPoint(0,0);

	if( mpOutputDevice )
	{
        MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(SourceUnit));
		::Point aVCLPoint = VCLUnoHelper::ConvertToVCLPoint(aPoint);
		::Point aDevPoint = mpOutputDevice->LogicToPixel(aVCLPoint, aMode );
        aAWTPoint = VCLUnoHelper::ConvertToAWTPoint(aDevPoint);
    }

    return aAWTPoint;
}

::com::sun::star::awt::Size SAL_CALL VCLXDevice::convertSizeToLogic( const ::com::sun::star::awt::Size& aSize, ::sal_Int16 TargetUnit ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    (void)aSize;
	::vos::OGuard aGuard( GetMutex() );
    if (TargetUnit == com::sun::star::util::MeasureUnit::PERCENT)
    {
        // percentage not allowed here
        throw ::com::sun::star::lang::IllegalArgumentException();
    }

    ::com::sun::star::awt::Size aAWTSize(0,0);
    // Width, Height


	if( mpOutputDevice )
	{
        MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(TargetUnit));
		::Size aVCLSize = VCLUnoHelper::ConvertToVCLSize(aSize);
		::Size aDevSz = mpOutputDevice->PixelToLogic(aVCLSize, aMode );
        aAWTSize = VCLUnoHelper::ConvertToAWTSize(aDevSz);
    }

    return aAWTSize;
}

::com::sun::star::awt::Size SAL_CALL VCLXDevice::convertSizeToPixel( const ::com::sun::star::awt::Size& aSize, ::sal_Int16 SourceUnit ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    (void)aSize;
	::vos::OGuard aGuard( GetMutex() );
    if (SourceUnit == com::sun::star::util::MeasureUnit::PERCENT ||
        SourceUnit == com::sun::star::util::MeasureUnit::PIXEL)
    {
        // pixel or percentage not allowed here
        throw ::com::sun::star::lang::IllegalArgumentException();
    }

    ::com::sun::star::awt::Size aAWTSize(0,0);
    // Width, Height
	if( mpOutputDevice )
	{
        MapMode aMode(VCLUnoHelper::ConvertToMapModeUnit(SourceUnit));
		::Size aVCLSize = VCLUnoHelper::ConvertToVCLSize(aSize);
		::Size aDevSz = mpOutputDevice->LogicToPixel(aVCLSize, aMode );
        aAWTSize = VCLUnoHelper::ConvertToAWTSize(aDevSz);
    }

    return aAWTSize;
}
