/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________

#ifndef __FRAMEWORK_DISPATCH_SOUNDHANDLER_HXX_
#include "soundhandler.hxx"
#endif

#ifndef __COMPHELPER_MEDIADESCRIPTOR_HXX_
#include <comphelper/mediadescriptor.hxx>
#endif

//_________________________________________________________________________________________________________________
//	interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/frame/DispatchResultState.hpp>

//_________________________________________________________________________________________________________________
//	includes of other projects
//_________________________________________________________________________________________________________________
#include <comphelper/sequenceashashmap.hxx>
#include <rtl/ustrbuf.hxx>

#include <cppuhelper/typeprovider.hxx>
#include <cppuhelper/factory.hxx>

//_________________________________________________________________________________________________________________
//	namespace
//_________________________________________________________________________________________________________________

namespace avmedia{

//_________________________________________________________________________________________________________________
//	non exported const
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//	non exported definitions
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//	declarations
//_________________________________________________________________________________________________________________

//*****************************************************************************************************************
//  XInterface, XTypeProvider, XServiceInfo
//*****************************************************************************************************************

void SAL_CALL SoundHandler::acquire() throw()
{
       /* Don't use mutex in methods of XInterface! */
       OWeakObject::acquire();
}

void SAL_CALL SoundHandler::release() throw()
{
       /* Don't use mutex in methods of XInterface! */
       OWeakObject::release();
}

css::uno::Any SAL_CALL SoundHandler::queryInterface( const css::uno::Type& aType ) throw( css::uno::RuntimeException )
{
       /* Attention: Don't use mutex or guard in this method!!! Is a method of XInterface.     */
        /* Ask for my own supported interfaces ...*/
       css::uno::Any aReturn( ::cppu::queryInterface( aType, 
               static_cast< css::lang::XTypeProvider* >(this),
               static_cast< css::lang::XServiceInfo* >(this),
               static_cast< css::frame::XNotifyingDispatch* >(this),
               static_cast< css::frame::XDispatch* >(this),
               static_cast< css::document::XExtendedFilterDetection* >(this)));
       /* If searched interface not supported by this class ... */
       if ( aReturn.hasValue() == sal_False )
       {
               /* ... ask baseclass for interfaces! */
               aReturn = OWeakObject::queryInterface( aType );
       }
        /* Return result of this search. */
       return aReturn;
}

css::uno::Sequence< sal_Int8 > SAL_CALL SoundHandler::getImplementationId() throw( css::uno::RuntimeException )
{
    /* Create one Id for all instances of this class.                                               */
    /* Use ethernet address to do this! (sal_True)                                                  */
    /* Optimize this method                                                                         */
    /* We initialize a static variable only one time. And we don't must use a mutex at every call!  */
    /* For the first call; pID is NULL - for the second call pID is different from NULL!            */
    static ::cppu::OImplementationId* pID = NULL ;
    if ( pID == NULL )
    {
        /* Ready for multithreading; get global mutex for first call of this method only! see before   */
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        /* Control these pointer again ... it can be, that another instance will be faster then these! */
        if ( pID == NULL )
        {
            /* Create a new static ID ... */
            static ::cppu::OImplementationId aID( sal_False );
            /* ... and set his address to static pointer! */
            pID = &aID ;
        }
    }
    return pID->getImplementationId();
}

css::uno::Sequence< css::uno::Type > SAL_CALL SoundHandler::getTypes() throw( css::uno::RuntimeException )
{                                                                     
    /* Optimize this method !                                       */
    /* We initialize a static variable only one time.               */
    /* And we don't must use a mutex at every call!                 */
    /* For the first call; pTypeCollection is NULL -                */
    /* for the second call pTypeCollection is different from NULL!  */
    static ::cppu::OTypeCollection* pTypeCollection = NULL ;
    if ( pTypeCollection == NULL )
    {
        /* Ready for multithreading; get global mutex for first call of this method only! see before   */
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
        /* Control these pointer again ... it can be, that another instance will be faster then these! */
        if ( pTypeCollection == NULL )
        {
            /* Create a static typecollection ...           */
            static ::cppu::OTypeCollection aTypeCollection
                (
                    ::getCppuType(( const ::com::sun::star::uno::Reference< css::lang::XTypeProvider >*)NULL ),
                    ::getCppuType(( const ::com::sun::star::uno::Reference< css::lang::XServiceInfo >*)NULL ),
                    ::getCppuType(( const ::com::sun::star::uno::Reference< css::frame::XNotifyingDispatch >*)NULL ),
                    ::getCppuType(( const ::com::sun::star::uno::Reference< css::frame::XDispatch >*)NULL ),
                    ::getCppuType(( const ::com::sun::star::uno::Reference< css::document::XExtendedFilterDetection >*)NULL )
                );
            /* ... and set his address to static pointer! */
            pTypeCollection = &aTypeCollection ;
        }
    }
    return pTypeCollection->getTypes();
}

#define DECLARE_ASCII( SASCIIVALUE ) \
        ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SASCIIVALUE ) )

