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

#ifdef SOLARIS
// HACK: prevent conflict between STLPORT and Workshop headers on Solaris 8
#include <ctime>
#endif

#include <string> // HACK: prevent conflict between STLPORT and Workshop headers

#ifndef _WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#include <unotools/viewoptions.hxx>
#ifndef GCC
#endif

#include <vcl/timer.hxx>

#include "splitwin.hxx"
#include "workwin.hxx"
#include <sfx2/dockwin.hxx>
#include <sfx2/app.hxx>
#include "dialog.hrc"
#include "sfx2/sfxresid.hxx"
#include <sfx2/mnumgr.hxx>
#include "virtmenu.hxx"
#include <sfx2/msgpool.hxx>
#include <sfx2/viewfrm.hxx>

#include <vector>
#include <utility>

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

#define VERSION	1
#define nPixel	30L
#define USERITEM_NAME			OUString::createFromAscii( "UserItem" )

namespace {
    // helper class to deactivate UpdateMode, if needed, for the life time of an instance
    class DeactivateUpdateMode
    {
    public:
        explicit DeactivateUpdateMode( SfxSplitWindow& rSplitWindow )
            : mrSplitWindow( rSplitWindow )
            , mbUpdateMode( rSplitWindow.IsUpdateMode() )
        {
            if ( mbUpdateMode )
            {
                mrSplitWindow.SetUpdateMode( sal_False );
            }
        }

        ~DeactivateUpdateMode( void )
        {
            if ( mbUpdateMode )
            {
                mrSplitWindow.SetUpdateMode( sal_True );
            }
        }

    private:
        SfxSplitWindow& mrSplitWindow;
        const sal_Bool mbUpdateMode;
    };
}

struct SfxDock_Impl
{
	sal_uInt16 				nType;
	SfxDockingWindow*	pWin;			// SplitWindow hat dieses Fenster
	sal_Bool				bNewLine;
	sal_Bool				bHide;			// SplitWindow hatte dieses Fenster
	long				nSize;
};

typedef SfxDock_Impl* SfxDockPtr;
SV_DECL_PTRARR_DEL( SfxDockArr_Impl, SfxDockPtr, 4, 4)
SV_IMPL_PTRARR( SfxDockArr_Impl, SfxDockPtr);

class SfxEmptySplitWin_Impl : public SplitWindow
{
/*  [Beschreibung]

	Das SfxEmptySplitWin_Impldow ist ein leeres SplitWindow, das das SfxSplitWindow
	im AutoHide-Modus ersetzt. Es dient nur als Platzhalter, um MouseMoves
	zu empfangen und ggf. das eigentlichte SplitWindow einzublenden
*/
friend class SfxSplitWindow;

	SfxSplitWindow* 	pOwner;
	sal_Bool				bFadeIn;
	sal_Bool				bAutoHide;
	sal_Bool				bSplit;
	sal_Bool				bEndAutoHide;
	Timer				aTimer;
	Point				aLastPos;
	sal_uInt16				nState;

						SfxEmptySplitWin_Impl( SfxSplitWindow *pParent )
							: SplitWindow( pParent->GetParent(), WinBits( WB_BORDER | WB_3DLOOK ) )
							, pOwner( pParent )
							, bFadeIn( sal_False )
							, bAutoHide( sal_False )
							, bSplit( sal_False )
							, bEndAutoHide( sal_False )
							, nState( 1 )
						{
							aTimer.SetTimeoutHdl(
								LINK(pOwner, SfxSplitWindow, TimerHdl ) );
							aTimer.SetTimeout( 200 );
//                            EnableDrop( sal_True );
							SetAlign( pOwner->GetAlign() );
							Actualize();
							ShowAutoHideButton( pOwner->IsAutoHideButtonVisible() );
							ShowFadeInHideButton( sal_True );
						}

						~SfxEmptySplitWin_Impl()
						{
							aTimer.Stop();
						}

	virtual void		MouseMove( const MouseEvent& );
	virtual void		AutoHide();
	virtual void		FadeIn();
	void				Actualize();
};

void SfxEmptySplitWin_Impl::Actualize()
{
	Size aSize( pOwner->GetSizePixel() );
	switch ( pOwner->GetAlign() )
	{
		case WINDOWALIGN_LEFT:
		case WINDOWALIGN_RIGHT:
			aSize.Width() = GetFadeInSize();
			break;
		case WINDOWALIGN_TOP:
		case WINDOWALIGN_BOTTOM:
			aSize.Height() = GetFadeInSize();
			break;
	}

	SetSizePixel( aSize );
}

void SfxEmptySplitWin_Impl::AutoHide()
{
	pOwner->SetPinned_Impl( !pOwner->bPinned );
	pOwner->SaveConfig_Impl();
	bAutoHide = sal_True;
	FadeIn();
}

void SfxEmptySplitWin_Impl::FadeIn()
{
	if (!bAutoHide )
		bAutoHide = IsFadeNoButtonMode();
	pOwner->SetFadeIn_Impl( sal_True );
	pOwner->Show_Impl();
	if ( bAutoHide )
	{
		// Timer zum Schlie\sen aufsetzen; der Aufrufer mu\s selbst sicherstellen,
		// da\s das Window nicht gleich wieder zu geht ( z.B. durch Setzen des
		// Focus oder einen modal mode )
		aLastPos = GetPointerPosPixel();
		aTimer.Start();
	}
	else
		pOwner->SaveConfig_Impl();
}

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

void SfxSplitWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
	if ( rMEvt.GetClicks() != 2 )
		SplitWindow::MouseButtonDown( rMEvt );
}

void SfxEmptySplitWin_Impl::MouseMove( const MouseEvent& rMEvt )
{
	SplitWindow::MouseMove( rMEvt );
}

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

SfxSplitWindow::SfxSplitWindow( Window* pParent, SfxChildAlignment eAl,
		SfxWorkWindow *pW, sal_Bool bWithButtons, WinBits nBits )

/*  [Beschreibung]

	Ein SfxSplitWindow verbirgt die rekursive Struktur des SV-Splitwindows
	nach au\sen, indem es einen tabellenartigen Aufbau mit Zeilen und Spalten
	( also maximale Rekursionstiefe 2 ) simuliert.
	Au\erdem sichert es die Persistenz der Anordnung der SfxDockingWindows.
*/

:	SplitWindow ( pParent, nBits | WB_HIDE ),
	eAlign(eAl),
	pWorkWin(pW),
	pDockArr( new SfxDockArr_Impl ),
	bLocked(sal_False),
	bPinned(sal_True),
	pEmptyWin(NULL),
	pActive(NULL)
{
	if ( bWithButtons )
	{
		ShowAutoHideButton( sal_False );    // no autohide button (pin) anymore
		ShowFadeOutButton( sal_True );
	}

	// SV-Alignment setzen
	WindowAlign eTbxAlign;
	switch ( eAlign )
	{
		case SFX_ALIGN_LEFT:
			eTbxAlign = WINDOWALIGN_LEFT;
			break;
		case SFX_ALIGN_RIGHT:
			eTbxAlign = WINDOWALIGN_RIGHT;
			break;
		case SFX_ALIGN_TOP:
			eTbxAlign = WINDOWALIGN_TOP;
			break;
		case SFX_ALIGN_BOTTOM:
			eTbxAlign = WINDOWALIGN_BOTTOM;
			bPinned = sal_True;
			break;
		default:
			eTbxAlign = WINDOWALIGN_TOP;  // some sort of default...
			break;  // -Wall lots not handled..
	}

	SetAlign (eTbxAlign);
	pEmptyWin = new SfxEmptySplitWin_Impl( this );
	if ( bPinned )
	{
		pEmptyWin->bFadeIn = sal_True;
		pEmptyWin->nState = 2;
	}

	if ( bWithButtons )
	{
		// Konfiguration einlesen
        String aWindowId = String::CreateFromAscii("SplitWindow");
        aWindowId += String::CreateFromInt32( (sal_Int32) eTbxAlign );
        SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
        String aWinData;
		Any aUserItem = aWinOpt.GetUserItem( USERITEM_NAME );
		OUString aTemp;
		if ( aUserItem >>= aTemp )
			aWinData = String( aTemp );
        if ( aWinData.Len() && aWinData.GetChar( (sal_uInt16) 0 ) == 'V' )
        {
            pEmptyWin->nState = (sal_uInt16) aWinData.GetToken( 1, ',' ).ToInt32();
            if ( pEmptyWin->nState & 2 )
                pEmptyWin->bFadeIn = sal_True;
            //bPinned = !( pEmptyWin->nState & 1 );
            bPinned = sal_True; // always assume pinned - floating mode not used anymore

            sal_uInt16 i=2;
            sal_uInt16 nCount = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
            for ( sal_uInt16 n=0; n<nCount; n++ )
            {
                SfxDock_Impl *pDock = new SfxDock_Impl;
                pDock->pWin = 0;
                pDock->bNewLine = sal_False;
                pDock->bHide = sal_True;
                pDock->nType = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
                if ( !pDock->nType )
                {
                    // K"onnte NewLine bedeuten
                    pDock->nType = (sal_uInt16) aWinData.GetToken(i++, ',').ToInt32();
                    if ( !pDock->nType )
                    {
                        // Lesefehler
                        delete pDock;
                        break;
                    }
                    else
                        pDock->bNewLine = sal_True;
                }

                pDockArr->Insert(pDock,n);
            }
        }
	}
	else
	{
		bPinned = sal_True;
		pEmptyWin->bFadeIn = sal_True;
		pEmptyWin->nState = 2;
	}

	SetAutoHideState( !bPinned );
	pEmptyWin->SetAutoHideState( !bPinned );
}

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

SfxSplitWindow::~SfxSplitWindow()
{
	if ( !pWorkWin->GetParent_Impl() )
		SaveConfig_Impl();

	if ( pEmptyWin )
	{
		// pOwner auf NULL setzen, sonst versucht pEmptyWin, nochmal zu
		// l"oschen; es wird n"amlich von au\sen immer das Fenster deleted,
		// das gerade angedockt ist
		pEmptyWin->pOwner = NULL;
		delete pEmptyWin;
	}

	delete pDockArr;
}

