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

#ifndef __FRAMEWORK_UIELEMENT_PROGRESSBARWRAPPER_HXX_
#include <uielement/progressbarwrapper.hxx>
#endif

//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________
#include <helper/statusindicator.hxx>
#include <threadhelp/resetableguard.hxx>
#include <uielement/statusindicatorinterfacewrapper.hxx>

//_________________________________________________________________________________________________________________
//	interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/ui/UIElementType.hpp>
#include <com/sun/star/lang/DisposedException.hpp>

//_________________________________________________________________________________________________________________
//	includes of other projects
//_________________________________________________________________________________________________________________
#include <vcl/svapp.hxx>
#include <toolkit/helper/vclunohelper.hxx>

//_________________________________________________________________________________________________________________
//	namespace
//_________________________________________________________________________________________________________________
using namespace ::com::sun::star;

namespace framework{

//_________________________________________________________________________________________________________________
//	non exported const
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//	non exported definitions
//_________________________________________________________________________________________________________________

//_________________________________________________________________________________________________________________
//	declarations
//_________________________________________________________________________________________________________________

ProgressBarWrapper::ProgressBarWrapper() :
UIElementWrapperBase( ::com::sun::star::ui::UIElementType::PROGRESSBAR )
    ,   m_bOwnsInstance( sal_False )
    ,   m_nRange( 100 )
    ,   m_nValue( 0 )
{
}

ProgressBarWrapper::~ProgressBarWrapper()
{
}

// public interfaces
void ProgressBarWrapper::setStatusBar( const uno::Reference< awt::XWindow >& rStatusBar, sal_Bool bOwnsInstance )
{
    ResetableGuard aGuard( m_aLock );

    if ( m_bDisposed )
        return;

    if ( m_bOwnsInstance )
    {
        // dispose XWindow reference our our status bar
        uno::Reference< lang::XComponent > xComponent( m_xStatusBar, uno::UNO_QUERY );
        try
        {
            if ( xComponent.is() )
                xComponent->dispose();
        }
        catch ( uno::Exception& )
        {
        }
        m_xStatusBar.clear();
    }

    m_bOwnsInstance = bOwnsInstance;
    m_xStatusBar    = rStatusBar;
}

uno::Reference< awt::XWindow > ProgressBarWrapper::getStatusBar() const
{
    ResetableGuard aGuard( m_aLock );

    if ( m_bDisposed )
        return uno::Reference< awt::XWindow >();

    return m_xStatusBar;
}

// wrapped methods of ::com::sun::star::task::XStatusIndicator
void ProgressBarWrapper::start( const ::rtl::OUString& Text, ::sal_Int32 Range )
throw (uno::RuntimeException)
{
    uno::Reference< awt::XWindow > xWindow;
    sal_Int32                      nValue( 0 );

    {
        ResetableGuard aGuard( m_aLock );

        if ( m_bDisposed )
            return;

        xWindow  = m_xStatusBar;
        m_nValue = 0;
        m_nRange = Range;
        nValue   = m_nValue;
    }

    if ( xWindow.is() )
    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
        {
            StatusBar* pStatusBar = (StatusBar *)pWindow;
            if ( !pStatusBar->IsProgressMode() )
                pStatusBar->StartProgressMode( Text );
            else
            {
			    pStatusBar->SetUpdateMode( sal_False );
			    pStatusBar->EndProgressMode();
                pStatusBar->StartProgressMode( Text );
			    pStatusBar->SetProgressValue( sal_uInt16( nValue ));
                pStatusBar->SetUpdateMode( sal_True );
            }
            pStatusBar->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
        }
    }
}

void ProgressBarWrapper::end()
throw (uno::RuntimeException)
{
    uno::Reference< awt::XWindow > xWindow;

    {
        ResetableGuard aGuard( m_aLock );

        if ( m_bDisposed )
            return;

        xWindow  = m_xStatusBar;
        m_nRange = 100;
        m_nValue = 0;
    }

    if ( xWindow.is() )
    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
        {
            StatusBar* pStatusBar = (StatusBar *)pWindow;
            if ( pStatusBar->IsProgressMode() )
                pStatusBar->EndProgressMode();
        }
    }
}

