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

#include <list>

#include <cppuhelper/implbase3.hxx>
#include <cppuhelper/implementationentry.hxx>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/document/XEventListener.hpp>
#include <com/sun/star/document/XEventBroadcaster.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/task/XJob.hpp>

#include <comphelper/processfactory.hxx>

#include <vos/mutex.hxx>
#include <osl/mutex.hxx>

#include <vcl/window.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/timer.hxx>
#include <vcl/menu.hxx>
#include <vcl/outdev.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/lineinfo.hxx>
#include <vcl/button.hxx>
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/sfx.hrc>
#include "rtl/ustrbuf.hxx"

#include "updatecheckui.hrc"

#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))

#define MSG_ERR_NO_WEBBROWSER_FOUND  (RID_SFX_APP_START + 7)
#define DEFAULT_MENUBAR_HEIGHT 24

#define PROPERTY_TITLE          RTL_CONSTASCII_STRINGPARAM("BubbleHeading")
#define PROPERTY_TEXT           RTL_CONSTASCII_STRINGPARAM("BubbleText")
#define PROPERTY_IMAGE          RTL_CONSTASCII_STRINGPARAM("BubbleImageURL")
#define PROPERTY_SHOW_BUBBLE    RTL_CONSTASCII_STRINGPARAM("BubbleVisible")
#define PROPERTY_CLICK_HDL      RTL_CONSTASCII_STRINGPARAM("MenuClickHDL")
#define PROPERTY_SHOW_MENUICON  RTL_CONSTASCII_STRINGPARAM("MenuIconVisible")

#define START_TIMER 1

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

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

static uno::Sequence< rtl::OUString > getServiceNames()
{
    uno::Sequence< rtl::OUString > aServiceList(1);
    aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheckUI");
    return aServiceList;
}

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

static rtl::OUString getImplementationName()
{
    return UNISTRING( "vnd.sun.UpdateCheckUI");
}

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

namespace
{

//------------------------------------------------------------------------------
class BubbleWindow : public FloatingWindow
{
    Point           maTipPos;
    Region          maBounds;
    Polygon         maRectPoly;
    Polygon         maTriPoly;
    XubString       maBubbleTitle;
    XubString       maBubbleText;
    Image           maBubbleImage;
    Size            maMaxTextSize;
    Rectangle       maTitleRect;
    Rectangle       maTextRect;
    long            mnTipOffset;

private:
    void            RecalcTextRects();

public:
                    BubbleWindow( Window* pParent, const XubString& rTitle,
                                  const XubString& rText, const Image& rImage );
                   ~BubbleWindow();