#define IMPLEMENTATIONNAME_SOUNDHANDLER DECLARE_ASCII("com.sun.star.comp.framework.SoundHandler")
#define SERVICENAME_CONTENTHANDLER DECLARE_ASCII("com.sun.star.frame.ContentHandler")

/*===========================================================================================================*/
/* XServiceInfo */
/*===========================================================================================================*/
::rtl::OUString SAL_CALL SoundHandler::getImplementationName() throw( css::uno::RuntimeException )
{
    return impl_getStaticImplementationName();
}

/*===========================================================================================================*/
/* XServiceInfo */
/*===========================================================================================================*/
sal_Bool SAL_CALL SoundHandler::supportsService( const ::rtl::OUString& sServiceName ) throw( css::uno::RuntimeException )
{
    /* Set default return value. */
    sal_Bool bReturn = sal_False ;
    /* Get names of all supported servicenames. */
    css::uno::Sequence< ::rtl::OUString >  seqServiceNames =   getSupportedServiceNames();
    const ::rtl::OUString*                 pArray          =   seqServiceNames.getConstArray();
    sal_Int32                              nCounter        =   0;                                           
    sal_Int32                              nLength         =   seqServiceNames.getLength();      
    /* Search for right name in list. */
    while   (
              ( nCounter      <       nLength         )       &&
              ( bReturn       ==      sal_False       )
            )
    {
        /* Is name was found, say "YES, SERVICE IS SUPPORTED." and break loop. */
        if ( pArray[nCounter] == sServiceName )
        {
            bReturn = sal_True ;
        }
        /* Else step to next element in list. */
        ++nCounter;
    }
    /* Return state of search. */
    return bReturn;
}

/*===========================================================================================================*/
/* XServiceInfo */
/*===========================================================================================================*/
css::uno::Sequence< ::rtl::OUString > SAL_CALL SoundHandler::getSupportedServiceNames() throw( css::uno::RuntimeException )
{
    return impl_getStaticSupportedServiceNames();
}

/*===========================================================================================================*/
/* Helper for XServiceInfo                                                                                   */
/*===========================================================================================================*/
css::uno::Sequence< ::rtl::OUString > SoundHandler::impl_getStaticSupportedServiceNames()
{
    css::uno::Sequence< ::rtl::OUString > seqServiceNames( 1 );
    seqServiceNames.getArray() [0] = SERVICENAME_CONTENTHANDLER;
    return seqServiceNames;
}

/*===========================================================================================================*/
/* Helper for XServiceInfo */
/*===========================================================================================================*/
::rtl::OUString SoundHandler::impl_getStaticImplementationName()
{
    return IMPLEMENTATIONNAME_SOUNDHANDLER;
}

css::uno::Reference< css::uno::XInterface > SAL_CALL SoundHandler::impl_createInstance( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) throw( css::uno::Exception )
{
    /* create new instance of service */
    SoundHandler* pClass = new SoundHandler( xServiceManager );
    /* hold it alive by increasing his ref count!!! */
    css::uno::Reference< css::uno::XInterface > xService( static_cast< ::cppu::OWeakObject* >(pClass), css::uno::UNO_QUERY );
    /* initialize new service instance ... he can use his own refcount ... we hold it! */
    pClass->impl_initService();
    /* return new created service as reference */
    return xService;
}

css::uno::Reference< css::lang::XSingleServiceFactory > SoundHandler::impl_createFactory( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager )
{
    css::uno::Reference< css::lang::XSingleServiceFactory > xReturn ( cppu::createSingleFactory (
       xServiceManager,
        SoundHandler::impl_getStaticImplementationName(),
        SoundHandler::impl_createInstance,
        SoundHandler::impl_getStaticSupportedServiceNames()
        )
    );
    return xReturn;
}

void SAL_CALL SoundHandler::impl_initService()
{
}


