/**************************************************************
 *
 * 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"
#include <tabwin/tabwindow.hxx>
#include <properties.h>

//_________________________________________________________________________________________________________________
//	my own includes
//_________________________________________________________________________________________________________________
#include <threadhelp/resetableguard.hxx>

//_________________________________________________________________________________________________________________
//	interface includes
//_________________________________________________________________________________________________________________
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/WindowDescriptor.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
//_________________________________________________________________________________________________________________
//	includes of other projects
//_________________________________________________________________________________________________________________
#include <rtl/ustrbuf.hxx>
#include <tools/urlobj.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <vcl/wrkwin.hxx>
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#include <comphelper/sequenceashashmap.hxx>

//_________________________________________________________________________________________________________________
//	Defines
//_________________________________________________________________________________________________________________
//

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

namespace framework
{

//*****************************************************************************************************************
//	XInterface, XTypeProvider, XServiceInfo
//*****************************************************************************************************************
DEFINE_XINTERFACE_11                    (   TabWindow										                                   ,
											::cppu::OWeakObject                                                                ,
                                            DIRECT_INTERFACE( css::lang::XTypeProvider								          ),
                                            DIRECT_INTERFACE( css::lang::XServiceInfo								          ),
											DIRECT_INTERFACE( css::lang::XInitialization							          ),
                                            DIRECT_INTERFACE( css::lang::XComponent                                           ),
											DIRECT_INTERFACE( css::awt::XWindowListener								          ),
                                            DIRECT_INTERFACE( css::awt::XTopWindowListener                                    ),
                                            DIRECT_INTERFACE( css::awt::XSimpleTabController                                  ),
											DERIVED_INTERFACE( css::lang::XEventListener, css::awt::XWindowListener           ),
											DIRECT_INTERFACE( css::beans::XMultiPropertySet							          ),
                                            DIRECT_INTERFACE( css::beans::XFastPropertySet							          ),
                                            DIRECT_INTERFACE( css::beans::XPropertySet								          )
										)

DEFINE_XTYPEPROVIDER_11                 (   TabWindow								,
                                            css::lang::XTypeProvider			    ,
                                            css::lang::XServiceInfo				    ,
											css::lang::XInitialization				,
                                            css::lang::XComponent                   ,
											css::awt::XWindowListener				,
                                            css::awt::XTopWindowListener            ,
                                            css::awt::XSimpleTabController          ,
											css::lang::XEventListener				,
                                            css::beans::XMultiPropertySet           ,
                                            css::beans::XFastPropertySet            ,
                                            css::beans::XPropertySet
										)

DEFINE_XSERVICEINFO_MULTISERVICE        (   TabWindow							,
                                            ::cppu::OWeakObject                 ,
                                            SERVICENAME_TABWINDOW				,
											IMPLEMENTATIONNAME_TABWINDOW
										)

DEFINE_INIT_SERVICE                     (   TabWindow, {} )

TabWindow::TabWindow( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) :
    ThreadHelpBase( &Application::GetSolarMutex() )
    , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
    , ::cppu::OPropertySetHelper  ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
    , m_bInitialized( sal_False )
    , m_bDisposed( sal_False )
    , m_nNextTabID( 1 )
    , m_aTitlePropName( RTL_CONSTASCII_USTRINGPARAM( "Title" ))
    , m_aPosPropName( RTL_CONSTASCII_USTRINGPARAM( "Position" ))
    , m_xServiceManager( xServiceManager )
    , m_aListenerContainer( m_aLock.getShareableOslMutex() )
{
}

TabWindow::~TabWindow()
{
}

//---------------------------------------------------------------------------------------------------------
// Helper
//---------------------------------------------------------------------------------------------------------

void TabWindow::implts_LayoutWindows() const
{
    const sal_Int32 nTabControlHeight = 30;

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );
    css::uno::Reference< css::awt::XDevice > xDevice( m_xTopWindow, css::uno::UNO_QUERY );
    css::uno::Reference< css::awt::XWindow > xWindow( m_xTopWindow, css::uno::UNO_QUERY );
    css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
    css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
    aLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    // Convert relative size to output size.
    if ( xWindow.is() && xDevice.is() )
    {
        css::awt::Rectangle  aRectangle  = xWindow->getPosSize();
        css::awt::DeviceInfo aInfo       = xDevice->getInfo();
        css::awt::Size       aSize       (  aRectangle.Width  - aInfo.LeftInset - aInfo.RightInset ,
                                            aRectangle.Height - aInfo.TopInset  - aInfo.BottomInset );

        css::awt::Size  aContainerWindowSize;
        css::awt::Size  aTabControlSize;

        aContainerWindowSize.Width = aSize.Width;
        aTabControlSize.Width = aSize.Width;

        aContainerWindowSize.Height = std::max( sal_Int32( 0 ), aSize.Height - nTabControlHeight );
        aTabControlSize.Height = nTabControlHeight;

        xContainerWindow->setPosSize( 0, 0,
                                      aContainerWindowSize.Width, aContainerWindowSize.Height,
                                      css::awt::PosSize::POSSIZE );
        xTabControlWindow->setPosSize( 0, std::max( nTabControlHeight, sal_Int32( aSize.Height - nTabControlHeight)),
                                       aTabControlSize.Width, aTabControlSize.Height,
                                       css::awt::PosSize::POSSIZE );
    }
}

TabControl* TabWindow::impl_GetTabControl( const css::uno::Reference< css::awt::XWindow >& rTabControlWindow ) const
{
	Window* pWindow = VCLUnoHelper::GetWindow( rTabControlWindow );
	if ( pWindow )
        return (TabControl *)pWindow;
    else
        return NULL;
}

void TabWindow::impl_SetTitle( const ::rtl::OUString& rTitle )
{
    if ( m_xTopWindow.is() )
    {
        Window* pWindow = VCLUnoHelper::GetWindow(
                            css::uno::Reference< css::awt::XWindow >(
                                m_xTopWindow, css::uno::UNO_QUERY ));
        if ( pWindow )
            pWindow->SetText( rTitle );
    }
}

void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID ) const
{
    ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
                                                        ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
    if (pContainer!=NULL)
	{
        ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
        while (pIterator.hasMoreElements())
        {
            try
            {
                switch ( eNotify )
                {
                    case NOTIFY_INSERTED:
                        ((css::awt::XTabListener*)pIterator.next())->inserted( ID );
                        break;
                    case NOTIFY_REMOVED:
                        ((css::awt::XTabListener*)pIterator.next())->removed( ID );
                        break;
                    case NOTIFY_ACTIVATED:
                        ((css::awt::XTabListener*)pIterator.next())->activated( ID );
                        break;
                    case NOTIFY_DEACTIVATED:
                        ((css::awt::XTabListener*)pIterator.next())->deactivated( ID );
                        break;
                    default:
                        break;
                }
            }
            catch( css::uno::RuntimeException& )
            {
                pIterator.remove();
            }
        }
	}
}

void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& rSeq ) const
{
    ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer(
                                                        ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) );
    if (pContainer!=NULL)
	{
        ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
        while (pIterator.hasMoreElements())
        {
            try
            {
                switch ( eNotify )
                {
                    case NOTIFY_CHANGED:
                        ((css::awt::XTabListener*)pIterator.next())->changed( ID, rSeq );
                        break;
                    default:
                        break;
                }
            }
            catch( css::uno::RuntimeException& )
            {
                pIterator.remove();
            }
        }
	}
}

//---------------------------------------------------------------------------------------------------------
// Links
//---------------------------------------------------------------------------------------------------------

IMPL_LINK( TabWindow, Activate, TabControl*, pTabControl )
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    sal_Int32 nPageId = pTabControl->GetCurPageId();

    rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( nPageId ));
    impl_SetTitle( aTitle );
    aLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    implts_SendNotification( NOTIFY_ACTIVATED, nPageId );

    return 1;
}

IMPL_LINK( TabWindow, Deactivate, TabControl*, pTabControl )
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );
    sal_Int32 nPageId = pTabControl->GetCurPageId();
    aLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    implts_SendNotification( NOTIFY_DEACTIVATED, nPageId );

    return 1;
}

//---------------------------------------------------------------------------------------------------------
// XInitialization
//---------------------------------------------------------------------------------------------------------

void SAL_CALL TabWindow::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
throw (css::uno::Exception, css::uno::RuntimeException)
{
    const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" ));
    const rtl::OUString aSizeArgName( RTL_CONSTASCII_USTRINGPARAM( "Size" ));

    css::awt::Size aDefaultSize( 500, 500 );
    css::awt::Size aSize( aDefaultSize );

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );
    sal_Bool                                               bInitialized( m_bInitialized );
	css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager );
	aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    if ( !bInitialized )
    {
		css::beans::PropertyValue				    aPropValue;
		css::uno::Reference< css::awt::XTopWindow > xTopWindow;
        css::uno::Reference< css::awt::XToolkit >   xToolkit;
        css::awt::WindowDescriptor                  aDescriptor;

        if ( xSMGR.is() )
        {
			try
            {
                xToolkit = css::uno::Reference< css::awt::XToolkit >(
                    xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY );
            }
            catch ( css::uno::RuntimeException& )
            {
                throw;
            }
            catch ( css::uno::Exception& )
            {
            }
        }

        for ( int i = 0; i < aArguments.getLength(); i++ )
        {
            if ( aArguments[i] >>= aPropValue )
            {
                if ( aPropValue.Name == aTopWindowArgName )
                    aPropValue.Value >>= xTopWindow;
                else if ( aPropValue.Name == aSizeArgName )
                {
                    aPropValue.Value >>= aSize;
                    if ( aSize.Width <= 0 )
                        aSize.Width = aDefaultSize.Width;
                    if ( aSize.Height <= 0 )
                        aSize.Height = aDefaultSize.Height;
                }
            }
        }

        if ( xToolkit.is() )
        {
            if ( !xTopWindow.is() )
            {
			    // describe top window properties.
			    aDescriptor.Type                =   css::awt::WindowClass_TOP;
			    aDescriptor.ParentIndex         =   -1;
			    aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >();
                aDescriptor.Bounds              =   css::awt::Rectangle( 0, 0, aSize.Width, aSize.Height );
			    aDescriptor.WindowAttributes    =   0;

			    try
                {
                    xTopWindow = css::uno::Reference< css::awt::XTopWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );
                }
                catch ( css::uno::RuntimeException& )
                {
                    throw;
                }
                catch ( css::uno::Exception& )
                {
                }
            }

            if ( xTopWindow.is() )
            {
	            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
			    aLock.lock();
                m_bInitialized = sal_True;
			    aLock.unlock();
	            /* SAFE AREA ----------------------------------------------------------------------------------------------- */

                css::uno::Reference< css::awt::XWindow > xWindow( xTopWindow, css::uno::UNO_QUERY );
                xWindow->addWindowListener( css::uno::Reference< css::awt::XWindowListener >(
				    static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));

                xTopWindow->addTopWindowListener( css::uno::Reference< css::awt::XTopWindowListener >(
                    static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW ));

				css::uno::Reference< css::awt::XWindow > xContainerWindow;
				css::uno::Reference< css::awt::XWindow > xTabControl;

				// describe container window properties.
				aDescriptor.Type                =   css::awt::WindowClass_SIMPLE;
				aDescriptor.ParentIndex         =   -1;
				aDescriptor.Parent              =   css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
				aDescriptor.Bounds              =   css::awt::Rectangle(0,0,0,0);
				aDescriptor.WindowAttributes    =   0;

				xContainerWindow = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );

				// create a tab control window properties
				aDescriptor.Type				= css::awt::WindowClass_SIMPLE;
				aDescriptor.WindowServiceName   = DECLARE_ASCII("tabcontrol");
				aDescriptor.ParentIndex			= -1;
				aDescriptor.Parent				= css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY );
				aDescriptor.Bounds				= css::awt::Rectangle( 0,0,0,0 );
				aDescriptor.WindowAttributes	= 0;

				xTabControl = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY );

				if ( xContainerWindow.is() && xTabControl.is() )
				{
	                /* SAFE AREA ----------------------------------------------------------------------------------------------- */
					aLock.lock();
					m_xTopWindow = xTopWindow;
                    m_xContainerWindow = xContainerWindow;
					m_xTabControlWindow = xTabControl;
					aLock.unlock();
	                /* SAFE AREA ----------------------------------------------------------------------------------------------- */

					xWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );

                    vos::OGuard	aGuard( Application::GetSolarMutex() );
                    Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
                    if( pWindow )
                        pWindow->Show( sal_True );

					pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
					if ( pWindow )
						pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );

					pWindow = VCLUnoHelper::GetWindow( xTabControl );
					if ( pWindow )
                    {
						pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE  );
                        TabControl* pTabControl = (TabControl *)pWindow;
                        pTabControl->SetActivatePageHdl( LINK( this, TabWindow, Activate ));
                        pTabControl->SetDeactivatePageHdl( LINK( this, TabWindow, Deactivate ));
                    }

                    implts_LayoutWindows();
				}
            }
        }
    }
}

