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



#include "precompiled_toolkit.hxx"

#include "toolkit/awt/animatedimagespeer.hxx"
#include "toolkit/helper/property.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/awt/XAnimatedImages.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/awt/ImageScaleMode.hpp>
/** === end UNO includes === **/

#include <comphelper/componentcontext.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <comphelper/processfactory.hxx>
#include <rtl/ustrbuf.hxx>
#include <tools/diagnose_ex.h>
#include <tools/urlobj.hxx>
#include <vcl/throbber.hxx>

#include <limits>

//......................................................................................................................
namespace toolkit
{
//......................................................................................................................

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
	using ::com::sun::star::uno::Sequence;
	using ::com::sun::star::uno::Type;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::container::ContainerEvent;
    using ::com::sun::star::awt::XAnimatedImages;
    using ::com::sun::star::awt::Size;
    using ::com::sun::star::lang::XMultiServiceFactory;
    using ::com::sun::star::graphic::XGraphicProvider;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::graphic::XGraphic;
	/** === end UNO using === **/
    namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;

	//==================================================================================================================
	//= AnimatedImagesPeer_Data
	//==================================================================================================================
    struct CachedImage
    {
        ::rtl::OUString                 sImageURL;
        mutable Reference< XGraphic >   xGraphic;

        CachedImage()
            :sImageURL()
            ,xGraphic()
        {
        }

        CachedImage( ::rtl::OUString const& i_imageURL )
            :sImageURL( i_imageURL )
            ,xGraphic()
        {
        }
    };

    struct AnimatedImagesPeer_Data
    {
        AnimatedImagesPeer&                             rAntiImpl;
        ::std::vector< ::std::vector< CachedImage > >   aCachedImageSets;

        AnimatedImagesPeer_Data( AnimatedImagesPeer& i_antiImpl )
            :rAntiImpl( i_antiImpl )
            ,aCachedImageSets()
        {
        }
    };