    virtual void    MouseButtonDown( const MouseEvent& rMEvt );
    virtual void    Paint( const Rectangle& rRect );
    void            Resize();
    void            Show( sal_Bool bVisible = sal_True, sal_uInt16 nFlags = SHOW_NOACTIVATE );
    void            SetTipPosPixel( const Point& rTipPos ) { maTipPos = rTipPos; }
    void            SetTitleAndText( const XubString& rTitle, const XubString& rText,
                                     const Image& rImage );
};

//------------------------------------------------------------------------------
class UpdateCheckUI : public ::cppu::WeakImplHelper3
                        < lang::XServiceInfo, document::XEventListener, beans::XPropertySet >
{
    uno::Reference< uno::XComponentContext > m_xContext;
    uno::Reference< task::XJob > mrJob;
    rtl::OUString       maBubbleTitle;
    rtl::OUString       maBubbleText;
    rtl::OUString       maBubbleImageURL;
    Image               maBubbleImage;
    BubbleWindow*       mpBubbleWin;
    SystemWindow*       mpIconSysWin;
    MenuBar*            mpIconMBar;
    ResMgr*             mpUpdResMgr;
    ResMgr*             mpSfxResMgr;
    Timer               maWaitTimer;
    Timer               maTimeoutTimer;
    Link                maWindowEventHdl;
    Link                maApplicationEventHdl;
    bool                mbShowBubble;
    bool                mbShowMenuIcon;
    bool                mbBubbleChanged;
    sal_uInt16              mnIconID;

private:
				    DECL_LINK( ClickHdl, sal_uInt16* );
				    DECL_LINK( HighlightHdl, MenuBar::MenuBarButtonCallbackArg* );
                    DECL_LINK( WaitTimeOutHdl, Timer* );
                    DECL_LINK( TimeOutHdl, Timer* );
                    DECL_LINK( UserEventHdl, UpdateCheckUI* );
                    DECL_LINK( WindowEventHdl, VclWindowEvent* );
                    DECL_LINK( ApplicationEventHdl, VclSimpleEvent* );

    BubbleWindow*   GetBubbleWindow();
    void            RemoveBubbleWindow( bool bRemoveIcon );
    Image           GetMenuBarIcon( MenuBar* pMBar );
    void            AddMenuBarIcon( SystemWindow* pSysWin, bool bAddEventHdl );
    Image           GetBubbleImage( ::rtl::OUString &rURL );

    uno::Reference< document::XEventBroadcaster > getGlobalEventBroadcaster() const
         throw (uno::RuntimeException);

public:
                    UpdateCheckUI(const uno::Reference<uno::XComponentContext>&);
    virtual        ~UpdateCheckUI();

    // XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName()
        throw (uno::RuntimeException);
    virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
        throw (uno::RuntimeException);
    virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
        throw (uno::RuntimeException);

    // XEventListener
    virtual void SAL_CALL notifyEvent(const document::EventObject& Event)
        throw (uno::RuntimeException);
    virtual void SAL_CALL disposing(const lang::EventObject& Event)
        throw (uno::RuntimeException);

	//XPropertySet
	virtual uno::Reference< beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(void)
        throw ( uno::RuntimeException );
	virtual void SAL_CALL setPropertyValue(const rtl::OUString& PropertyName, const uno::Any& aValue)
        throw( beans::UnknownPropertyException, beans::PropertyVetoException,
               lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException );
	virtual uno::Any SAL_CALL getPropertyValue(const rtl::OUString& PropertyName)
        throw ( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException );
	virtual void SAL_CALL addPropertyChangeListener(const rtl::OUString& PropertyName,
                                                    const uno::Reference< beans::XPropertyChangeListener > & aListener)
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException );
	virtual void SAL_CALL removePropertyChangeListener(const rtl::OUString& PropertyName,
                                                       const uno::Reference< beans::XPropertyChangeListener > & aListener)
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException );
	virtual void SAL_CALL addVetoableChangeListener(const rtl::OUString& PropertyName,
                                                    const uno::Reference< beans::XVetoableChangeListener > & aListener)
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException );
	virtual void SAL_CALL removeVetoableChangeListener(const rtl::OUString& PropertyName,
                                                       const uno::Reference< beans::XVetoableChangeListener > & aListener)
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException );
};

//------------------------------------------------------------------------------
UpdateCheckUI::UpdateCheckUI(const uno::Reference<uno::XComponentContext>& xContext) :
      m_xContext(xContext)
    , mpBubbleWin( NULL )
    , mpIconSysWin( NULL )
    , mpIconMBar( NULL )
    , mbShowBubble( false )
    , mbShowMenuIcon( false )
    , mbBubbleChanged( false )
    , mnIconID( 0 )
{
    mpUpdResMgr = ResMgr::CreateResMgr( "updchk" );
    mpSfxResMgr = ResMgr::CreateResMgr( "sfx" );

    maBubbleImage = GetBubbleImage( maBubbleImageURL );

    maWaitTimer.SetTimeout( 400 );
    maWaitTimer.SetTimeoutHdl( LINK( this, UpdateCheckUI, WaitTimeOutHdl ) );

    maTimeoutTimer.SetTimeout( 10000 );
    maTimeoutTimer.SetTimeoutHdl( LINK( this, UpdateCheckUI, TimeOutHdl ) );

    uno::Reference< document::XEventBroadcaster > xBroadcaster( getGlobalEventBroadcaster() );
    xBroadcaster->addEventListener( this );

    maWindowEventHdl = LINK( this, UpdateCheckUI, WindowEventHdl );
    maApplicationEventHdl = LINK( this, UpdateCheckUI, ApplicationEventHdl );
    Application::AddEventListener( maApplicationEventHdl );
}

//------------------------------------------------------------------------------
UpdateCheckUI::~UpdateCheckUI()
{
    Application::RemoveEventListener( maApplicationEventHdl );
    RemoveBubbleWindow( true );
    delete mpUpdResMgr;
    delete mpSfxResMgr;
}