void SfxSplitWindow::SaveConfig_Impl()
{
	// Konfiguration abspeichern
	String aWinData('V');
    aWinData += String::CreateFromInt32( VERSION );
	aWinData += ',';
    aWinData += String::CreateFromInt32( pEmptyWin->nState );
	aWinData += ',';

	sal_uInt16 nCount = 0;
	sal_uInt16 n;
	for ( n=0; n<pDockArr->Count(); n++ )
	{
		SfxDock_Impl *pDock = (*pDockArr)[n];
		if ( pDock->bHide || pDock->pWin )
			nCount++;
	}

    aWinData += String::CreateFromInt32( nCount );

	for ( n=0; n<pDockArr->Count(); n++ )
	{
		SfxDock_Impl *pDock = (*pDockArr)[n];
		if ( !pDock->bHide && !pDock->pWin )
			continue;
		if ( pDock->bNewLine )
			aWinData += DEFINE_CONST_UNICODE(",0");
		aWinData += ',';
        aWinData += String::CreateFromInt32( pDock->nType);
	}

    String aWindowId = String::CreateFromAscii("SplitWindow");
    aWindowId += String::CreateFromInt32( (sal_Int32) GetAlign() );
    SvtViewOptions aWinOpt( E_WINDOW, aWindowId );
	aWinOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aWinData ) ) );
}

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

void SfxSplitWindow::StartSplit()
{
	long nSize = 0;
	Size aSize = GetSizePixel();

	if ( pEmptyWin )
	{
		pEmptyWin->bFadeIn = sal_True;
		pEmptyWin->bSplit = sal_True;
	}

	Rectangle aRect = pWorkWin->GetFreeArea( !bPinned );
	switch ( GetAlign() )
	{
		case WINDOWALIGN_LEFT:
		case WINDOWALIGN_RIGHT:
			nSize = aSize.Width() + aRect.GetWidth();
			break;
		case WINDOWALIGN_TOP:
		case WINDOWALIGN_BOTTOM:
			nSize = aSize.Height() + aRect.GetHeight();
			break;
	}

	SetMaxSizePixel( nSize );
}

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

void SfxSplitWindow::SplitResize()
{
	if ( bPinned )
	{
		pWorkWin->ArrangeChilds_Impl();
		pWorkWin->ShowChilds_Impl();
	}
	else
		pWorkWin->ArrangeAutoHideWindows( this );
}

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

void SfxSplitWindow::Split()
{
    if ( pEmptyWin )
        pEmptyWin->bSplit = sal_False;

    SplitWindow::Split();

    std::vector< std::pair< sal_uInt16, long > > aNewOrgSizes;

    sal_uInt16 nCount = pDockArr->Count();
    for ( sal_uInt16 n=0; n<nCount; n++ )
    {
        SfxDock_Impl *pD = (*pDockArr)[n];
        if ( pD->pWin )
        {
            const sal_uInt16 nId = pD->nType;
            const long nSize    = GetItemSize( nId, SWIB_FIXED );
            const long nSetSize = GetItemSize( GetSet( nId ) );
            Size aSize;

            if ( IsHorizontal() )
            {
                aSize.Width()  = nSize;
                aSize.Height() = nSetSize;
            }
            else
            {
                aSize.Width()  = nSetSize;
                aSize.Height() = nSize;
            }

            pD->pWin->SetItemSize_Impl( aSize );

            aNewOrgSizes.push_back( std::pair< sal_uInt16, long >( nId, nSize ) );
        }
    }

    // workaround insuffiency of <SplitWindow> regarding dock layouting:
    // apply FIXED item size as 'original' item size to improve layouting of undock-dock-cycle of a window
    {
        DeactivateUpdateMode aDeactivateUpdateMode( *this );
        for ( sal_uInt16 i = 0; i < aNewOrgSizes.size(); ++i )
        {
            SetItemSize( aNewOrgSizes[i].first, aNewOrgSizes[i].second );
        }
    }

    SaveConfig_Impl();
}

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

void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize)

/*  [Beschreibung]

	Zum Einf"ugen von SfxDockingWindows kann auch keine Position "ubergeben
	werden. Das SfxSplitWindow sucht dann die zuletzt gemerkte zu dem
	"ubergebenen SfxDockingWindow heraus oder h"angt es als letztes neu an.

*/
{
	short nLine = -1;    	// damit erstes Fenster nLine auf 0 hochsetzen kann
	sal_uInt16 nL;
	sal_uInt16 nPos = 0;
	sal_Bool bNewLine = sal_True;
	sal_Bool bSaveConfig = sal_False;
	SfxDock_Impl *pFoundDock=0;
	sal_uInt16 nCount = pDockArr->Count();
	for ( sal_uInt16 n=0; n<nCount; n++ )
	{
		SfxDock_Impl *pDock = (*pDockArr)[n];
		if ( pDock->bNewLine )
		{
			// Das Fenster er"offnet eine neue Zeile
			if ( pFoundDock )
				// Aber hinter dem gerade eingef"ugten Fenster
				break;

			// Neue Zeile
			nPos = 0;
			bNewLine = sal_True;
		}

		if ( pDock->pWin )
		{
			// Es gibt an dieser Stelle gerade ein Fenster
			if ( bNewLine && !pFoundDock )
			{
				// Bisher ist nicht bekannt, in welcher realen Zeile es liegt
				GetWindowPos( pDock->pWin, nL, nPos );
				nLine = (short) nL;
			}

			if ( !pFoundDock )
			{
				// Fenster liegt vor dem eingef"ugten
				nPos++;
			}

			// Zeile ist schon er"offnet
			bNewLine = sal_False;
			if ( pFoundDock )
				break;
		}

		if ( pDock->nType == pDockWin->GetType() )
		{
			DBG_ASSERT( !pFoundDock && !pDock->pWin, "Fenster ist schon vorhanden!");
			pFoundDock = pDock;
			if ( !bNewLine )
				break;
			else
			{
				// Es wurde zuletzt eine neue Reihe gestartet, aber noch kein
				// darin liegendes Fenster gefunden; daher weitersuchen, ob noch
				// ein Fenster in dieser Zeile folgt, um bNewLine korrekt zu setzen.
				// Dabei darf aber nLine oder nPos nicht mehr ver"andert werden!
				nLine++;
			}
		}
	}

	if ( !pFoundDock )
	{
		// Nicht gefunden, am Ende einf"ugen
		pFoundDock = new SfxDock_Impl;
		pFoundDock->bHide = sal_True;
		pDockArr->Insert( pFoundDock, nCount );
		pFoundDock->nType = pDockWin->GetType();
		nLine++;
		nPos = 0;
		bNewLine = sal_True;
		pFoundDock->bNewLine = bNewLine;
		bSaveConfig = sal_True;
	}

	pFoundDock->pWin = pDockWin;
	pFoundDock->bHide = sal_False;
	InsertWindow_Impl( pFoundDock, rSize, nLine, nPos, bNewLine );
	if ( bSaveConfig )
		SaveConfig_Impl();
}

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