//---------------------------------------------------------------------------------------------------------
//	XComponent
//---------------------------------------------------------------------------------------------------------
void SAL_CALL TabWindow::dispose() throw (css::uno::RuntimeException)
{
    // Send message to all listener and forget her references.
    css::uno::Reference< css::lang::XComponent > xThis(
        static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
    css::lang::EventObject aEvent( xThis );

    m_aListenerContainer.disposeAndClear( aEvent );

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow );
    css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow );
    css::uno::Reference< css::awt::XTopWindow > xTopWindow( m_xTopWindow );
    m_xTabControlWindow.clear();
    m_xContainerWindow.clear();
    m_xTopWindow.clear();
    aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    css::uno::Reference< css::lang::XComponent > xComponent( xTabControlWindow, css::uno::UNO_QUERY );
    if ( xComponent.is() )
        xComponent->dispose();

    xComponent = css::uno::Reference< css::lang::XComponent >( xContainerWindow, css::uno::UNO_QUERY );
    if ( xComponent.is() )
        xComponent->dispose();

    xComponent = css::uno::Reference< css::lang::XComponent >( xTopWindow, css::uno::UNO_QUERY );
    if ( xComponent.is() )
        xComponent->dispose();

    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
	aLock.lock();
    m_bDisposed = sal_True;
    aLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
}

