/**************************************************************
 *
 * 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>
#include <cppuhelper/implementationentry.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!!! It's 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 than 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 than 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       )
            )
    {
        /* If 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::uno::XComponentContext >& xContext ) throw( css::uno::Exception )
{
    /* create new instance of service */
    SoundHandler* pClass = new SoundHandler( xContext );
    /* 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;
}

static struct ::cppu::ImplementationEntry g_component_entries[] =
{
    {
        SoundHandler::impl_createInstance,
        SoundHandler::impl_getStaticImplementationName,
        SoundHandler::impl_getStaticSupportedServiceNames,
        ::cppu::createSingleComponentFactory,
        0,
        0
    },
    { 0, 0, 0, 0, 0, 0 }
};

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      "xContext", reference to component context for creation of new services
    @return     -

    @onerror    Show an assertion and do nothing else.
    @threadsafe yes
*//*-*************************************************************************************************************/
SoundHandler::SoundHandler( const css::uno::Reference< css::uno::XComponentContext >& xContext )
		//	Init baseclasses first
        :   ThreadHelpBase      (          )
        ,   ::cppu::OWeakObject (          )
        // Init member
	,   m_bError		( false    )
        ,   m_xContext          ( xContext )
{
    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 immediately. 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 dying 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) Don't 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 unnecessary 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 file 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 these 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" SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
       *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}

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

extern "C" SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory(const sal_Char* pImplementationName, void* pServiceManager, void* pRegistryKey )
{
    return ::cppu::component_getFactoryHelper( pImplementationName, pServiceManager, pRegistryKey, avmedia::g_component_entries );
}