	//==================================================================================================================
	//= helper
	//==================================================================================================================
    namespace
    {
        //--------------------------------------------------------------------------------------------------------------
        bool lcl_ensureImage_throw( Reference< XGraphicProvider > const& i_graphicProvider, const bool i_isHighContrast, const CachedImage& i_cachedImage )
        {
            if ( !i_cachedImage.xGraphic.is() )
            {
                ::comphelper::NamedValueCollection aMediaProperties;
                if ( i_isHighContrast )
                {
                    // try (to find) the high-contrast version of the graphic first
                    INetURLObject aURL( i_cachedImage.sImageURL );
                    if ( aURL.GetProtocol() != INET_PROT_PRIV_SOFFICE )
                    {
                        rtl::OUString sURL( i_cachedImage.sImageURL );
                        const sal_Int32 separatorPos = sURL.lastIndexOf( '/' );
                        if ( separatorPos != -1 )
                        {
                            ::rtl::OUStringBuffer composer;
                            composer.append( sURL.copy( 0, separatorPos ) );
                            composer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/hicontrast" ) );
                            composer.append( sURL.copy( separatorPos ) );

                            aMediaProperties.put( "URL", composer.makeStringAndClear() );
                            i_cachedImage.xGraphic.set( i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
                        }
                    }
                }
                if ( !i_cachedImage.xGraphic.is() )
                {
                    aMediaProperties.put( "URL", i_cachedImage.sImageURL );
                    i_cachedImage.xGraphic.set( i_graphicProvider->queryGraphic( aMediaProperties.getPropertyValues() ), UNO_QUERY );
                }
            }
            return i_cachedImage.xGraphic.is();
        }

	    //--------------------------------------------------------------------------------------------------------------
        Size lcl_getGraphicSizePixel( Reference< XGraphic > const& i_graphic )
        {
            Size aSizePixel;
            try
            {
                if ( i_graphic.is() )
                {
                    const Reference< XPropertySet > xGraphicProps( i_graphic, UNO_QUERY_THROW );
                    OSL_VERIFY( xGraphicProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SizePixel" ) ) ) >>= aSizePixel );
                }
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
            return aSizePixel;
        }

	    //--------------------------------------------------------------------------------------------------------------
        void lcl_init( Sequence< ::rtl::OUString > const& i_imageURLs, ::std::vector< CachedImage >& o_images )
        {
            o_images.resize(0);
            size_t count = size_t( i_imageURLs.getLength() );
            o_images.reserve( count );
            for ( size_t i = 0; i < count; ++i )
            {
                o_images.push_back( CachedImage( i_imageURLs[i] ) );
            }
        }

	    //--------------------------------------------------------------------------------------------------------------
        void lcl_updateImageList_nothrow( AnimatedImagesPeer_Data& i_data )
        {
            Throbber* pThrobber = dynamic_cast< Throbber* >( i_data.rAntiImpl.GetWindow() );
            if ( pThrobber == NULL )
                return;

            try
            {
                // collect the image sizes of the different image sets
                const ::comphelper::ComponentContext aContext( ::comphelper::getProcessServiceFactory() );
                const Reference< XGraphicProvider > xGraphicProvider( aContext.createComponent( "com.sun.star.graphic.GraphicProvider" ), UNO_QUERY_THROW );

                const bool isHighContrast = pThrobber->GetSettings().GetStyleSettings().GetHighContrastMode();

                sal_Int32 nPreferredSet = -1;
                const size_t nImageSetCount = i_data.aCachedImageSets.size();
                if ( nImageSetCount < 2 )
                {
                    nPreferredSet = sal_Int32( nImageSetCount ) - 1;
                }
                else
                {
                    ::std::vector< Size > aImageSizes( nImageSetCount );
                    for ( sal_Int32 nImageSet = 0; size_t( nImageSet ) < nImageSetCount; ++nImageSet )
                    {
                        ::std::vector< CachedImage > const& rImageSet( i_data.aCachedImageSets[ nImageSet ] );
                        if  (   ( rImageSet.empty() )
                            ||  ( !lcl_ensureImage_throw( xGraphicProvider, isHighContrast, rImageSet[0] ) )
                            )
                        {
                            aImageSizes[ nImageSet ] = Size( ::std::numeric_limits< long >::max(), ::std::numeric_limits< long >::max() );
                        }
                        else
                        {
                            aImageSizes[ nImageSet ] = lcl_getGraphicSizePixel( rImageSet[0].xGraphic );
                        }
                    }

                    // find the set with the smallest difference between window size and image size
                    const ::Size aWindowSizePixel = pThrobber->GetSizePixel();
                    long nMinimalDistance = ::std::numeric_limits< long >::max();
                    for (   ::std::vector< Size >::const_iterator check = aImageSizes.begin();
                            check != aImageSizes.end();
                            ++check
                        )
                    {
                        if  (   ( check->Width > aWindowSizePixel.Width() )
                            ||  ( check->Height > aWindowSizePixel.Height() )
                            )
                            // do not use an image set which doesn't fit into the window
                            continue;

                        const sal_Int64 distance =
                                ( aWindowSizePixel.Width() - check->Width ) * ( aWindowSizePixel.Width() - check->Width )
                            +   ( aWindowSizePixel.Height() - check->Height ) * ( aWindowSizePixel.Height() - check->Height );
                        if ( distance < nMinimalDistance )
                        {
                            nMinimalDistance = distance;
                            nPreferredSet = check - aImageSizes.begin();
                        }
                    }
                }

                // found a set?
                Sequence< Reference< XGraphic > > aImages;
                if ( ( nPreferredSet >= 0 ) && ( size_t( nPreferredSet ) < nImageSetCount ) )
                {
                    // => set the images
                    ::std::vector< CachedImage > const& rImageSet( i_data.aCachedImageSets[ nPreferredSet ] );
                    aImages.realloc( rImageSet.size() );
                    sal_Int32 imageIndex = 0;
                    for (   ::std::vector< CachedImage >::const_iterator cachedImage = rImageSet.begin();
                            cachedImage != rImageSet.end();
                            ++cachedImage, ++imageIndex
                        )
                    {
                        lcl_ensureImage_throw( xGraphicProvider, isHighContrast, *cachedImage );
                        aImages[ imageIndex ] = cachedImage->xGraphic;
                    }
                }
                pThrobber->setImageList( aImages );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
        }

	    //--------------------------------------------------------------------------------------------------------------
        void lcl_updateImageList_nothrow( AnimatedImagesPeer_Data& i_data, const Reference< XAnimatedImages >& i_images )
        {
            try
            {
                const sal_Int32 nImageSetCount = i_images->getImageSetCount();
                i_data.aCachedImageSets.resize(0);
                for ( sal_Int32 set = 0;  set < nImageSetCount; ++set )
                {
                    const Sequence< ::rtl::OUString > aImageURLs( i_images->getImageSet( set ) );
                    ::std::vector< CachedImage > aImages;
                    lcl_init( aImageURLs, aImages );
                    i_data.aCachedImageSets.push_back( aImages );
                }

                lcl_updateImageList_nothrow( i_data );
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

	//==================================================================================================================
	//= AnimatedImagesPeer
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    AnimatedImagesPeer::AnimatedImagesPeer()
        :AnimatedImagesPeer_Base()
        ,m_pData( new AnimatedImagesPeer_Data( *this ) )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    AnimatedImagesPeer::~AnimatedImagesPeer()
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::startAnimation(  ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
        if ( pThrobber != NULL)
            pThrobber->start();
    }

	//------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::stopAnimation(  ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
        if ( pThrobber != NULL)
            pThrobber->stop();
    }

	//------------------------------------------------------------------------------------------------------------------
    ::sal_Bool SAL_CALL AnimatedImagesPeer::isAnimationRunning(  ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
        if ( pThrobber != NULL)
            return pThrobber->isRunning();
        return sal_False;
    }

	//------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::setProperty( const ::rtl::OUString& i_propertyName, const Any& i_value ) throw(RuntimeException)
    {
	    ::vos::OGuard aGuard( GetMutex() );

        Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
        if ( pThrobber == NULL )
        {
            VCLXWindow::setProperty( i_propertyName, i_value );
            return;
        }

        const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName );
        switch ( nPropertyId )
        {
            case BASEPROPERTY_STEP_TIME:
            {
                sal_Int32 nStepTime( 0 );
                if ( i_value >>= nStepTime )
                    pThrobber->setStepTime( nStepTime );
                break;
            }
            case BASEPROPERTY_AUTO_REPEAT:
            {
                sal_Bool bRepeat( sal_True );
                if ( i_value >>= bRepeat )
                    pThrobber->setRepeat( bRepeat );
                break;
            }

            case BASEPROPERTY_IMAGE_SCALE_MODE:
            {
                sal_Int16 nScaleMode( ImageScaleMode::ANISOTROPIC );
                ImageControl* pImageControl = dynamic_cast< ImageControl* >( GetWindow() );
                if ( pImageControl && ( i_value >>= nScaleMode ) )
                {
                    pImageControl->SetScaleMode( nScaleMode );
                }
            }
            break;

            default:
                AnimatedImagesPeer_Base::setProperty( i_propertyName, i_value );
                break;
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    Any SAL_CALL AnimatedImagesPeer::getProperty( const ::rtl::OUString& i_propertyName ) throw(RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );

        Any aReturn;

        Throbber* pThrobber( dynamic_cast< Throbber* >( GetWindow() ) );
        if ( pThrobber == NULL )
            return VCLXWindow::getProperty( i_propertyName );

        const sal_uInt16 nPropertyId = GetPropertyId( i_propertyName );
        switch ( nPropertyId )
        {
        case BASEPROPERTY_STEP_TIME:
            aReturn <<= pThrobber->getStepTime();
            break;

        case BASEPROPERTY_AUTO_REPEAT:
            aReturn <<= pThrobber->getRepeat();
            break;

        case BASEPROPERTY_IMAGE_SCALE_MODE:
            {
                ImageControl const* pImageControl = dynamic_cast< ImageControl* >( GetWindow() );
                aReturn <<= ( pImageControl ? pImageControl->GetScaleMode() : ImageScaleMode::ANISOTROPIC );
            }
            break;

        default:
            aReturn = AnimatedImagesPeer_Base::getProperty( i_propertyName );
            break;
        }

        return aReturn;
    }

    //------------------------------------------------------------------------------------------------------------------
    void AnimatedImagesPeer::ProcessWindowEvent( const VclWindowEvent& i_windowEvent )
    {
        switch ( i_windowEvent.GetId() )
        {
        case VCLEVENT_WINDOW_RESIZE:
            lcl_updateImageList_nothrow( *m_pData );
            break;
        }

        AnimatedImagesPeer_Base::ProcessWindowEvent( i_windowEvent );
    }

    //------------------------------------------------------------------------------------------------------------------
    void AnimatedImagesPeer::impl_updateImages_nolck( const Reference< XInterface >& i_animatedImages )
    {
        ::vos::OGuard aGuard( GetMutex() );

        lcl_updateImageList_nothrow( *m_pData, Reference< XAnimatedImages >( i_animatedImages, UNO_QUERY_THROW ) );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );

        sal_Int32 nPosition(0);
        OSL_VERIFY( i_event.Accessor >>= nPosition );
        size_t position = size_t( nPosition );
        if ( position > m_pData->aCachedImageSets.size() )
        {
            OSL_ENSURE( false, "AnimatedImagesPeer::elementInserted: illegal accessor/index!" );
            lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
        }

        Sequence< ::rtl::OUString > aImageURLs;
        OSL_VERIFY( i_event.Element >>= aImageURLs );
        ::std::vector< CachedImage > aImages;
        lcl_init( aImageURLs, aImages );
        m_pData->aCachedImageSets.insert( m_pData->aCachedImageSets.begin() + position, aImages );
        lcl_updateImageList_nothrow( *m_pData );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );

        sal_Int32 nPosition(0);
        OSL_VERIFY( i_event.Accessor >>= nPosition );
        size_t position = size_t( nPosition );
        if ( position >= m_pData->aCachedImageSets.size() )
        {
            OSL_ENSURE( false, "AnimatedImagesPeer::elementRemoved: illegal accessor/index!" );
            lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
        }

        m_pData->aCachedImageSets.erase( m_pData->aCachedImageSets.begin() + position );
        lcl_updateImageList_nothrow( *m_pData );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException)
    {
        ::vos::OGuard aGuard( GetMutex() );
        Reference< XAnimatedImages > xAnimatedImages( i_event.Source, UNO_QUERY_THROW );

        sal_Int32 nPosition(0);
        OSL_VERIFY( i_event.Accessor >>= nPosition );
        size_t position = size_t( nPosition );
        if ( position >= m_pData->aCachedImageSets.size() )
        {
            OSL_ENSURE( false, "AnimatedImagesPeer::elementReplaced: illegal accessor/index!" );
            lcl_updateImageList_nothrow( *m_pData, xAnimatedImages );
        }

        Sequence< ::rtl::OUString > aImageURLs;
        OSL_VERIFY( i_event.Element >>= aImageURLs );
        ::std::vector< CachedImage > aImages;
        lcl_init( aImageURLs, aImages );
        m_pData->aCachedImageSets[ position ] = aImages;
        lcl_updateImageList_nothrow( *m_pData );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::disposing( const EventObject& i_event ) throw (RuntimeException)
    {
        VCLXWindow::disposing( i_event );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::modified( const EventObject& i_event ) throw (RuntimeException)
    {
        impl_updateImages_nolck( i_event.Source );
    }

    //------------------------------------------------------------------------------------------------------------------
    void SAL_CALL AnimatedImagesPeer::dispose(  ) throw(RuntimeException)
    {
        AnimatedImagesPeer_Base::dispose();
        ::vos::OGuard aGuard( GetMutex() );
        m_pData->aCachedImageSets.resize(0);
    }

//......................................................................................................................
} // namespace toolkit
//......................................................................................................................