void SfxSplitWindow::ReleaseWindow_Impl(SfxDockingWindow *pDockWin, sal_Bool bSave)

/*  [Beschreibung]

	Das DockingWindow wird nicht mehr in den internen Daten gespeichert.
*/

{
	SfxDock_Impl *pDock=0;
	sal_uInt16 nCount = pDockArr->Count();
	sal_Bool bFound = sal_False;
	for ( sal_uInt16 n=0; n<nCount; n++ )
	{
		pDock = (*pDockArr)[n];
		if ( pDock->nType == pDockWin->GetType() )
		{
			if ( pDock->bNewLine && n<nCount-1 )
				(*pDockArr)[n+1]->bNewLine = sal_True;

			// Fenster hat schon eine Position, die vergessen wir
			bFound = sal_True;
			pDockArr->Remove(n);
			break;
		}
	}

	if ( bFound )
		delete pDock;

	if ( bSave )
		SaveConfig_Impl();
}

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

void SfxSplitWindow::MoveWindow( SfxDockingWindow* pDockWin, const Size& rSize,
						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)

/*  [Beschreibung]

	Das DockingWindow wird innerhalb des Splitwindows verschoben.

*/

{
	sal_uInt16 nL, nP;
	GetWindowPos( pDockWin, nL, nP );

	if ( nLine > nL && GetItemCount( GetItemId( nL, 0 ) ) == 1 )
	{
		// Wenn das letzte Fenster aus seiner Zeile entfernt wird, rutscht
		// alles eine Zeile nach vorne!
		nLine--;
	}
/*
	else if ( nLine == nL && nPos > nP )
	{
		nPos--;
	}
*/
	RemoveWindow( pDockWin );
	InsertWindow( pDockWin, rSize, nLine, nPos, bNewLine );
}

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

void SfxSplitWindow::InsertWindow( SfxDockingWindow* pDockWin, const Size& rSize,
						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)

/*  [Beschreibung]

	Das DockingWindow wird in dieses Splitwindow geschoben und soll die
	"ubergebene Position und Gr"o\se haben.

*/
{
	ReleaseWindow_Impl( pDockWin, sal_False );
	SfxDock_Impl *pDock = new SfxDock_Impl;
	pDock->bHide = sal_False;
	pDock->nType = pDockWin->GetType();
	pDock->bNewLine = bNewLine;
	pDock->pWin = pDockWin;

	DBG_ASSERT( nPos==0 || !bNewLine, "Falsche Paramenter!");
	if ( bNewLine )
		nPos = 0;

	// Das Fenster mu\s vor dem ersten Fenster eingef"ugt werden, das die
	// gleiche oder eine gr"o\sere Position hat als pDockWin.
	sal_uInt16 nCount = pDockArr->Count();

	// Wenn gar kein Fenster gefunden wird, wird als erstes eingef"ugt
	sal_uInt16 nInsertPos = 0;
	for ( sal_uInt16 n=0; n<nCount; n++ )
	{
		SfxDock_Impl *pD = (*pDockArr)[n];

		if (pD->pWin)
		{
			// Ein angedocktes Fenster wurde gefunden
			// Wenn kein geeignetes Fenster hinter der gew"unschten Einf"ugeposition
			// gefunden wird, wird am Ende eingef"ugt
			nInsertPos = nCount;
			sal_uInt16 nL=0, nP=0;
			GetWindowPos( pD->pWin, nL, nP );

			if ( (nL == nLine && nP == nPos) || nL > nLine )
			{
				DBG_ASSERT( nL == nLine || bNewLine || nPos > 0, "Falsche Parameter!" );
				if ( nL == nLine && nPos == 0 && !bNewLine )
				{
					DBG_ASSERT(pD->bNewLine, "Keine neue Zeile?");

					// Das Fenster wird auf nPos==0 eingeschoben
					pD->bNewLine = sal_False;
					pDock->bNewLine = sal_True;
				}

				nInsertPos = n;
				break;
			}
		}
	}

	pDockArr->Insert(pDock, nInsertPos);
	InsertWindow_Impl( pDock, rSize, nLine, nPos, bNewLine );
	SaveConfig_Impl();
}

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