//------------------------------------------------------------------------------
uno::Reference<document::XEventBroadcaster>
UpdateCheckUI::getGlobalEventBroadcaster() const throw (uno::RuntimeException)
{
    if( !m_xContext.is() )
        throw uno::RuntimeException(
            UNISTRING( "UpdateCheckUI: empty component context" ),
                uno::Reference< uno::XInterface >() );

    uno::Reference< lang::XMultiComponentFactory > xServiceManager(m_xContext->getServiceManager());

    if( !xServiceManager.is() )
        throw uno::RuntimeException(
            UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ),
                uno::Reference< uno::XInterface >() );

    return uno::Reference<document::XEventBroadcaster> (
        xServiceManager->createInstanceWithContext(
            UNISTRING( "com.sun.star.frame.GlobalEventBroadcaster" ),
            m_xContext),
        uno::UNO_QUERY_THROW);
}

//------------------------------------------------------------------------------
rtl::OUString SAL_CALL
UpdateCheckUI::getImplementationName() throw (uno::RuntimeException)
{
    return ::getImplementationName();
}

//------------------------------------------------------------------------------
uno::Sequence< rtl::OUString > SAL_CALL
UpdateCheckUI::getSupportedServiceNames() throw (uno::RuntimeException)
{
    return ::getServiceNames();
}

//------------------------------------------------------------------------------
sal_Bool SAL_CALL
UpdateCheckUI::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException)
{
    uno::Sequence< rtl::OUString > aServiceNameList = ::getServiceNames();

    for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
        if( aServiceNameList[n].equals(serviceName) )
            return sal_True;

    return sal_False;
}

//------------------------------------------------------------------------------
Image UpdateCheckUI::GetMenuBarIcon( MenuBar* pMBar )
{
    sal_uInt32 nResID;
    Window *pMBarWin = pMBar->GetWindow();
    sal_uInt32 nMBarHeight = 20;

    if ( pMBarWin )
        nMBarHeight = pMBarWin->GetOutputSizePixel().getHeight();

    if ( Application::GetSettings().GetStyleSettings().GetHighContrastMode() ) {
        if ( nMBarHeight >= 35 )
            nResID = RID_UPDATE_AVAILABLE_26_HC;
        else
            nResID = RID_UPDATE_AVAILABLE_16_HC;
    } else {
        if ( nMBarHeight >= 35 )
            nResID = RID_UPDATE_AVAILABLE_26;
        else
            nResID = RID_UPDATE_AVAILABLE_16;
    }

    return Image( ResId( nResID, *mpUpdResMgr ) );
}

//------------------------------------------------------------------------------
Image UpdateCheckUI::GetBubbleImage( ::rtl::OUString &rURL )
{
    Image aImage;

    if ( maBubbleImageURL.getLength() != 0 )
    {
    	uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();

        if( !xServiceManager.is() )
            throw uno::RuntimeException(
                UNISTRING( "UpdateCheckUI: unable to obtain service manager from component context" ),
                    uno::Reference< uno::XInterface >() );

        try
		{
            uno::Reference< graphic::XGraphicProvider > xGraphProvider(
                    xServiceManager->createInstance(
                            ::rtl::OUString::createFromAscii( "com.sun.star.graphic.GraphicProvider" ) ),
                    uno::UNO_QUERY );
            if ( xGraphProvider.is() )
            {
                uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
                aMediaProps[0].Name = ::rtl::OUString::createFromAscii( "URL" );
                aMediaProps[0].Value <<= rURL;

                uno::Reference< graphic::XGraphic > xGraphic = xGraphProvider->queryGraphic( aMediaProps );
                if ( xGraphic.is() )
                {
                    aImage = Image( xGraphic );
                }
            }
        }
        catch( uno::Exception& )
        {
        }
    }

    if ( aImage.GetSizePixel().Width() == 0 )
        aImage = InfoBox::GetStandardImage();

    return aImage;
}