void ProgressBarWrapper::setText( const ::rtl::OUString& Text )
throw (uno::RuntimeException)
{
    uno::Reference< awt::XWindow > xWindow;
    sal_Int32 nValue( 0 );

    {
        ResetableGuard aGuard( m_aLock );

        if ( m_bDisposed )
            return;

        xWindow  = m_xStatusBar;
        m_aText  = Text;
        nValue   = m_nValue;
    }

    if ( xWindow.is() )
    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
        {
            StatusBar* pStatusBar = (StatusBar *)pWindow;
			if( pStatusBar->IsProgressMode() )
            {
			    pStatusBar->SetUpdateMode( sal_False );
			    pStatusBar->EndProgressMode();
                pStatusBar->StartProgressMode( Text );
			    pStatusBar->SetProgressValue( sal_uInt16( nValue ));
                pStatusBar->SetUpdateMode( sal_True );
            }
            else
                pStatusBar->SetText( Text );
        }
    }
}

void ProgressBarWrapper::setValue( ::sal_Int32 nValue )
throw (uno::RuntimeException)
{
    uno::Reference< awt::XWindow > xWindow;
    rtl::OUString aText;
    sal_Bool      bSetValue( sal_False );

    {
        ResetableGuard aGuard( m_aLock );

        if ( m_bDisposed )
            return;

        xWindow  = m_xStatusBar;

        double fVal( 0 );
        if ( m_nRange > 0 )
        {
            fVal = ( double( nValue ) / double( m_nRange )) * 100;
            fVal = std::max( double( 0 ), std::min( fVal, double( 100 )));
        }

        if ( m_nValue != sal_Int32( fVal ))
        {
            m_nValue = sal_Int32( fVal );
            bSetValue = sal_True;
        }

        nValue   = m_nValue;
        aText    = m_aText;
    }

    if ( xWindow.is() && bSetValue )
    {
        vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
        Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
        if ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )
        {
            StatusBar* pStatusBar = (StatusBar *)pWindow;
            if ( !pStatusBar->IsProgressMode() )
                pStatusBar->StartProgressMode( aText );
            pStatusBar->SetProgressValue( sal_uInt16( nValue ));
        }
    }
}

void ProgressBarWrapper::reset()
throw (uno::RuntimeException)
{
    setText( rtl::OUString() );
    setValue( 0 );
}

// XInitialization
void SAL_CALL ProgressBarWrapper::initialize( const uno::Sequence< uno::Any >& )
throw (uno::Exception, uno::RuntimeException)
{
    // dummy - do nothing
}

// XUpdatable
void SAL_CALL ProgressBarWrapper::update()
throw (uno::RuntimeException)
{
    // dummy - do nothing
}

// XComponent
void SAL_CALL ProgressBarWrapper::dispose()
throw (uno::RuntimeException)
{
    uno::Reference< lang::XComponent > xThis(
        static_cast< cppu::OWeakObject* >(this),
        uno::UNO_QUERY );

    {
        ResetableGuard aLock( m_aLock );

        if ( m_bDisposed )
            return;
    }

    {
        lang::EventObject aEvent( xThis );
        m_aListenerContainer.disposeAndClear( aEvent );

        ResetableGuard aLock( m_aLock );
        if ( m_bOwnsInstance )
        {
            try
            {
                uno::Reference< lang::XComponent > xComponent( m_xStatusBar, uno::UNO_QUERY );
                if ( xComponent.is() )
                    xComponent->dispose();
            }
            catch ( lang::DisposedException& )
            {
            }
        }

        m_xStatusBar.clear();
        m_bDisposed = sal_True;
    }
}

// XUIElement
uno::Reference< uno::XInterface > SAL_CALL ProgressBarWrapper::getRealInterface()
throw (uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    // Ready for multithreading
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        return uno::Reference< uno::XInterface >();
    else
    {
        uno::Reference< uno::XInterface > xComp( m_xProgressBarIfacWrapper );
        if ( !xComp.is() )
        {
            StatusIndicatorInterfaceWrapper* pWrapper =
                new StatusIndicatorInterfaceWrapper(
                    uno::Reference< lang::XComponent >(
                        static_cast< cppu::OWeakObject* >( this ),
                        uno::UNO_QUERY ));
                xComp = uno::Reference< uno::XInterface >(
                    static_cast< cppu::OWeakObject* >( pWrapper ),
                    uno::UNO_QUERY );
             m_xProgressBarIfacWrapper = xComp;
        }

        return xComp;
    }
}

}		//	namespace framework