void SAL_CALL TabWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
throw (css::uno::RuntimeException)
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    if ( m_bDisposed )
        return;
    aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
}

void SAL_CALL TabWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
throw (css::uno::RuntimeException)
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    if ( m_bDisposed )
        return;
    aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener );
}

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

//---------------------------------------------------------------------------------------------------------
// XWindowListener
//---------------------------------------------------------------------------------------------------------
void SAL_CALL TabWindow::windowResized( const css::awt::WindowEvent& )
throw( css::uno::RuntimeException )
{
    implts_LayoutWindows();
}

void SAL_CALL TabWindow::windowMoved( const css::awt::WindowEvent& )
throw( css::uno::RuntimeException )
{
}

void SAL_CALL TabWindow::windowShown( const css::lang::EventObject& )
throw( css::uno::RuntimeException )
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
        pTabControl->Show();

    if ( m_xContainerWindow.is() )
    {
        Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
        if ( pWindow )
            pWindow->Show();
    }
}

void SAL_CALL TabWindow::windowHidden( const css::lang::EventObject& )
throw( css::uno::RuntimeException )
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    if ( m_xContainerWindow.is() )
    {
        Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
        if ( pWindow )
            pWindow->Hide();
    }

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
        pTabControl->Hide();
}

//---------------------------------------------------------------------------------------------------------
// XTopWindowListener
//---------------------------------------------------------------------------------------------------------
void SAL_CALL TabWindow::windowOpened( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

void SAL_CALL TabWindow::windowClosing( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
    css::uno::Reference< css::lang::XComponent > xComponent( (OWeakObject *)this, css::uno::UNO_QUERY );
    if ( xComponent.is() )
        xComponent->dispose();
}

void SAL_CALL TabWindow::windowClosed( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

void SAL_CALL TabWindow::windowMinimized( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

void SAL_CALL TabWindow::windowNormalized( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

void SAL_CALL TabWindow::windowActivated( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

void SAL_CALL TabWindow::windowDeactivated( const css::lang::EventObject& )
throw (css::uno::RuntimeException)
{
}

//---------------------------------------------------------------------------------------------------------
//	XSimpleTabController
//---------------------------------------------------------------------------------------------------------

::sal_Int32 SAL_CALL TabWindow::insertTab()
throw (css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    sal_Int32 nNextTabID( m_nNextTabID++ );

    rtl::OUString aTitle;
    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
        pTabControl->InsertPage( sal_uInt16( nNextTabID ), aTitle );
    aLock.unlock();
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    implts_SendNotification( NOTIFY_INSERTED, nNextTabID );

    return nNextTabID;
}

void SAL_CALL TabWindow::removeTab( ::sal_Int32 ID )
throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
    {
        sal_uInt16 nCurTabId = pTabControl->GetCurPageId();
        sal_uInt16 nPos      = pTabControl->GetPagePos( sal_uInt16( ID ));
        if ( nPos == TAB_PAGE_NOTFOUND )
            throw css::lang::IndexOutOfBoundsException();
        else
        {
            pTabControl->RemovePage( sal_uInt16( ID ));
            nCurTabId = pTabControl->GetCurPageId();
        }
        aLock.unlock();
        /* SAFE AREA ----------------------------------------------------------------------------------------------- */

        implts_SendNotification( NOTIFY_REMOVED, ID );

        // activate new tab if old tab was active!
        nPos = pTabControl->GetPagePos( sal_uInt16( nCurTabId ));
        if ( nPos != TAB_PAGE_NOTFOUND && nCurTabId != ID )
            activateTab( nCurTabId );
    }
}

void SAL_CALL TabWindow::setTabProps( ::sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& Properties )
throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
    {
        sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
        if ( nPos == TAB_PAGE_NOTFOUND )
            throw css::lang::IndexOutOfBoundsException();
        else
        {
            comphelper::SequenceAsHashMap aSeqHashMap( Properties );

            ::rtl::OUString aTitle  = pTabControl->GetPageText( sal_uInt16( ID ));
            sal_Int32       nNewPos = nPos;

            aTitle = aSeqHashMap.getUnpackedValueOrDefault< ::rtl::OUString >(
                                    m_aTitlePropName, aTitle );
            pTabControl->SetPageText( sal_uInt16( ID ), aTitle );
            nNewPos = aSeqHashMap.getUnpackedValueOrDefault< sal_Int32 >(
                                    m_aPosPropName, nNewPos );
            if ( nNewPos != sal_Int32( nPos ))
            {
                nPos = sal_uInt16( nNewPos );
                if ( nPos >= pTabControl->GetPageCount() )
                    nPos = TAB_APPEND;

                pTabControl->RemovePage( sal_uInt16( ID ));
                pTabControl->InsertPage( sal_uInt16( ID ), aTitle, nPos );
            }

            /* SAFE AREA ----------------------------------------------------------------------------------------------- */
            aLock.unlock();

            css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq = getTabProps( ID );
            implts_SendNotification( NOTIFY_CHANGED, ID, aNamedValueSeq );
        }
    }
}

css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindow::getTabProps( ::sal_Int32 ID )
throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq;

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
    {
        sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
        if ( nPos == TAB_PAGE_NOTFOUND )
            throw css::lang::IndexOutOfBoundsException();
        else
        {
            rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
                          nPos   = pTabControl->GetPagePos( sal_uInt16( ID ));

            css::uno::Sequence< css::beans::NamedValue > aSeq( 2 );
            aSeq[0].Name  = m_aTitlePropName;
            aSeq[0].Value = css::uno::makeAny( aTitle );
            aSeq[1].Name  = m_aPosPropName;
            aSeq[1].Value = css::uno::makeAny( sal_Int32( nPos ));
            return aSeq;
        }
    }
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */

    return aNamedValueSeq;
}

void SAL_CALL TabWindow::activateTab( ::sal_Int32 ID )
throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
    {
        sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID ));
        if ( nPos == TAB_PAGE_NOTFOUND )
            throw css::lang::IndexOutOfBoundsException();
        else
        {
            sal_Int32 nOldID     = pTabControl->GetCurPageId();
            rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID ));
            pTabControl->SetCurPageId( sal_uInt16( ID ));
            pTabControl->SelectTabPage( sal_uInt16( ID ));
            impl_SetTitle( aTitle );

            aLock.unlock();
            /* SAFE AREA ----------------------------------------------------------------------------------------------- */

            if ( nOldID != TAB_PAGE_NOTFOUND )
                implts_SendNotification( NOTIFY_DEACTIVATED, nOldID );
            implts_SendNotification( NOTIFY_ACTIVATED, ID );
        }
    }
}

