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

// must be first
#include <canvas/debug.hxx>
#include <tools/diagnose_ex.h>
#include <canvas/verbosetrace.hxx>

#include <math.h>

#include <comphelper/anytostring.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <vcl/window.hxx>
#include <vcl/syschild.hxx>
#include <vcl/salbtype.hxx>

#include <basegfx/tools/canvastools.hxx>
#include <basegfx/numeric/ftools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/range/b2irange.hxx>
#include <canvas/canvastools.hxx>
#include <cppcanvas/vclfactory.hxx>
#include <cppcanvas/basegfxfactory.hxx>
#include <cppcanvas/basegfxfactory.hxx>
#include <avmedia/mediawindow.hxx>

#include <com/sun/star/media/XManager.hpp>
#include <com/sun/star/media/XPlayer.hpp>
#include <com/sun/star/media/XPlayerWindow.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/NoSupportException.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/rendering/XCanvas.hpp>
#include <com/sun/star/lang/XComponent.hdl>

#include "viewmediashape.hxx"
#include "mediashape.hxx"
#include "tools.hxx"
#include "unoview.hxx"

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

namespace slideshow
{
    namespace internal
    {
        ViewMediaShape::ViewMediaShape( const ViewLayerSharedPtr&                       rViewLayer,
										const uno::Reference< drawing::XShape >&        rxShape,
                                        const uno::Reference< uno::XComponentContext >& rxContext ) :
			mpViewLayer( rViewLayer ),
			mpMediaWindow(),
			maWindowOffset( 0, 0 ),
            maBounds(),
			mxShape( rxShape ),
			mxPlayer(),
			mxPlayerWindow(),
            mxComponentContext( rxContext ),
            mbIsSoundEnabled(true)
        {
            ENSURE_OR_THROW( mxShape.is(), "ViewMediaShape::ViewMediaShape(): Invalid Shape" );
            ENSURE_OR_THROW( mpViewLayer, "ViewMediaShape::ViewMediaShape(): Invalid View" );
            ENSURE_OR_THROW( mpViewLayer->getCanvas(), "ViewMediaShape::ViewMediaShape(): Invalid ViewLayer canvas" );
            ENSURE_OR_THROW( mxComponentContext.is(), "ViewMediaShape::ViewMediaShape(): Invalid component context" );

            UnoViewSharedPtr pUnoView (::boost::dynamic_pointer_cast<UnoView>(rViewLayer));
            if (pUnoView)
            {
                mbIsSoundEnabled = pUnoView->isSoundEnabled();
            }
        }

		// ---------------------------------------------------------------------
				
		ViewMediaShape::~ViewMediaShape()
		{		
            try
            {
                endMedia();
            }
            catch (uno::Exception &) 
            {
                OSL_ENSURE( false, rtl::OUStringToOString(
                                comphelper::anyToString(
                                    cppu::getCaughtException() ),
                                RTL_TEXTENCODING_UTF8 ).getStr() );
            }
		}

		// ---------------------------------------------------------------------

        ViewLayerSharedPtr ViewMediaShape::getViewLayer() const
        {
            return mpViewLayer;
        }

		// ---------------------------------------------------------------------
		
        bool ViewMediaShape::startMedia()
        {
            if( !mxPlayer.is() )
			    implInitialize( maBounds );

            if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
				mxPlayer->start();
			
			return true;
        }

		// ---------------------------------------------------------------------
		
        void ViewMediaShape::endMedia()
        {
			// shutdown player window
			if( mxPlayerWindow.is() )
			{
				uno::Reference< lang::XComponent > xComponent( mxPlayerWindow, uno::UNO_QUERY );
		
				if( xComponent.is() )
					xComponent->dispose();
			
				mxPlayerWindow.clear();
			}

            mpMediaWindow = ::std::auto_ptr< SystemChildWindow >();
            			
			// shutdown player
			if( mxPlayer.is() )
			{
				mxPlayer->stop();

				uno::Reference< lang::XComponent > xComponent( mxPlayer, uno::UNO_QUERY );
		
				if( xComponent.is() )
					xComponent->dispose();
			
				mxPlayer.clear();
			}
		}

		// ---------------------------------------------------------------------
		