void SfxSplitWindow::InsertWindow_Impl( SfxDock_Impl* pDock,
						const Size& rSize,
						sal_uInt16 nLine, sal_uInt16 nPos, sal_Bool bNewLine)

/*  [Beschreibung]

	F"ugt ein DockingWindow ein und veranla\st die Neuberechnung der Gr"o\se
	des Splitwindows.
*/

{
	SfxDockingWindow* pDockWin = pDock->pWin;

	sal_uInt16 nItemBits = pDockWin->GetWinBits_Impl();

	long nWinSize, nSetSize;
	if ( IsHorizontal() )
	{
		nWinSize = rSize.Width();
		nSetSize = rSize.Height();
	}
	else
	{
		nSetSize = rSize.Width();
		nWinSize = rSize.Height();
	}

	pDock->nSize = nWinSize;

    DeactivateUpdateMode* pDeactivateUpdateMode = new DeactivateUpdateMode( *this );

	if ( bNewLine || nLine == GetItemCount( 0 ) )
	{
		// Es soll nicht in eine vorhandene Zeile eingef"ugt werden, sondern
		// eine neue erzeugt werden

		sal_uInt16 nId = 1;
		for ( sal_uInt16 n=0; n<GetItemCount(0); n++ )
		{
			if ( GetItemId(n) >= nId )
				nId = GetItemId(n)+1;
		}

		// Eine neue nLine-te Zeile erzeugen
		sal_uInt16 nBits = nItemBits;
		if ( GetAlign() == WINDOWALIGN_TOP || GetAlign() == WINDOWALIGN_BOTTOM )
			nBits |= SWIB_COLSET;
		InsertItem( nId, nSetSize, nLine, 0, nBits );
	}

	// In Zeile mit Position nLine das Fenster einf"ugen
	// ItemWindowSize auf "Prozentual" setzen, da SV dann das Umgr"o\sern
	// so macht, wie man erwartet; "Pixel" macht eigentlich nur Sinn, wenn
	// auch Items mit prozentualen oder relativen Gr"o\sen dabei sind.
	nItemBits |= SWIB_PERCENTSIZE;
	bLocked = sal_True;
	sal_uInt16 nSet = GetItemId( nLine );
	InsertItem( pDockWin->GetType(), pDockWin, nWinSize, nPos, nSet, nItemBits );

	// Splitwindows werden im SFX einmal angelegt und beim Einf"ugen des ersten
	// DockingWindows sichtbar gemacht.
	if ( GetItemCount( 0 ) == 1 && GetItemCount( 1 ) == 1 )
	{
		// Das Neuarrangieren am WorkWindow und ein Show() auf das SplitWindow
		// wird vom SfxDockingwindow veranla\st (->SfxWorkWindow::ConfigChild_Impl)
		if ( !bPinned && !IsFloatingMode() )
		{
			bPinned = sal_True;
			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
			pEmptyWin->bFadeIn = sal_False;
			SetPinned_Impl( sal_False );
			pEmptyWin->Actualize();
            DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
			pWorkWin->ArrangeChilds_Impl();
			if ( bFadeIn )
				FadeIn();
		}
		else
		{
			sal_Bool bFadeIn = ( pEmptyWin->nState & 2 ) != 0;
			pEmptyWin->bFadeIn = sal_False;
			pEmptyWin->Actualize();
#ifdef DBG_UTIL
            if ( !bPinned || !pEmptyWin->bFadeIn )
            {
                DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering empty Splitwindow" );
            }
            else
            {
                DBG_TRACE( "SfxSplitWindow::InsertWindow_Impl - registering real Splitwindow" );
            }
#endif
			pWorkWin->RegisterChild_Impl( *GetSplitWindow(), eAlign, sal_True )->nVisible = CHILD_VISIBLE;
			pWorkWin->ArrangeChilds_Impl();
			if ( bFadeIn )
				FadeIn();
		}

		pWorkWin->ShowChilds_Impl();
	}

    delete pDeactivateUpdateMode;
    bLocked = sal_False;

    // workaround insuffiency of <SplitWindow> regarding dock layouting:
    // apply FIXED item size as 'original' item size to improve layouting of undock-dock-cycle of a window
    {
        std::vector< std::pair< sal_uInt16, long > > aNewOrgSizes;
        // get FIXED item sizes
        sal_uInt16 nCount = pDockArr->Count();
        for ( sal_uInt16 n=0; n<nCount; n++ )
        {
            SfxDock_Impl *pD = (*pDockArr)[n];
            if ( pD->pWin )
            {
                const sal_uInt16 nId = pD->nType;
                const long nSize    = GetItemSize( nId, SWIB_FIXED );
                aNewOrgSizes.push_back( std::pair< sal_uInt16, long >( nId, nSize ) );
            }
        }
        // apply new item sizes
        DeactivateUpdateMode aDeactivateUpdateMode( *this );
        for ( sal_uInt16 i = 0; i < aNewOrgSizes.size(); ++i )
        {
            SetItemSize( aNewOrgSizes[i].first, aNewOrgSizes[i].second );
        }
    }
}

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

void SfxSplitWindow::RemoveWindow( SfxDockingWindow* pDockWin, sal_Bool bHide )