::sal_Int32 SAL_CALL TabWindow::getActiveTabID()
throw (css::uno::RuntimeException)
{
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    ResetableGuard aLock( m_aLock );

    if ( m_bDisposed )
        throw css::lang::DisposedException();

    TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow );
    if ( pTabControl )
    {
        sal_uInt16 nID = pTabControl->GetCurPageId();
        if ( nID == TAB_PAGE_NOTFOUND )
            return -1;
        else
            return sal_Int32( nID );
    }

    return -1;
    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
}

void SAL_CALL TabWindow::addTabListener(
    const css::uno::Reference< css::awt::XTabListener >& xListener )
throw (css::uno::RuntimeException)
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    if ( m_bDisposed )
        return;
    aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    m_aListenerContainer.addInterface(
        ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
}

void SAL_CALL TabWindow::removeTabListener( const css::uno::Reference< css::awt::XTabListener >& xListener )
throw (css::uno::RuntimeException)
{
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
	ResetableGuard aLock( m_aLock );
    if ( m_bDisposed )
        return;
    aLock.unlock();
	/* SAFE AREA ----------------------------------------------------------------------------------------------- */

    m_aListenerContainer.removeInterface(
        ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener );
}

//---------------------------------------------------------------------------------------------------------
//	OPropertySetHelper
//---------------------------------------------------------------------------------------------------------