//------------------------------------------------------------------------------
void UpdateCheckUI::AddMenuBarIcon( SystemWindow *pSysWin, bool bAddEventHdl )
{
    if ( ! mbShowMenuIcon )
        return;

    vos::OGuard aGuard( Application::GetSolarMutex() );

    MenuBar *pActiveMBar = pSysWin->GetMenuBar();
    if ( ( pSysWin != mpIconSysWin ) || ( pActiveMBar != mpIconMBar ) )
    {
        if ( bAddEventHdl && mpIconSysWin )
            mpIconSysWin->RemoveEventListener( maWindowEventHdl );

        RemoveBubbleWindow( true );

        if ( pActiveMBar )
        {
            rtl::OUStringBuffer aBuf;
            if( maBubbleTitle.getLength() )
                aBuf.append( maBubbleTitle );
            if( maBubbleText.getLength() )
            {
                if( maBubbleTitle.getLength() )
                    aBuf.appendAscii( "\n\n" );
                aBuf.append( maBubbleText );
            }
                
            Image aImage = GetMenuBarIcon( pActiveMBar );
            mnIconID = pActiveMBar->AddMenuBarButton( aImage,
                                    LINK( this, UpdateCheckUI, ClickHdl ),
                                    aBuf.makeStringAndClear()
                                    );
            pActiveMBar->SetMenuBarButtonHighlightHdl( mnIconID,
                                    LINK( this, UpdateCheckUI, HighlightHdl ) );
        }
        mpIconMBar = pActiveMBar;
        mpIconSysWin = pSysWin;
        if ( bAddEventHdl && mpIconSysWin )
            mpIconSysWin->AddEventListener( maWindowEventHdl );
    }

    if ( mbShowBubble && pActiveMBar )
    {
        mpBubbleWin = GetBubbleWindow();
        if ( mpBubbleWin )
        {
            mpBubbleWin->Show( sal_True );
            maTimeoutTimer.Start();
        }
        mbShowBubble = false;
    }
}

//------------------------------------------------------------------------------
void SAL_CALL UpdateCheckUI::notifyEvent(const document::EventObject& rEvent)
    throw (uno::RuntimeException)
{
	vos::OGuard aGuard( Application::GetSolarMutex() );

	if( rEvent.EventName.compareToAscii( RTL_CONSTASCII_STRINGPARAM("OnPrepareViewClosing") ) == 0 )
    {
        RemoveBubbleWindow( true );
    }
}

//------------------------------------------------------------------------------
void SAL_CALL UpdateCheckUI::disposing(const lang::EventObject&)
    throw (uno::RuntimeException)
{
}

//------------------------------------------------------------------------------
uno::Reference< beans::XPropertySetInfo > UpdateCheckUI::getPropertySetInfo(void)
    throw ( uno::RuntimeException )
{
	return NULL;
}

//------------------------------------------------------------------------------
void UpdateCheckUI::setPropertyValue(const rtl::OUString& rPropertyName,
									 const uno::Any& rValue)
	throw( beans::UnknownPropertyException, beans::PropertyVetoException,
		   lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    rtl::OUString aString;

	if( rPropertyName.compareToAscii( PROPERTY_TITLE ) == 0 ) {
        rValue >>= aString;
        if ( aString != maBubbleTitle ) {
            maBubbleTitle = aString;
            mbBubbleChanged = true;
        }
    }
    else if( rPropertyName.compareToAscii( PROPERTY_TEXT ) == 0 ) {
        rValue >>= aString;
        if ( aString != maBubbleText ) {
            maBubbleText = aString;
            mbBubbleChanged = true;
        }
    }
    else if( rPropertyName.compareToAscii( PROPERTY_IMAGE ) == 0 ) {
        rValue >>= aString;
        if ( aString != maBubbleImageURL ) {
            maBubbleImageURL = aString;
            maBubbleImage = GetBubbleImage( maBubbleImageURL );
            mbBubbleChanged = true;
        }
    }
    else if( rPropertyName.compareToAscii( PROPERTY_SHOW_BUBBLE ) == 0 ) {
        rValue >>= mbShowBubble;
		if ( mbShowBubble )
            Application::PostUserEvent( LINK( this, UpdateCheckUI, UserEventHdl ) );
        else if ( mpBubbleWin )
            mpBubbleWin->Show( sal_False );
    }
    else if( rPropertyName.compareToAscii( PROPERTY_CLICK_HDL ) == 0 ) {
        uno::Reference< task::XJob > aJob;
        rValue >>= aJob;
        if ( aJob.is() )
            mrJob = aJob;
        else
            throw lang::IllegalArgumentException();
    }
    else if (rPropertyName.compareToAscii( PROPERTY_SHOW_MENUICON ) == 0) {
        bool bShowMenuIcon = sal_False;
        rValue >>= bShowMenuIcon;
        if ( bShowMenuIcon != mbShowMenuIcon )
        {
            mbShowMenuIcon = bShowMenuIcon;
            if ( bShowMenuIcon )
                Application::PostUserEvent( LINK( this, UpdateCheckUI, UserEventHdl ) );
            else
                RemoveBubbleWindow( true );
        }
    }
    else
        throw beans::UnknownPropertyException();

    if ( mbBubbleChanged && mpBubbleWin )
        mpBubbleWin->Show( sal_False );
}