/*-************************************************************************************************************//**
    @short      standard ctor
    @descr      These initialize a new instance of this class with needed informations for work.

    @seealso    using at owner

    @param      "xFactory", reference to service manager for creation of new services
    @return     -

    @onerror    Show an assertion and do nothing else.
    @threadsafe yes
*//*-*************************************************************************************************************/
SoundHandler::SoundHandler( const css::uno::Reference< css::lang::XMultiServiceFactory >& xFactory )
		//	Init baseclasses first
        :   ThreadHelpBase      (          )
        ,   ::cppu::OWeakObject (          )
        // Init member
	,   m_bError		( false    )
        ,   m_xFactory          ( xFactory )
{
    m_aUpdateTimer.SetTimeoutHdl(LINK(this, SoundHandler, implts_PlayerNotify));
}

/*-************************************************************************************************************//**
    @short      standard dtor
    @descr      -

    @seealso    -

    @param      -
    @return     -

    @onerror    -
    @threadsafe -
*//*-*************************************************************************************************************/
SoundHandler::~SoundHandler()
{
    if (m_xListener.is())
    {
        css::frame::DispatchResultEvent aEvent;
        aEvent.State = css::frame::DispatchResultState::FAILURE;
        m_xListener->dispatchFinished(aEvent);
        m_xListener = css::uno::Reference< css::frame::XDispatchResultListener >();
    }
}

/*-************************************************************************************************************//**
    @interface  ::com::sun::star::frame::XDispatch

    @short      try to load audio file
    @descr      This method try to load given audio file by URL and play it. We use vcl/Sound class to do that.
                Playing of sound is asynchron every time.

    @attention  We must hold us alive by ourself ... because we use async. vcl sound player ... but playing is started
                in async interface call "dispatch()" too. And caller forget us imediatly. But then our uno ref count
                will decreased to 0 and will die. The only solution is to use own reference to our implementation.
                But we do it for really started jobs only and release it during call back of vcl.

    @seealso    class vcl/Sound
    @seealso    method implts_PlayerNotify()

    @param      "aURL"      , URL to dispatch.
    @param      "lArguments", list of optional arguments.
    @return     -

    @onerror    We do nothing.
    @threadsafe yes
*//*-*************************************************************************************************************/
void SAL_CALL SoundHandler::dispatchWithNotification(const css::util::URL&                                             aURL      ,
                                                     const css::uno::Sequence< css::beans::PropertyValue >&            lDescriptor,
                                                     const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) throw(css::uno::RuntimeException)
{
    // SAFE {
    const ::vos::OGuard aLock( m_aLock );

    { 
	//close streams otherwise on windows we can't reopen the file in the
	//media player when we pass the url to directx as it'll already be open
        ::comphelper::MediaDescriptor aDescriptor(lDescriptor);

	css::uno::Reference< css::io::XInputStream > xInputStream =
		aDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_INPUTSTREAM(),
		css::uno::Reference< css::io::XInputStream >());
	if (xInputStream.is()) xInputStream->closeInput();
    }

    // If player currently used for other dispatch() requests ...
    // cancel it by calling stop()!
    m_aUpdateTimer.Stop();
    if (m_xPlayer.is())
    {
        if (m_xPlayer->isPlaying())
            m_xPlayer->stop();
        m_xPlayer.clear();
    }

    // Try to initialize player.
    m_xListener = xListener;
    try
    {
        m_bError = false;
        m_xPlayer.set( avmedia::MediaWindow::createPlayer( aURL.Complete ), css::uno::UNO_QUERY_THROW );
        // OK- we can start async playing ...
        // Count this request and initialize self-holder against dieing by uno ref count ...
        m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);
        m_xPlayer->start();
        m_aUpdateTimer.SetTimeout( 200 );
        m_aUpdateTimer.Start();
    }
    catch( css::uno::Exception& e )
    {
        m_bError = true;
        (void)e;
        m_xPlayer.clear();
    }

    // } SAFE
}