// XPropertySet helper
sal_Bool SAL_CALL TabWindow::convertFastPropertyValue( css::uno::Any&       aConvertedValue ,
													   css::uno::Any&       aOldValue       ,
                                                       sal_Int32			nHandle         ,
													   const css::uno::Any& aValue             )
throw( css::lang::IllegalArgumentException )
{
	//	Initialize state with sal_False !!!
	//	(Handle can be invalid)
	sal_Bool bReturn = sal_False;

    switch( nHandle )
	{
        case TABWINDOW_PROPHANDLE_PARENTWINDOW :
            bReturn = PropHelper::willPropertyBeChanged(
                        com::sun::star::uno::makeAny( m_xContainerWindow ),
                        aValue,
                        aOldValue,
                        aConvertedValue);
                break;

        case TABWINDOW_PROPHANDLE_TOPWINDOW :
            bReturn = PropHelper::willPropertyBeChanged(
                        com::sun::star::uno::makeAny( m_xTopWindow ),
                        aValue,
                        aOldValue,
                        aConvertedValue);
                break;
	}

	// Return state of operation.
	return bReturn ;
}

void SAL_CALL TabWindow::setFastPropertyValue_NoBroadcast( sal_Int32,
                                                           const css::uno::Any&)
throw( css::uno::Exception )
{
}