//------------------------------------------------------------------------------
uno::Any UpdateCheckUI::getPropertyValue(const rtl::OUString& rPropertyName)
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

	uno::Any aRet;

    if( rPropertyName.compareToAscii( PROPERTY_TITLE ) == 0 )
        aRet = uno::makeAny( maBubbleTitle );
    else if( rPropertyName.compareToAscii( PROPERTY_TEXT ) == 0 )
        aRet = uno::makeAny( maBubbleText );
    else if( rPropertyName.compareToAscii( PROPERTY_SHOW_BUBBLE ) == 0 )
        aRet = uno::makeAny( mbShowBubble );
    else if( rPropertyName.compareToAscii( PROPERTY_IMAGE ) == 0 )
        aRet = uno::makeAny( maBubbleImageURL );
    else if( rPropertyName.compareToAscii( PROPERTY_CLICK_HDL ) == 0 )
        aRet = uno::makeAny( mrJob );
    else if( rPropertyName.compareToAscii( PROPERTY_SHOW_MENUICON ) == 0 )
        aRet = uno::makeAny( mbShowMenuIcon );
    else
        throw beans::UnknownPropertyException();

	return aRet;
}

//------------------------------------------------------------------------------
void UpdateCheckUI::addPropertyChangeListener( const rtl::OUString& /*aPropertyName*/,
                                               const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
	//no bound properties
}

//------------------------------------------------------------------------------
void UpdateCheckUI::removePropertyChangeListener( const rtl::OUString& /*aPropertyName*/,
                                                  const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
	//no bound properties
}

//------------------------------------------------------------------------------
void UpdateCheckUI::addVetoableChangeListener( const rtl::OUString& /*aPropertyName*/,
                                               const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
	//no vetoable properties
}

//------------------------------------------------------------------------------
void UpdateCheckUI::removeVetoableChangeListener( const rtl::OUString& /*aPropertyName*/,
                                                  const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
	throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
	//no vetoable properties
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BubbleWindow * UpdateCheckUI::GetBubbleWindow()
{
    if ( !mpIconSysWin )
        return NULL;

    Rectangle aIconRect = mpIconMBar->GetMenuBarButtonRectPixel( mnIconID );
    if( aIconRect.IsEmpty() )
        return NULL;
    
    BubbleWindow* pBubbleWin = mpBubbleWin;

    if ( !pBubbleWin ) {
        pBubbleWin = new BubbleWindow( mpIconSysWin,
		  					           XubString( maBubbleTitle ),
                                       XubString( maBubbleText ),
                                       maBubbleImage );
        mbBubbleChanged = false;
    }
    else if ( mbBubbleChanged ) {
        pBubbleWin->SetTitleAndText( XubString( maBubbleTitle ), 
                                     XubString( maBubbleText ),
                                     maBubbleImage );
        mbBubbleChanged = false;
    }

    Point aWinPos = aIconRect.BottomCenter();

    pBubbleWin->SetTipPosPixel( aWinPos );

    return pBubbleWin;
}

//------------------------------------------------------------------------------
void UpdateCheckUI::RemoveBubbleWindow( bool bRemoveIcon )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    maWaitTimer.Stop();
    maTimeoutTimer.Stop();

    if ( mpBubbleWin )
    {
        delete mpBubbleWin;
        mpBubbleWin = NULL;
    }

    if ( bRemoveIcon )
    {
        try {
            if ( mpIconMBar && ( mnIconID != 0 ) )
            {
                mpIconMBar->RemoveMenuBarButton( mnIconID );
                mpIconMBar = NULL;
                mnIconID = 0;
            }
        }
        catch ( ... ) {
            mpIconMBar = NULL;
            mnIconID = 0;
        }

        mpIconSysWin = NULL;
    }
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, ClickHdl, sal_uInt16*, EMPTYARG )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    maWaitTimer.Stop();
    if ( mpBubbleWin )
        mpBubbleWin->Show( sal_False );

    if ( mrJob.is() )
    {
        try {
            uno::Sequence<beans::NamedValue> aEmpty;
            mrJob->execute( aEmpty );
        }
        catch(const uno::Exception&) {
            ErrorBox( NULL, ResId( MSG_ERR_NO_WEBBROWSER_FOUND, *mpSfxResMgr )).Execute();
        }
    }

    return 0;
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, HighlightHdl, MenuBar::MenuBarButtonCallbackArg*, pData )
{
	if ( pData->bHighlight )
        maWaitTimer.Start();
    else
        RemoveBubbleWindow( false );

	return 0;
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, WaitTimeOutHdl, Timer*, EMPTYARG )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    mpBubbleWin = GetBubbleWindow();

    if ( mpBubbleWin )
    {
        mpBubbleWin->Show();
    }

	return 0;
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, TimeOutHdl, Timer*, EMPTYARG )
{
    RemoveBubbleWindow( false );

	return 0;
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, UserEventHdl, UpdateCheckUI*, EMPTYARG )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    Window *pTopWin = Application::GetFirstTopLevelWindow();
    Window *pActiveWin = Application::GetActiveTopWindow();
	SystemWindow *pActiveSysWin = NULL;

    Window *pBubbleWin = NULL;
    if ( mpBubbleWin )
        pBubbleWin = mpBubbleWin;

	if ( pActiveWin && ( pActiveWin != pBubbleWin ) && pActiveWin->IsTopWindow() )
		pActiveSysWin = pActiveWin->GetSystemWindow();

    if ( pActiveWin == pBubbleWin )
        pActiveSysWin = NULL;

    while ( !pActiveSysWin && pTopWin )
    {
        if ( ( pTopWin != pBubbleWin ) && pTopWin->IsTopWindow() )
            pActiveSysWin = pTopWin->GetSystemWindow();
        if ( !pActiveSysWin )
            pTopWin = Application::GetNextTopLevelWindow( pTopWin );
    }

	if ( pActiveSysWin )
        AddMenuBarIcon( pActiveSysWin, true );

    return 0;
}