        void ViewMediaShape::pauseMedia()
        {
            if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
				mxPlayer->stop();
		}

		// ---------------------------------------------------------------------

        void ViewMediaShape::setMediaTime(double fTime)
        {
            if( mxPlayer.is() && ( mxPlayer->getDuration() > 0.0 ) )
				mxPlayer->setMediaTime(fTime);
        }

		// ---------------------------------------------------------------------
		
        bool ViewMediaShape::render( const ::basegfx::B2DRectangle&	rBounds ) const
        {
            ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();;

            if( !pCanvas )
                return false;

			if( !mpMediaWindow.get() && !mxPlayerWindow.is() )
			{
                // fill the shape background with black
                fillRect( pCanvas,
                          rBounds,
                          0x000000FFU );
			}

            return true;
        }

        bool ViewMediaShape::resize( const ::basegfx::B2DRectangle&	rNewBounds ) const
        {
            maBounds = rNewBounds;

            ::cppcanvas::CanvasSharedPtr pCanvas = mpViewLayer->getCanvas();;

            if( !pCanvas )
                return false;

			if( !mxPlayerWindow.is() )
                return true;

            uno::Reference< beans::XPropertySet > xPropSet( pCanvas->getUNOCanvas()->getDevice(),
                                                            uno::UNO_QUERY );
            
            uno::Reference< awt::XWindow > xParentWindow;
            if( xPropSet.is() &&
                getPropertyValue( xParentWindow,
                                  xPropSet,
                                  ::rtl::OUString::createFromAscii( "Window" )) )
            {
                const awt::Rectangle aRect( xParentWindow->getPosSize() );
                
                maWindowOffset.X = aRect.X;
                maWindowOffset.Y = aRect.Y;
            }

            ::basegfx::B2DRange aTmpRange;
            ::canvas::tools::calcTransformedRectBounds( aTmpRange, 
                                                        rNewBounds, 
                                                        mpViewLayer->getTransformation() );
            const ::basegfx::B2IRange& rRangePix(
                ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
				
            mxPlayerWindow->setEnable( !rRangePix.isEmpty() );
    														
            if( rRangePix.isEmpty() )
                return true;				    
					
            const Point aPosPixel( rRangePix.getMinX() + maWindowOffset.X,
                                   rRangePix.getMinY() + maWindowOffset.Y );
            const Size	aSizePixel( rRangePix.getMaxX() - rRangePix.getMinX(),
                                    rRangePix.getMaxY() - rRangePix.getMinY() );
            
            if( mpMediaWindow.get() )
            {
                mpMediaWindow->SetPosSizePixel( aPosPixel, aSizePixel );
                mxPlayerWindow->setPosSize( 0, 0, 
                                            aSizePixel.Width(), aSizePixel.Height(), 
                                            0 );
            }
            else
            {
                mxPlayerWindow->setPosSize( aPosPixel.X(), aPosPixel.Y(), 
                                            aSizePixel.Width(), aSizePixel.Height(), 
                                            0 );
            }

			return true;
        }
		
		// ---------------------------------------------------------------------
				
		bool ViewMediaShape::implInitialize( const ::basegfx::B2DRectangle& rBounds )
		{
			if( !mxPlayer.is() && mxShape.is() )
			{
				ENSURE_OR_RETURN_FALSE( mpViewLayer->getCanvas(), 
                                   "ViewMediaShape::update(): Invalid layer canvas" );

				uno::Reference< rendering::XCanvas > xCanvas( mpViewLayer->getCanvas()->getUNOCanvas() );

				if( xCanvas.is() )
				{
					uno::Reference< beans::XPropertySet >	xPropSet;
					::rtl::OUString 						aURL;
					
					try
					{
						xPropSet.set( mxShape, uno::UNO_QUERY );

						// create Player
						if( xPropSet.is() && 
							( xPropSet->getPropertyValue( 
                                  ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaURL" ) ) ) >>=aURL ) )
						{
							implInitializeMediaPlayer( aURL );
						}
						
						// create visible object
						uno::Sequence< uno::Any > aDeviceParams;
						
						if( ::canvas::tools::getDeviceInfo( xCanvas, aDeviceParams ).getLength() > 1 )
						{
							::rtl::OUString aImplName;
							
							aDeviceParams[ 0 ] >>= aImplName;
						
							if( aImplName.endsWithIgnoreAsciiCaseAsciiL( 
                                    RTL_CONSTASCII_STRINGPARAM("VCL") ))
                            {
								implInitializeVCLBasedPlayerWindow( rBounds, aDeviceParams );
                            }
							else if( aImplName.endsWithIgnoreAsciiCaseAsciiL( 
                                         RTL_CONSTASCII_STRINGPARAM("DX")) ||
									 aImplName.endsWithIgnoreAsciiCaseAsciiL( 
                                         RTL_CONSTASCII_STRINGPARAM("DX9")))
                            {
								implInitializeDXBasedPlayerWindow( rBounds, aDeviceParams );
                            }
						}
						
						// set player properties
						implSetMediaProperties( xPropSet );
					}
                    catch( uno::RuntimeException& )
                    {
                        throw;
                    }
					catch( uno::Exception& )
					{
                        OSL_ENSURE( false,
                                    rtl::OUStringToOString(
                                        comphelper::anyToString( cppu::getCaughtException() ),
                                        RTL_TEXTENCODING_UTF8 ).getStr() ); 
					}
				}
			}
			
			return mxPlayer.is() || mxPlayerWindow.is();
	    }

		// ---------------------------------------------------------------------
		
		void ViewMediaShape::implSetMediaProperties( const uno::Reference< beans::XPropertySet >& rxProps )
		{
			if( mxPlayer.is() )
			{
				mxPlayer->setMediaTime( 0.0 );
			
                if( rxProps.is() )
                {
					sal_Bool bLoop( false );
					getPropertyValue( bLoop,
                                      rxProps,
                                      ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Loop" )));
					mxPlayer->setPlaybackLoop( bLoop );

					sal_Bool bMute( false );
					getPropertyValue( bMute,
                                      rxProps,
                                      ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Mute" )));
					mxPlayer->setMute( bMute || !mbIsSoundEnabled);

					sal_Int16 nVolumeDB(0);
					getPropertyValue( nVolumeDB,
                                      rxProps,
                                      ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VolumeDB" )));
					mxPlayer->setVolumeDB( nVolumeDB );
				
                    if( mxPlayerWindow.is() )
                    {
						media::ZoomLevel eZoom(media::ZoomLevel_FIT_TO_WINDOW);
						getPropertyValue( eZoom,
                                          rxProps,
                                          ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Zoom" )));
						mxPlayerWindow->setZoomLevel( eZoom );
					}
				}
			}
		}
		
		// ---------------------------------------------------------------------
				
		void ViewMediaShape::implInitializeMediaPlayer( const ::rtl::OUString& rMediaURL )
		{
			if( !mxPlayer.is() )
			{
				try
				{
					if( rMediaURL.getLength() )
					{
						mxPlayer.set( avmedia::MediaWindow::createPlayer( rMediaURL ), 
                            uno::UNO_QUERY );
					}
				}
                catch( uno::RuntimeException& )
                {
                    throw;
                }
				catch( const uno::Exception& )
				{
                    throw lang::NoSupportException(
                        rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
                                           "No video support for ") ) + rMediaURL,
                        uno::Reference<uno::XInterface>() );
				}
			}
		}

		// ---------------------------------------------------------------------
					
		bool ViewMediaShape::implInitializeVCLBasedPlayerWindow( const ::basegfx::B2DRectangle&   rBounds,
																 const uno::Sequence< uno::Any >& rVCLDeviceParams)
		{
			if( !mpMediaWindow.get() && !rBounds.isEmpty() )
			{
				try
				{
					sal_Int64 aVal=0;
					
					rVCLDeviceParams[ 1 ] >>= aVal;
					
					Window* pWindow = reinterpret_cast< Window* >( aVal );
					
					if( pWindow )
					{
						::basegfx::B2DRange aTmpRange;
						::canvas::tools::calcTransformedRectBounds( aTmpRange, 
                                                                    rBounds, 
																	mpViewLayer->getTransformation() );
                        const ::basegfx::B2IRange& rRangePix(
                            ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
																	
						if( !rRangePix.isEmpty() )
						{
							uno::Sequence< uno::Any > 	aArgs( 3 );
							awt::Rectangle				aAWTRect( rRangePix.getMinX(),
																  rRangePix.getMinY(),
														  		  rRangePix.getMaxX() - rRangePix.getMinX(),
														  		  rRangePix.getMaxY() - rRangePix.getMinY() );

							mpMediaWindow = ::std::auto_ptr< SystemChildWindow >( new
                                                SystemChildWindow( pWindow, WB_CLIPCHILDREN ) );
							mpMediaWindow->SetBackground( Color( COL_BLACK ) );
							mpMediaWindow->SetPosSizePixel( Point( aAWTRect.X, aAWTRect.Y ),
                                                           Size( aAWTRect.Width, aAWTRect.Height ) );
							mpMediaWindow->Show();
							
							if( mxPlayer.is() )
							{
								aArgs[ 0 ] = uno::makeAny( 
                                    sal::static_int_cast< sal_IntPtr >( mpMediaWindow->GetParentWindowHandle() ) );
								
								aAWTRect.X = aAWTRect.Y = 0;
								aArgs[ 1 ] = uno::makeAny( aAWTRect );

                                aArgs[ 2 ] = uno::makeAny( reinterpret_cast< sal_IntPtr >( mpMediaWindow.get() ) );
								
								mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) );
								
								if( mxPlayerWindow.is() )
								{
									mxPlayerWindow->setVisible( true );
									mxPlayerWindow->setEnable( true );
								}
							}
						}
					}
				}
                catch( uno::RuntimeException& )
                {
                    throw;
                }
				catch( uno::Exception& )
				{
                    OSL_ENSURE( false,
                                rtl::OUStringToOString(
                                    comphelper::anyToString( cppu::getCaughtException() ),
                                    RTL_TEXTENCODING_UTF8 ).getStr() ); 
				}
			}
			
			return mxPlayerWindow.is();
		}
		
		// ---------------------------------------------------------------------
	
		bool ViewMediaShape::implInitializeDXBasedPlayerWindow( const ::basegfx::B2DRectangle&   rBounds,
																const uno::Sequence< uno::Any >& rDXDeviceParams )
		{
            if( !mxPlayerWindow.is() )
	    	{
        		try
		        {
				    if( rDXDeviceParams.getLength() == 2 )
				    {
					    sal_Int64 aWNDVal=0;
    					
					    rDXDeviceParams[ 1 ] >>= aWNDVal;
   					
					    if( aWNDVal )
					    {
						    ::basegfx::B2DRange aTmpRange;
						    ::canvas::tools::calcTransformedRectBounds( aTmpRange, 
                                                                        rBounds, 
																	    mpViewLayer->getTransformation() );
                            const ::basegfx::B2IRange& rRangePix(
                                ::basegfx::unotools::b2ISurroundingRangeFromB2DRange( aTmpRange ));
    																	
						    if( !rRangePix.isEmpty() )
						    {
							    uno::Sequence< uno::Any > 	aArgs( 2 );
							    awt::Rectangle				aAWTRect( rRangePix.getMinX() + maWindowOffset.X,
                                                                      rRangePix.getMinY() + maWindowOffset.Y,
                                                                      rRangePix.getMaxX() - rRangePix.getMinX(),
                                                                      rRangePix.getMaxY() - rRangePix.getMinY() );

							    if( mxPlayer.is() )
							    {
								    aArgs[ 0 ] = uno::makeAny( sal::static_int_cast< sal_Int32 >( aWNDVal) );
								    aArgs[ 1 ] = uno::makeAny( aAWTRect );

								    mxPlayerWindow.set( mxPlayer->createPlayerWindow( aArgs ) );
							    }
						    }
					    }
				    }
    			}
                catch( uno::RuntimeException& )
                {
                    throw;
                }
	    	    catch( uno::Exception& )
		        {
                    OSL_ENSURE( false,
                                rtl::OUStringToOString(
                                    comphelper::anyToString( cppu::getCaughtException() ),
                                    RTL_TEXTENCODING_UTF8 ).getStr() ); 
		        }
		    }
			
			return mxPlayerWindow.is();
		}
	}
}