/*  [Beschreibung]

	Entfernt ein DockingWindow. Wenn es das letzte war, wird das SplitWindow
	gehidet.
*/
{
	sal_uInt16 nSet = GetSet( pDockWin->GetType() );

	// Splitwindows werden im SFX einmal angelegt und nach dem Entfernen
	// des letzten DockingWindows unsichtbar gemacht.
	if ( GetItemCount( nSet ) == 1 && GetItemCount( 0 ) == 1 )
	{
		// Das Neuarrangieren am WorkWindow wird vom SfxDockingwindow
		// veranla\st!
		Hide();
		pEmptyWin->aTimer.Stop();
        sal_uInt16 nRealState = pEmptyWin->nState;
		FadeOut_Impl();
		pEmptyWin->Hide();
#ifdef DBG_UTIL
        if ( !bPinned || !pEmptyWin->bFadeIn )
        {
            DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing empty Splitwindow" );
        }
        else
        {
            DBG_TRACE( "SfxSplitWindow::RemoveWindow - releasing real Splitwindow" );
        }
#endif
		pWorkWin->ReleaseChild_Impl( *GetSplitWindow() );
		pEmptyWin->nState = nRealState;
		pWorkWin->ArrangeAutoHideWindows( this );
	}

	SfxDock_Impl *pDock=0;
	sal_uInt16 nCount = pDockArr->Count();
	for ( sal_uInt16 n=0; n<nCount; n++ )
	{
		pDock = (*pDockArr)[n];
		if ( pDock->nType == pDockWin->GetType() )
		{
			pDock->pWin = 0;
			pDock->bHide = bHide;
			break;
		}
	}

	// Fenster removen, und wenn es das letzte der Zeile war, auch die Zeile
	// ( Zeile = ItemSet )
    DeactivateUpdateMode* pDeactivateUpdateMode = new DeactivateUpdateMode( *this );
    bLocked = sal_True;

	RemoveItem( pDockWin->GetType() );

	if ( nSet && !GetItemCount( nSet ) )
		RemoveItem( nSet );

    delete pDeactivateUpdateMode;
    bLocked = sal_False;
};

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

sal_Bool SfxSplitWindow::GetWindowPos( const SfxDockingWindow* pWindow,
										sal_uInt16& rLine, sal_uInt16& rPos ) const
/*  [Beschreibung]

	Liefert die Id des Itemsets und die des Items f"ur das "ubergebene
	DockingWindow in der alten Zeilen/Spalten-Bezeichnung zur"uck.
*/

{
	sal_uInt16 nSet = GetSet ( pWindow->GetType() );
	if ( nSet == SPLITWINDOW_ITEM_NOTFOUND )
		return sal_False;

	rPos  = GetItemPos( pWindow->GetType(), nSet );
	rLine = GetItemPos( nSet );
	return sal_True;
}

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

sal_Bool SfxSplitWindow::GetWindowPos( const Point& rTestPos,
									  sal_uInt16& rLine, sal_uInt16& rPos ) const
/*  [Beschreibung]

	Liefert die Id des Itemsets und die des Items f"ur das DockingWindow
	an der "ubergebenen Position in der alten Zeilen/Spalten-Bezeichnung
	zur"uck.
*/

{
	sal_uInt16 nId = GetItemId( rTestPos );
	if ( nId == 0 )
		return sal_False;

	sal_uInt16 nSet = GetSet ( nId );
	rPos  = GetItemPos( nId, nSet );
	rLine = GetItemPos( nSet );
	return sal_True;
}

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

sal_uInt16 SfxSplitWindow::GetLineCount() const

/*  [Beschreibung]

	Liefert die Zeilenzahl = Zahl der Sub-Itemsets im Root-Set.
*/
{
	return GetItemCount( 0 );
}

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

long SfxSplitWindow::GetLineSize( sal_uInt16 nLine ) const

/*  [Beschreibung]

	Liefert die "Zeilenh"ohe" des nLine-ten Itemsets.
*/
{
	sal_uInt16 nId = GetItemId( nLine );
	return GetItemSize( nId );
}

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

sal_uInt16 SfxSplitWindow::GetWindowCount( sal_uInt16 nLine ) const

/*  [Beschreibung]

	Liefert die
*/
{
	sal_uInt16 nId = GetItemId( nLine );
	return GetItemCount( nId );
}

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

sal_uInt16 SfxSplitWindow::GetWindowCount() const

/*  [Beschreibung]

	Liefert die Gesamtzahl aller Fenstert
*/
{
	return GetItemCount( 0 );
}

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

void SfxSplitWindow::Command( const CommandEvent& rCEvt )
{
	SplitWindow::Command( rCEvt );
}

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