void SAL_CALL TabWindow::getFastPropertyValue( css::uno::Any& aValue ,
                                               sal_Int32      nHandle    ) const
{
    switch( nHandle )
	{
        case TABWINDOW_PROPHANDLE_PARENTWINDOW:
            aValue <<= m_xContainerWindow;
            break;
        case TABWINDOW_PROPHANDLE_TOPWINDOW:
            aValue <<= m_xTopWindow;
            break;
    }
}

::cppu::IPropertyArrayHelper& SAL_CALL TabWindow::getInfoHelper()
{
	// Optimize this method !
	// We initialize a static variable only one time. And we don't need to use a mutex at every call!
	// For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
    static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;

    if( pInfoHelper == NULL )
	{
		// Ready for multithreading
        osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;

		// Control this pointer again, another instance can be faster then these!
        if( pInfoHelper == NULL )
		{
			// Define static member to give structure of properties to baseclass "OPropertySetHelper".
			// "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
			// "sal_True" say: Table is sorted by name.
            static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
			pInfoHelper = &aInfoHelper;
		}
	}

    return(*pInfoHelper);
}

css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL TabWindow::getPropertySetInfo()
throw ( css::uno::RuntimeException )
{
	// Optimize this method !
	// We initialize a static variable only one time. And we don't need to use a mutex at every call!
	// For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
    static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL;

    if( pInfo == NULL )
	{
		// Ready for multithreading
		osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
		// Control this pointer again, another instance can be faster then these!
        if( pInfo == NULL )
		{
			// Create structure of propertysetinfo for baseclass "OPropertySetHelper".
			// (Use method "getInfoHelper()".)
            static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
			pInfo = &xInfo;
		}
	}

	return (*pInfo);
}

const css::uno::Sequence< css::beans::Property > TabWindow::impl_getStaticPropertyDescriptor()
{
	// Create a new static property array to initialize sequence!
	// Table of all predefined properties of this class. It's used from OPropertySetHelper-class!
	// Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
	// It's necessary for methods of OPropertySetHelper.
	// ATTENTION:
    //      YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!

    static const com::sun::star::beans::Property pProperties[] =
	{
        com::sun::star::beans::Property( TABWINDOW_PROPNAME_PARENTWINDOW,
                                         TABWINDOW_PROPHANDLE_PARENTWINDOW,
                                         ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
                                         com::sun::star::beans::PropertyAttribute::READONLY  ),
        com::sun::star::beans::Property( TABWINDOW_PROPNAME_TOPWINDOW,
                                         TABWINDOW_PROPHANDLE_TOPWINDOW,
                                         ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL),
                                         com::sun::star::beans::PropertyAttribute::READONLY  )
	}; 	// Use it to initialize sequence!
    static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, TABWINDOW_PROPCOUNT );

	// Return static "PropertyDescriptor"
    return lPropertyDescriptor;
}

}