void SAL_CALL SoundHandler::dispatch( const css::util::URL&                                  aURL       ,
                                      const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
{
    dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
}

/*-************************************************************************************************************//**
    @interface  ::com::sun::star::document::XExtendedFilterDetection

    @short      try to detect file (given as argument included in "lDescriptor")
    @descr      We try to detect, if given file could be handled by this class and is a well known one.
                If it is - we return right internal type name - otherwise we return nothing!
                So call can search for another detect service and ask him too.

    @attention  a) We don't need any mutex here ... because we don't use any member!
                b) Dont' use internal player instance "m_pPlayer" to detect given sound file!
                   It's not necessary to do that ... and we can use temp. variable to do the same.
                   This way is easy - we don't must synchronize it with currently played sounds!
                   Another reason to do so ... We are a listener on our internal ma_Player object.
                   If you would call "IsSoundFile()" on this instance, he would call us back and
                   we make some uneccssary things ...

    @seealso    -

    @param      "lDescriptor", description of file to detect
    @return     Internal type name which match this file ... or nothing if it is unknown.

    @onerror    We return nothing.
    @threadsafe yes
*//*-*************************************************************************************************************/
::rtl::OUString SAL_CALL SoundHandler::detect( css::uno::Sequence< css::beans::PropertyValue >& lDescriptor ) throw( css::uno::RuntimeException )
{
    // Our default is "nothing". So we can return it, if detection failed or fily type is really unknown.
    ::rtl::OUString sTypeName;

    // Analyze given descriptor to find filename or input stream or ...
    ::comphelper::MediaDescriptor aDescriptor(lDescriptor);
    ::rtl::OUString               sURL       = aDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_URL(), ::rtl::OUString());

    if (
        !sURL.isEmpty() &&
        (avmedia::MediaWindow::isMediaURL(sURL))
       )
    {
        // If the file type is supported depends on the OS, so...
        // I think we can the following ones:
        //  a) look for given extension of url to map our type decision HARD CODED!!!
        //  b) return preferred type every time... it's easy :-)
        sTypeName = ::rtl::OUString::createFromAscii("wav_Wave_Audio_File");
        aDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sTypeName;
        aDescriptor >> lDescriptor;
    }

    // Return our decision.
    return sTypeName;
}

/*-************************************************************************************************************//**
    @short      call back of sound player
    @descr      Our player call us back to give us some informations.
                We use this informations to callback our might existing listener.

    @seealso    method dispatchWithNotification()

    @param      -
    @return     0 every time ... it doesn't matter for us.

    @onerror    -
    @threadsafe yes
*//*-*************************************************************************************************************/
IMPL_LINK( SoundHandler, implts_PlayerNotify, void*, EMPTYARG )
{
    // SAFE {
    ::vos::OClearableGuard aLock( m_aLock );

    if (m_xPlayer.is() && m_xPlayer->isPlaying() && m_xPlayer->getMediaTime() < m_xPlayer->getDuration())
    {
        m_aUpdateTimer.Start();
        return 0L;
    }
    m_xPlayer.clear();

    // We use m_xSelfHold to let us die ... but we must live till real finishing of this method too!!!
    // So we SHOULD use another "self-holder" temp. to provide that ...
    css::uno::Reference< css::uno::XInterface > xOperationHold = m_xSelfHold;
    m_xSelfHold = css::uno::Reference< css::uno::XInterface >();

    // notify might existing listener
    // And forget this listener!
    // Because the corresponding dispatch was finished.
    if (m_xListener.is())
    {
        css::frame::DispatchResultEvent aEvent;
        if (!m_bError)
            aEvent.State = css::frame::DispatchResultState::SUCCESS;
        else
            aEvent.State = css::frame::DispatchResultState::FAILURE;
        m_xListener->dispatchFinished(aEvent);
        m_xListener = css::uno::Reference< css::frame::XDispatchResultListener >();
    }

    // } SAFE
	//release aLock before end of method at which point xOperationHold goes out of scope and pThis dies
	aLock.clear();
    return 0;
}

} // namespace framework

// ------------------------------------------
// - component_getImplementationEnvironment -
// ------------------------------------------

extern "C" void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
       *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

// ------------------------
// - component_getFactory -
// ------------------------

extern "C" void* SAL_CALL component_getFactory(const sal_Char* pImplementationName, void* pServiceManager, void* /*pRegistryKey*/ )
{
    void* pReturn = NULL;
    if  (pServiceManager !=  NULL )
    {
        /* Define variables which are used in following macros. */
        css::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > xFactory;
        css::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager;
            xServiceManager = reinterpret_cast< ::com::sun::star::lang::XMultiServiceFactory* >( pServiceManager )  ;

        if ( avmedia::SoundHandler::impl_getStaticImplementationName().equals( ::rtl::OUString::createFromAscii( pImplementationName ) ) )
            xFactory = avmedia::SoundHandler::impl_createFactory( xServiceManager );

        if ( xFactory.is() == sal_True )
        {
            xFactory->acquire();
            pReturn = xFactory.get();
        }
    }
    /* Return with result of this operation. */
    return pReturn;
}