// -----------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, WindowEventHdl, VclWindowEvent*, pEvent )
{
    sal_uLong nEventID = pEvent->GetId();

    if ( VCLEVENT_OBJECT_DYING == nEventID )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        if ( mpIconSysWin == pEvent->GetWindow() )
        {
            mpIconSysWin->RemoveEventListener( maWindowEventHdl );
            RemoveBubbleWindow( true );
        }
    }
    else if ( VCLEVENT_WINDOW_MENUBARADDED == nEventID )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        Window *pWindow = pEvent->GetWindow();
        if ( pWindow )
        {
            SystemWindow *pSysWin = pWindow->GetSystemWindow();
            if ( pSysWin )
            {
                AddMenuBarIcon( pSysWin, false );
            }
        }
    }
    else if ( VCLEVENT_WINDOW_MENUBARREMOVED == nEventID )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        MenuBar *pMBar = (MenuBar*) pEvent->GetData();
        if ( pMBar && ( pMBar == mpIconMBar ) )
            RemoveBubbleWindow( true );
    }
    else if ( ( nEventID == VCLEVENT_WINDOW_MOVE ) ||
              ( nEventID == VCLEVENT_WINDOW_RESIZE ) )
    {
        vos::OGuard aGuard( Application::GetSolarMutex() );
        if ( ( mpIconSysWin == pEvent->GetWindow() ) &&
             ( mpBubbleWin != NULL ) && ( mpIconMBar != NULL ) )
        {
            Rectangle aIconRect = mpIconMBar->GetMenuBarButtonRectPixel( mnIconID );
            Point aWinPos = aIconRect.BottomCenter();
            mpBubbleWin->SetTipPosPixel( aWinPos );
            if ( mpBubbleWin->IsVisible() )
                mpBubbleWin->Show();    // This will recalc the screen positon of the bubble
        }
    }

    return 0;
}