IMPL_LINK( SfxSplitWindow, TimerHdl, Timer*, pTimer)
{
	if ( pTimer )
		pTimer->Stop();

	if ( CursorIsOverRect( sal_False ) || !pTimer )
	{
		// Wenn der Mauszeiger innerhalb des Fensters liegt, SplitWindow anzeigen
		// und Timer zum Schlie\sen aufsetzen
		pEmptyWin->bAutoHide = sal_True;
		if ( !IsVisible() )
			pEmptyWin->FadeIn();

		pEmptyWin->aLastPos = GetPointerPosPixel();
		pEmptyWin->aTimer.Start();
	}
	else if ( pEmptyWin->bAutoHide )
	{
		if ( GetPointerPosPixel() != pEmptyWin->aLastPos )
		{
			// Die Maus wurd innerhalb der Timerlaugzeit bewegt, also erst einmal
			// nichts tun
			pEmptyWin->aLastPos = GetPointerPosPixel();
			pEmptyWin->aTimer.Start();
			return 0L;
		}

		// Speziell f"ur TF_AUTOSHOW_ON_MOUSEMOVE :
		// Wenn das Fenster nicht sichtbar ist, gibt es nichts zu tun
		// (Benutzer ist einfach mit der Maus "uber pEmptyWin gefahren)
		if ( IsVisible() )
		{
			pEmptyWin->bEndAutoHide = sal_False;
			if ( !Application::IsInModalMode() &&
				  !PopupMenu::IsInExecute() &&
				  !pEmptyWin->bSplit && !HasChildPathFocus( sal_True ) )
			{
				// W"ahrend ein modaler Dialog oder ein Popupmenu offen sind
				// oder w"ahrend des Splittens auf keinen Fall zumachen; auch
				// solange eines der Children den Focus hat, bleibt das
				// das Fenster offen
				pEmptyWin->bEndAutoHide = sal_True;
			}

			if ( pEmptyWin->bEndAutoHide )
			{
				// Von mir aus kann Schlu\s sein mit AutoShow
				// Aber vielleicht will noch ein anderes SfxSplitWindow offen bleiben,
				// dann bleiben auch alle anderen offen
				if ( !pWorkWin->IsAutoHideMode( this ) )
				{
					FadeOut_Impl();
					pWorkWin->ArrangeAutoHideWindows( this );
				}
				else
				{
					pEmptyWin->aLastPos = GetPointerPosPixel();
					pEmptyWin->aTimer.Start();
				}
			}
			else
			{
				pEmptyWin->aLastPos = GetPointerPosPixel();
				pEmptyWin->aTimer.Start();
			}
		}
	}

	return 0L;
}

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

sal_Bool SfxSplitWindow::CursorIsOverRect( sal_Bool bForceAdding ) const
{
	sal_Bool bVisible = IsVisible();

	// Auch das kollabierte SplitWindow ber"ucksichtigen
	Point aPos = pEmptyWin->GetParent()->OutputToScreenPixel( pEmptyWin->GetPosPixel() );
	Size aSize = pEmptyWin->GetSizePixel();

	if ( bForceAdding )
	{
		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
		aPos.X() -= nPixel;
		aPos.Y() -= nPixel;
		aSize.Width() += 2 * nPixel;
		aSize.Height() += 2 * nPixel;
	}

	Rectangle aRect( aPos, aSize );

	if ( bVisible )
	{
		Point aVisPos = GetPosPixel();
		Size aVisSize = GetSizePixel();

		// Um +/- ein paar Pixel erweitern, sonst ist es zu nerv"os
		aVisPos.X() -= nPixel;
		aVisPos.Y() -= nPixel;
		aVisSize.Width() += 2 * nPixel;
		aVisSize.Height() += 2 * nPixel;

		Rectangle aVisRect( aVisPos, aVisSize );
		aRect = aRect.GetUnion( aVisRect );
	}

	if ( aRect.IsInside( OutputToScreenPixel( ((Window*)this)->GetPointerPosPixel() ) ) )
		return sal_True;
	return sal_False;
}

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

SplitWindow* SfxSplitWindow::GetSplitWindow()
{
	if ( !bPinned || !pEmptyWin->bFadeIn )
		return pEmptyWin;
	return this;
}

//-------------------------------------------------------------------------
sal_Bool SfxSplitWindow::IsFadeIn() const
{
	return pEmptyWin->bFadeIn;
}

sal_Bool SfxSplitWindow::IsAutoHide( sal_Bool bSelf ) const
{
	return bSelf ? pEmptyWin->bAutoHide && !pEmptyWin->bEndAutoHide : pEmptyWin->bAutoHide;
}

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

void SfxSplitWindow::SetPinned_Impl( sal_Bool bOn )
{
	if ( bPinned == bOn )
		return;

	bPinned = bOn;
	if ( GetItemCount( 0 ) == 0 )
		return;

	if ( !bOn )
	{
		pEmptyWin->nState |= 1;
		if ( pEmptyWin->bFadeIn )
		{
			// Ersatzfenster anmelden
            DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing real Splitwindow" );
			pWorkWin->ReleaseChild_Impl( *this );
			Hide();
			pEmptyWin->Actualize();
            DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering empty Splitwindow" );
			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
		}

		Point aPos( GetPosPixel() );
		aPos = GetParent()->OutputToScreenPixel( aPos );
		SetFloatingPos( aPos );
		SetFloatingMode( sal_True );
		GetFloatingWindow()->SetOutputSizePixel( GetOutputSizePixel() );

		if ( pEmptyWin->bFadeIn )
			Show();
	}
	else
	{
		pEmptyWin->nState &= ~1;
		SetOutputSizePixel( GetFloatingWindow()->GetOutputSizePixel() );
		SetFloatingMode( sal_False );

		if ( pEmptyWin->bFadeIn )
		{
			// Ersatzfenster abmelden
            DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - releasing empty Splitwindow" );
			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
			pEmptyWin->Hide();
            DBG_TRACE( "SfxSplitWindow::SetPinned_Impl - registering real Splitwindow" );
			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
		}
	}

	SetAutoHideState( !bPinned );
	pEmptyWin->SetAutoHideState( !bPinned );
}

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

void SfxSplitWindow::SetFadeIn_Impl( sal_Bool bOn )
{
	if ( bOn == pEmptyWin->bFadeIn )
		return;

	if ( GetItemCount( 0 ) == 0 )
		return;

	pEmptyWin->bFadeIn = bOn;
	if ( bOn )
	{
		pEmptyWin->nState |= 2;
		if ( IsFloatingMode() )
		{
			// FloatingWindow ist nicht sichtbar, also anzeigen
			pWorkWin->ArrangeAutoHideWindows( this );
			Show();
		}
		else
		{
            DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing empty Splitwindow" );
			pWorkWin->ReleaseChild_Impl( *pEmptyWin );
			pEmptyWin->Hide();
            DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering real Splitwindow" );
			pWorkWin->RegisterChild_Impl( *this, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
			pWorkWin->ArrangeChilds_Impl();
			pWorkWin->ShowChilds_Impl();
		}
	}
	else
	{
		pEmptyWin->bAutoHide = sal_False;
		pEmptyWin->nState &= ~2;
		if ( !IsFloatingMode() )
		{
			// Das Fenster "schwebt" nicht, soll aber ausgeblendet werden,
            DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - releasing real Splitwindow" );
			pWorkWin->ReleaseChild_Impl( *this );
			Hide();
			pEmptyWin->Actualize();
            DBG_TRACE( "SfxSplitWindow::SetFadeIn_Impl - registering empty Splitwindow" );
			pWorkWin->RegisterChild_Impl( *pEmptyWin, eAlign, sal_True )->nVisible = CHILD_VISIBLE;
			pWorkWin->ArrangeChilds_Impl();
			pWorkWin->ShowChilds_Impl();
			pWorkWin->ArrangeAutoHideWindows( this );
		}
		else
		{
			Hide();
			pWorkWin->ArrangeAutoHideWindows( this );
		}
	}
}

void SfxSplitWindow::AutoHide()
{
	// Wenn dieser Handler am "echten" SplitWindow aufgerufen wird, ist es
	// entweder angedockt und soll "schwebend" angezeigt werden oder umgekehrt
	if ( !bPinned )
	{
		// Es "schwebt", also wieder andocken
		SetPinned_Impl( sal_True );
		pWorkWin->ArrangeChilds_Impl();
	}
	else
	{
		// In den "Schwebezustand" bringen
		SetPinned_Impl( sal_False );
		pWorkWin->ArrangeChilds_Impl();
		pWorkWin->ArrangeAutoHideWindows( this );
	}

	pWorkWin->ShowChilds_Impl();
	SaveConfig_Impl();
}

void SfxSplitWindow::FadeOut_Impl()
{
    if ( pEmptyWin->aTimer.IsActive() )
    {
        pEmptyWin->bAutoHide = sal_False;
        pEmptyWin->aTimer.Stop();
    }

	SetFadeIn_Impl( sal_False );
	Show_Impl();
}

void SfxSplitWindow::FadeOut()
{
	FadeOut_Impl();
	SaveConfig_Impl();
}

void SfxSplitWindow::FadeIn()
{
	SetFadeIn_Impl( sal_True );
	Show_Impl();
}

void SfxSplitWindow::Show_Impl()
{
	sal_uInt16 nCount = pDockArr->Count();
	for ( sal_uInt16 n=0; n<nCount; n++ )
	{
		SfxDock_Impl *pDock = (*pDockArr)[n];
		if ( pDock->pWin )
			pDock->pWin->FadeIn( pEmptyWin->bFadeIn );
	}
}
/*
void SfxSplitWindow::Pin_Impl( sal_Bool bPin )
{
	if ( bPinned != bPin )
		AutoHide();
}
*/
sal_Bool SfxSplitWindow::ActivateNextChild_Impl( sal_Bool bForward )
{
	// Wenn kein pActive, auf erstes bzw. letztes Fenster gehen ( bei !bForward wird erst in der loop dekrementiert )
	sal_uInt16 nCount = pDockArr->Count();
	sal_uInt16 n = bForward ? 0 : nCount;

	// Wenn Focus innerhalb, dann ein Fenster vor oder zur"uck, wenn m"oglich
	if ( pActive )
	{
		// Aktives Fenster ermitteln
		for ( n=0; n<nCount; n++ )
		{
			SfxDock_Impl *pD = (*pDockArr)[n];
			if ( pD->pWin && pD->pWin->HasChildPathFocus() )
				break;
		}

		if ( bForward )
			// ein Fenster weiter ( wenn dann n>nCount, wird die Schleife unten gar nicht durchlaufen )
			n++;
	}

	if ( bForward )
	{
		// N"achstes Fenster suchen
		for ( sal_uInt16 nNext=n; nNext<nCount; nNext++ )
		{
			SfxDock_Impl *pD = (*pDockArr)[nNext];
			if ( pD->pWin )
			{
				pD->pWin->GrabFocus();
				return sal_True;
			}
		}
	}
	else
	{
		// Vorheriges Fenster suchen
		for ( sal_uInt16 nNext=n; nNext--; )
		{
			SfxDock_Impl *pD = (*pDockArr)[nNext];
			if ( pD->pWin )
			{
				pD->pWin->GrabFocus();
				return sal_True;
			}
		}
	}

	return sal_False;
}

void SfxSplitWindow::SetActiveWindow_Impl( SfxDockingWindow* pWin )
{
	pActive = pWin;
	pWorkWin->SetActiveChild_Impl( this );
}