//------------------------------------------------------------------------------
IMPL_LINK( UpdateCheckUI, ApplicationEventHdl, VclSimpleEvent *, pEvent)
{
    switch (pEvent->GetId())
    {
        case VCLEVENT_WINDOW_SHOW:
        case VCLEVENT_WINDOW_ACTIVATE:
        case VCLEVENT_WINDOW_GETFOCUS: {
            vos::OGuard aGuard( Application::GetSolarMutex() );

            Window *pWindow = static_cast< VclWindowEvent * >(pEvent)->GetWindow();
            if ( pWindow && pWindow->IsTopWindow() )
            {
                SystemWindow *pSysWin = pWindow->GetSystemWindow();
                MenuBar      *pMBar   = pSysWin->GetMenuBar();
                if ( pSysWin && pMBar )
                {
                    AddMenuBarIcon( pSysWin, true );
                }
            }
            break;
        }
    }
    return 0;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

#define TIP_HEIGHT             15
#define TIP_WIDTH               7
#define TIP_RIGHT_OFFSET       18
#define BUBBLE_BORDER          10
#define TEXT_MAX_WIDTH        300
#define TEXT_MAX_HEIGHT       200
#define INITIAL_SHOW_TIME   10000

//------------------------------------------------------------------------------
BubbleWindow::BubbleWindow( Window* pParent, const XubString& rTitle,
                            const XubString& rText, const Image& rImage )
    : FloatingWindow( pParent, WB_SYSTEMWINDOW
                               | WB_OWNERDRAWDECORATION
                               | WB_NOBORDER
                    )
    , maBubbleTitle( rTitle )
    , maBubbleText( rText )
    , maBubbleImage( rImage )
    , maMaxTextSize( TEXT_MAX_WIDTH, TEXT_MAX_HEIGHT )
    , mnTipOffset( 0 )
{
    SetBackground( Wallpaper( GetSettings().GetStyleSettings().GetHelpColor() ) );
}

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

//------------------------------------------------------------------------------
void BubbleWindow::Resize()
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

	FloatingWindow::Resize();

    Size aSize = GetSizePixel();

    if ( ( aSize.Height() < 20 ) || ( aSize.Width() < 60 ) )
        return;

    Rectangle aRect( 0, TIP_HEIGHT, aSize.Width(), aSize.Height() - TIP_HEIGHT );
	maRectPoly = Polygon( aRect, 6, 6 );
    Region aRegion( maRectPoly );
    long nTipOffset = aSize.Width() - TIP_RIGHT_OFFSET + mnTipOffset;

    Point aPointArr[4];
    aPointArr[0] = Point( nTipOffset, TIP_HEIGHT );
    aPointArr[1] = Point( nTipOffset, 0 );
    aPointArr[2] = Point( nTipOffset + TIP_WIDTH , TIP_HEIGHT );
    aPointArr[3] = Point( nTipOffset, TIP_HEIGHT );
 	maTriPoly = Polygon( 4, aPointArr );
    Region aTriRegion( maTriPoly );

    aRegion.Union( aTriRegion);
    maBounds = aRegion;

	SetWindowRegionPixel( maBounds );
}

//------------------------------------------------------------------------------
void BubbleWindow::SetTitleAndText( const XubString& rTitle,
                                    const XubString& rText,
                                    const Image& rImage )
{
    maBubbleTitle = rTitle;
    maBubbleText = rText;
    maBubbleImage = rImage;

    Resize();
}

//------------------------------------------------------------------------------
void BubbleWindow::Paint( const Rectangle& )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    LineInfo aThickLine( LINE_SOLID, 2 );

    DrawPolyLine( maRectPoly, aThickLine );
    DrawPolyLine( maTriPoly );

    Color aOldLine = GetLineColor();
    Size aSize = GetSizePixel();
    long nTipOffset = aSize.Width() - TIP_RIGHT_OFFSET + mnTipOffset;

    SetLineColor( GetSettings().GetStyleSettings().GetHelpColor() );
    DrawLine( Point( nTipOffset+2, TIP_HEIGHT ),
              Point( nTipOffset + TIP_WIDTH -1 , TIP_HEIGHT ),
              aThickLine );
    SetLineColor( aOldLine );

	//Image aImage = InfoBox::GetStandardImage();
	Size aImgSize = maBubbleImage.GetSizePixel();

	DrawImage( Point( BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT ), maBubbleImage );

	Font aOldFont = GetFont();
	Font aBoldFont = aOldFont;
	aBoldFont.SetWeight( WEIGHT_BOLD );

    SetFont( aBoldFont );
    Rectangle aTitleRect = maTitleRect;
	aTitleRect.Move( aImgSize.Width(), 0 );
    DrawText( aTitleRect, maBubbleTitle, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );

    SetFont( aOldFont );
    Rectangle aTextRect = maTextRect;
	aTextRect.Move( aImgSize.Width(), 0 );
    DrawText( aTextRect, maBubbleText, TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );
}

//------------------------------------------------------------------------------
void BubbleWindow::MouseButtonDown( const MouseEvent& )
{
    Show( sal_False );
}

//------------------------------------------------------------------------------
void BubbleWindow::Show( sal_Bool bVisible, sal_uInt16 nFlags )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

	if ( !bVisible )
    {
        FloatingWindow::Show( bVisible );
        return;
    }

    // don't show bubbles without a text
    if ( ( maBubbleTitle.Len() == 0 ) && ( maBubbleText.Len() == 0 ) )
        return;

	Size aWindowSize = GetSizePixel();

	// Image aImage = InfoBox::GetStandardImage();
	Size aImgSize = maBubbleImage.GetSizePixel();

	RecalcTextRects();

	aWindowSize.setHeight( maTitleRect.GetHeight() * 7 / 4+ maTextRect.GetHeight() +
						   3 * BUBBLE_BORDER + TIP_HEIGHT );

	if ( maTitleRect.GetWidth() > maTextRect.GetWidth() )
		aWindowSize.setWidth( maTitleRect.GetWidth() );
	else
		aWindowSize.setWidth( maTextRect.GetWidth() );

	aWindowSize.setWidth( aWindowSize.Width() + 3 * BUBBLE_BORDER + aImgSize.Width() );

	if ( aWindowSize.Height() < aImgSize.Height() + TIP_HEIGHT + 2 * BUBBLE_BORDER )
		aWindowSize.setHeight( aImgSize.Height() + TIP_HEIGHT + 2 * BUBBLE_BORDER );

	Point aPos;
	aPos.X() = maTipPos.X() - aWindowSize.Width() + TIP_RIGHT_OFFSET;
    aPos.Y() = maTipPos.Y();
    Point aScreenPos = GetParent()->OutputToAbsoluteScreenPixel( aPos );
    if ( aScreenPos.X() < 0 )
    {
        mnTipOffset = aScreenPos.X();
        aPos.X() -= mnTipOffset;
    }
	SetPosSizePixel( aPos, aWindowSize );

	FloatingWindow::Show( bVisible, nFlags );
}

//------------------------------------------------------------------------------
void BubbleWindow::RecalcTextRects()
{
    Size aTotalSize;
    sal_Bool bFinished = sal_False;
	Font aOldFont = GetFont();
	Font aBoldFont = aOldFont;

	aBoldFont.SetWeight( WEIGHT_BOLD );

    while ( !bFinished )
    {
        SetFont( aBoldFont );

        maTitleRect = GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize ),
                                   maBubbleTitle,
								   TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );

        SetFont( aOldFont );
        maTextRect = GetTextRect( Rectangle( Point( 0, 0 ), maMaxTextSize ),
                                  maBubbleText,
                                  TEXT_DRAW_MULTILINE | TEXT_DRAW_WORDBREAK );

        if ( maTextRect.GetHeight() < 10 )
            maTextRect.setHeight( 10 );

	    aTotalSize.setHeight( maTitleRect.GetHeight() +
							  aBoldFont.GetHeight() * 3 / 4 +
							  maTextRect.GetHeight() +
						      3 * BUBBLE_BORDER + TIP_HEIGHT );
        if ( aTotalSize.Height() > maMaxTextSize.Height() )
        {
            maMaxTextSize.Width() = maMaxTextSize.Width() * 3 / 2;
            maMaxTextSize.Height() = maMaxTextSize.Height() * 3 / 2;
        }
        else
            bFinished = sal_True;
    }
    maTitleRect.Move( 2*BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT );
	maTextRect.Move( 2*BUBBLE_BORDER, BUBBLE_BORDER + TIP_HEIGHT + maTitleRect.GetHeight() + aBoldFont.GetHeight() * 3 / 4 );
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

} // anonymous namespace

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

static uno::Reference<uno::XInterface> SAL_CALL
createInstance(const uno::Reference<uno::XComponentContext>& xContext)
{
    return  *new UpdateCheckUI(xContext);
}

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

static const cppu::ImplementationEntry kImplementations_entries[] =
{
    {
        createInstance,
        getImplementationName,
        getServiceNames,
        cppu::createSingleComponentFactory,
        NULL,
        0
    },
	{ NULL, NULL, NULL, NULL, NULL, 0 }
} ;

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

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

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

extern "C" void *
component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
{
    return cppu::component_getFactoryHelper(
        pszImplementationName,
        pServiceManager,
        pRegistryKey,
        kImplementations_entries) ;
}

