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

#define _SV_HEADBAR_CXX
#include <svtools/headbar.hxx>
#include <tools/debug.hxx>
#ifndef _TOOLS_LIST_HXX
#include <tools/list.hxx>
#endif

#ifndef _VCL_APP_HXX
#include <vcl/svapp.hxx>
#endif
#ifndef _VCL_HELP_HXX
#include <vcl/help.hxx>
#endif
#ifndef _VCL_IMAGE_HXX
#include <vcl/image.hxx>
#endif
#include <com/sun/star/accessibility/XAccessible.hpp>

#include <com/sun/star/accessibility/AccessibleRole.hpp>
#include <vclxaccessibleheaderbar.hxx>
// =======================================================================

struct ImplHeadItem
{
	sal_uInt16				mnId;
	HeaderBarItemBits	mnBits;
	long				mnSize;
	rtl::OString		maHelpId;
	Image				maImage;
	XubString			maOutText;
	XubString			maText;
	XubString			maHelpText;
	void*				mpUserData;
};

DECLARE_LIST( ImplHeadItemList, ImplHeadItem* )

// =======================================================================

#define HEAD_ARROWSIZE1 			4
#define HEAD_ARROWSIZE2 			7

#define HEADERBAR_TEXTOFF			2
#define HEADERBAR_ARROWOFF			5
#define HEADERBAR_SPLITOFF			3

#define HEADERBAR_DRAGOFF			4
#define HEADERBAR_DRAGOUTOFF		15

#define HEAD_HITTEST_ITEM			((sal_uInt16)0x0001)
#define HEAD_HITTEST_DIVIDER		((sal_uInt16)0x0002)

// =======================================================================

void HeaderBar::ImplInit( WinBits nWinStyle )
{
	mpItemList		= new ImplHeadItemList;
	mnBorderOff1	= 0;
	mnBorderOff2	= 0;
	mnOffset		= 0;
	mnDX			= 0;
	mnDY			= 0;
	mnDragSize		= 0;
	mnStartPos		= 0;
	mnDragPos		= 0;
	mnMouseOff		= 0;
	mnCurItemId 	= 0;
	mnItemDragPos	= HEADERBAR_ITEM_NOTFOUND;
	mbDrag			= sal_False;
	mbItemDrag		= sal_False;
	mbOutDrag		= sal_False;
	mbItemMode		= sal_False;

	m_pVCLXHeaderBar = NULL;
	// StyleBits auswerten
	if ( nWinStyle & WB_DRAG )
		mbDragable = sal_True;
	else
		mbDragable = sal_False;
	if ( nWinStyle & WB_BUTTONSTYLE )
		mbButtonStyle = sal_True;
	else
		mbButtonStyle = sal_False;
	if ( nWinStyle & WB_BORDER )
	{
		mnBorderOff1 = 1;
		mnBorderOff2 = 1;
	}
	else
	{
		if ( nWinStyle & WB_BOTTOMBORDER )
			mnBorderOff2 = 1;
	}

	ImplInitSettings( sal_True, sal_True, sal_True );
	//SetAccessibleRole(com::sun::star::accessibility::AccessibleRole::COLUMN_HEADER);	
}

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

HeaderBar::HeaderBar( Window* pParent, WinBits nWinStyle ) :
	Window( pParent, nWinStyle & WB_3DLOOK )
{
	ImplInit( nWinStyle );
	SetSizePixel( CalcWindowSizePixel() );
}

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

HeaderBar::HeaderBar( Window* pParent, const ResId& rResId ) :
	Window( pParent, rResId )
{
	ImplInit( rResId.GetWinBits() );
}

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

HeaderBar::~HeaderBar()
{
	// Alle Items loeschen
	ImplHeadItem* pItem = mpItemList->First();
	while ( pItem )
	{
		delete pItem;
		pItem = mpItemList->Next();
	}

	delete mpItemList;
}

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

void HeaderBar::ImplInitSettings( sal_Bool bFont,
								  sal_Bool bForeground, sal_Bool bBackground )
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();

	if ( bFont )
	{
		Font aFont;
		aFont = rStyleSettings.GetToolFont();
		if ( IsControlFont() )
			aFont.Merge( GetControlFont() );
		SetZoomedPointFont( aFont );
	}

	if ( bForeground || bFont )
	{
		Color aColor;
		if ( IsControlForeground() )
			aColor = GetControlForeground();
		else
			aColor = rStyleSettings.GetButtonTextColor();
		SetTextColor( aColor );
		SetTextFillColor();
	}

	if ( bBackground )
	{
		Color aColor;
		if ( IsControlBackground() )
			aColor = GetControlBackground();
		else
			aColor = rStyleSettings.GetFaceColor();
		SetBackground( aColor );
	}
}

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

long HeaderBar::ImplGetItemPos( sal_uInt16 nPos ) const
{
	long nX = -mnOffset;
	for ( sal_uInt16 i = 0; i < nPos; i++ )
		nX += mpItemList->GetObject( i )->mnSize;
	return nX;
}

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

Rectangle HeaderBar::ImplGetItemRect( sal_uInt16 nPos ) const
{
	Rectangle aRect( ImplGetItemPos( nPos ), 0, 0, mnDY-1 );
	aRect.Right() = aRect.Left() + mpItemList->GetObject( nPos )->mnSize - 1;
	// Gegen Ueberlauf auf einigen Systemen testen
	if ( aRect.Right() > 16000 )
		aRect.Right() = 16000;
	return aRect;
}

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

sal_uInt16 HeaderBar::ImplHitTest( const Point& rPos,
							   long& nMouseOff, sal_uInt16& nPos ) const
{
	ImplHeadItem*	pItem;
	sal_uInt16			nCount = (sal_uInt16)mpItemList->Count();
	sal_Bool			bLastFixed = sal_True;
	long			nX = -mnOffset;

	for ( sal_uInt16 i = 0; i < nCount; i++ )
	{
		pItem = mpItemList->GetObject( i );

		if ( rPos.X() < (nX+pItem->mnSize) )
		{
			sal_uInt16 nMode;

			if ( !bLastFixed && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
			{
				nMode = HEAD_HITTEST_DIVIDER;
				nPos = i-1;
				nMouseOff = rPos.X()-nX+1;
			}
			else
			{
				nPos = i;

				if ( !(pItem->mnBits & HIB_FIXED) && (rPos.X() >= (nX+pItem->mnSize-HEADERBAR_SPLITOFF)) )
				{
					nMode = HEAD_HITTEST_DIVIDER;
					nMouseOff = rPos.X()-(nX+pItem->mnSize);
				}
				else
				{
					nMode = HEAD_HITTEST_ITEM;
					nMouseOff = rPos.X()-nX;
				}
			}

			return nMode;
		}

		if ( pItem->mnBits & HIB_FIXED )
			bLastFixed = sal_True;
		else
			bLastFixed = sal_False;

		nX += pItem->mnSize;
	}

	if ( !bLastFixed )
	{
		pItem = mpItemList->GetObject( nCount-1 );
		if ( (pItem->mnSize < 4)  && (rPos.X() < (nX+HEADERBAR_SPLITOFF)) )
		{
			nPos = nCount-1;
			nMouseOff = rPos.X()-nX+1;
			return HEAD_HITTEST_DIVIDER;
		}
	}

	return 0;
}

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

void HeaderBar::ImplInvertDrag( sal_uInt16 nStartPos, sal_uInt16 nEndPos )
{
	Rectangle aRect1 = ImplGetItemRect( nStartPos );
	Rectangle aRect2 = ImplGetItemRect( nEndPos );
	Point	  aStartPos = aRect1.Center();
	Point	  aEndPos = aStartPos;
	Rectangle aStartRect( aStartPos.X()-2, aStartPos.Y()-2,
						  aStartPos.X()+2, aStartPos.Y()+2 );

	if ( nEndPos > nStartPos )
	{
		aStartPos.X() += 3;
		aEndPos.X() = aRect2.Right()-6;
	}
	else
	{
		aStartPos.X() -= 3;
		aEndPos.X() = aRect2.Left()+6;
	}

	SetRasterOp( ROP_INVERT );
	DrawRect( aStartRect );
	DrawLine( aStartPos, aEndPos );
	if ( nEndPos > nStartPos )
	{
		DrawLine( Point( aEndPos.X()+1, aEndPos.Y()-3 ),
				  Point( aEndPos.X()+1, aEndPos.Y()+3 ) );
		DrawLine( Point( aEndPos.X()+2, aEndPos.Y()-2 ),
				  Point( aEndPos.X()+2, aEndPos.Y()+2 ) );
		DrawLine( Point( aEndPos.X()+3, aEndPos.Y()-1 ),
				  Point( aEndPos.X()+3, aEndPos.Y()+1 ) );
		DrawPixel( Point( aEndPos.X()+4, aEndPos.Y() ) );
	}
	else
	{
		DrawLine( Point( aEndPos.X()-1, aEndPos.Y()-3 ),
				  Point( aEndPos.X()-1, aEndPos.Y()+3 ) );
		DrawLine( Point( aEndPos.X()-2, aEndPos.Y()-2 ),
				  Point( aEndPos.X()-2, aEndPos.Y()+2 ) );
		DrawLine( Point( aEndPos.X()-3, aEndPos.Y()-1 ),
				  Point( aEndPos.X()-3, aEndPos.Y()+1 ) );
		DrawPixel( Point( aEndPos.X()-4, aEndPos.Y() ) );
	}
	SetRasterOp( ROP_OVERPAINT );
}

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

void HeaderBar::ImplDrawItem( OutputDevice* pDev,
							  sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
							  const Rectangle& rItemRect,
							  const Rectangle* pRect,
							  sal_uLong )
{
	Rectangle aRect = rItemRect;

	// Wenn kein Platz, dann brauchen wir auch nichts ausgeben
	if ( aRect.GetWidth() <= 1 )
		return;

	// Feststellen, ob Rectangle ueberhaupt sichtbar
	if ( pRect )
	{
		if ( aRect.Right() < pRect->Left() )
			return;
		else if ( aRect.Left() > pRect->Right() )
			return;
	}
	else
	{
		if ( aRect.Right() < 0 )
			return;
		else if ( aRect.Left() > mnDX )
			return;
	}

	ImplHeadItem*			pItem  = mpItemList->GetObject( nPos );
	HeaderBarItemBits		nBits = pItem->mnBits;
	const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();

	// Border muss nicht gemalt werden
	aRect.Top() 	+= mnBorderOff1;
	aRect.Bottom()	-= mnBorderOff2;

	// Hintergrund loeschen
	if ( !pRect || bDrag )
	{
		if ( bDrag )
		{
			pDev->SetLineColor();
			pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
			pDev->DrawRect( aRect );
		}
		else
			pDev->DrawWallpaper( aRect, GetBackground() );
	}

	// Trennlinie malen
	pDev->SetLineColor( rStyleSettings.GetDarkShadowColor() );
	pDev->DrawLine( Point( aRect.Right(), aRect.Top() ),
					Point( aRect.Right(), aRect.Bottom() ) );

	// ButtonStyle malen
    // avoid 3D borders
    Color aSelectionTextColor( COL_TRANSPARENT );
    if( bHigh )
        DrawSelectionBackground( aRect, 1, sal_True, sal_False, sal_False, &aSelectionTextColor );
	else if ( !mbButtonStyle || (nBits & HIB_FLAT) )
        DrawSelectionBackground( aRect, 0, sal_True, sal_False, sal_False, &aSelectionTextColor );

	// Wenn kein Platz, dann brauchen wir auch nichts ausgeben
	if ( aRect.GetWidth() < 1 )
		return;

	// Positionen und Groessen berechnen und Inhalt ausgeben
	pItem->maOutText = pItem->maText;
	Size aImageSize = pItem->maImage.GetSizePixel();
	Size aTxtSize( pDev->GetTextWidth( pItem->maOutText ), 0  );
	if ( pItem->maOutText.Len() )
		aTxtSize.Height() = pDev->GetTextHeight();
	long nArrowWidth = 0;
	if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
		nArrowWidth = HEAD_ARROWSIZE2+HEADERBAR_ARROWOFF;

	// Wenn kein Platz fuer Image, dann nicht ausgeben
	long nTestHeight = aImageSize.Height();
	if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
		nTestHeight += aTxtSize.Height();
	if ( (aImageSize.Width() > aRect.GetWidth()) || (nTestHeight > aRect.GetHeight()) )
	{
		aImageSize.Width() = 0;
		aImageSize.Height() = 0;
	}

	// Text auf entsprechende Laenge kuerzen
	sal_Bool bLeftText = sal_False;
	long nMaxTxtWidth = aRect.GetWidth()-(HEADERBAR_TEXTOFF*2)-nArrowWidth;
	if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
		nMaxTxtWidth -= aImageSize.Width();
	long nTxtWidth = aTxtSize.Width();
	if ( nTxtWidth > nMaxTxtWidth )
	{
		bLeftText = sal_True;
		// 3 == Len of "..."
		pItem->maOutText.AppendAscii( "..." );
		do
		{
			pItem->maOutText.Erase( pItem->maOutText.Len()-3-1, 1 );
			nTxtWidth = pDev->GetTextWidth( pItem->maOutText );
		}
		while ( (nTxtWidth > nMaxTxtWidth) && (pItem->maOutText.Len() > 3) );
		if ( pItem->maOutText.Len() == 3 )
		{
			nTxtWidth = 0;
			pItem->maOutText.Erase();
		}
	}

	// Text/Imageposition berechnen
	long nTxtPos;
	if ( !bLeftText && (nBits & HIB_RIGHT) )
	{
		nTxtPos = aRect.Right()-nTxtWidth-HEADERBAR_TEXTOFF;
		if ( nBits & HIB_RIGHTIMAGE )
			nTxtPos -= aImageSize.Width();
	}
	else if ( !bLeftText && (nBits & HIB_CENTER) )
	{
		long nTempWidth = nTxtWidth;
		if ( nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE) )
			nTempWidth += aImageSize.Width();
		nTxtPos = aRect.Left()+(aRect.GetWidth()-nTempWidth)/2;
		if ( nBits & HIB_LEFTIMAGE )
			nTxtPos += aImageSize.Width();
		if ( nArrowWidth )
		{
			if ( nTxtPos+nTxtWidth+nArrowWidth >= aRect.Right() )
			{
				nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
				if ( nBits & HIB_LEFTIMAGE )
					nTxtPos += aImageSize.Width();
			}
		}
	}
	else
	{
		nTxtPos = aRect.Left()+HEADERBAR_TEXTOFF;
		if ( nBits & HIB_LEFTIMAGE )
			nTxtPos += aImageSize.Width();
		if ( nBits & HIB_RIGHT )
			nTxtPos += nArrowWidth;
	}

	// TextPosition berechnen
	long nTxtPosY = 0;
	if ( pItem->maOutText.Len() || (nArrowWidth && aTxtSize.Height()) )
	{
		if ( nBits & HIB_TOP )
		{
			nTxtPosY = aRect.Top();
			if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
				nTxtPosY += aImageSize.Height();
		}
		else if ( nBits & HIB_BOTTOM )
			nTxtPosY = aRect.Bottom()-aTxtSize.Height();
		else
		{
			long nTempHeight = aTxtSize.Height();
			if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
				nTempHeight += aImageSize.Height();
			nTxtPosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
			if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
				nTxtPosY += aImageSize.Height();
		}
	}

	// Text ausgebeben
	if ( pItem->maOutText.Len() )
	{
        if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
        {
            pDev->Push( PUSH_TEXTCOLOR );
            pDev->SetTextColor( aSelectionTextColor );
        }
		if ( IsEnabled() )
			pDev->DrawText( Point( nTxtPos, nTxtPosY ), pItem->maOutText );
		else
			pDev->DrawCtrlText( Point( nTxtPos, nTxtPosY ), pItem->maOutText, 0, STRING_LEN, TEXT_DRAW_DISABLE );
        if( aSelectionTextColor != Color( COL_TRANSPARENT ) )
            pDev->Pop();
	}

	// Wenn Image vorhanden, Position berechnen und ausgeben
	long nImagePosY = 0;
	if ( aImageSize.Width() && aImageSize.Height() )
	{
		long nImagePos = nTxtPos;
		if ( nBits & HIB_LEFTIMAGE )
		{
			nImagePos -= aImageSize.Width();
			if ( nBits & HIB_RIGHT )
				nImagePos -= nArrowWidth;
		}
		else if ( nBits & HIB_RIGHTIMAGE )
		{
			nImagePos += nTxtWidth;
			if ( !(nBits & HIB_RIGHT) )
				nImagePos += nArrowWidth;
		}
		else
		{
			if ( nBits & HIB_RIGHT )
				nImagePos = aRect.Right()-aImageSize.Width();
			else if ( nBits & HIB_CENTER )
				nImagePos = aRect.Left()+(aRect.GetWidth()-aImageSize.Width())/2;
			else
				nImagePos = aRect.Left()+HEADERBAR_TEXTOFF;
		}

		if ( nBits & HIB_TOP )
			nImagePosY = aRect.Top();
		else if ( nBits & HIB_BOTTOM )
		{
			nImagePosY = aRect.Bottom()-aImageSize.Height();
			if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
				nImagePosY -= aTxtSize.Height();
		}
		else
		{
			long nTempHeight = aImageSize.Height();
			if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) )
				nTempHeight += aTxtSize.Height();
			nImagePosY = aRect.Top()+((aRect.GetHeight()-nTempHeight)/2);
		}
		if ( nImagePos+aImageSize.Width() <= aRect.Right() )
		{
			sal_uInt16 nStyle = 0;
			if ( !IsEnabled() )
				nStyle |= IMAGE_DRAW_DISABLE;
			pDev->DrawImage( Point( nImagePos, nImagePosY ), pItem->maImage, nStyle );
		}
	}

	if ( nBits & (HIB_UPARROW | HIB_DOWNARROW) )
	{
		long nArrowX = nTxtPos;
		if ( nBits & HIB_RIGHT )
			nArrowX -= nArrowWidth;
		else
			nArrowX += nTxtWidth+HEADERBAR_ARROWOFF;
		if ( !(nBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && !pItem->maText.Len() )
		{
			if ( nBits & HIB_RIGHT )
				nArrowX -= aImageSize.Width();
			else
				nArrowX += aImageSize.Width();
		}

		// Feststellen, ob Platz genug ist, das Item zu malen
		sal_Bool bDraw = sal_True;
		if ( nArrowX < aRect.Left()+HEADERBAR_TEXTOFF )
			bDraw = sal_False;
		else if ( nArrowX+HEAD_ARROWSIZE2 > aRect.Right() )
			bDraw = sal_False;

		if ( bDraw )
		{
			long nArrowY;
			if ( aTxtSize.Height() )
				nArrowY = nTxtPosY+(aTxtSize.Height()/2);
			else if ( aImageSize.Width() && aImageSize.Height() )
				nArrowY = nImagePosY+(aImageSize.Height()/2);
			else
			{
				if ( nBits & HIB_TOP )
					nArrowY = aRect.Top()+1;
				else if ( nBits & HIB_BOTTOM )
					nArrowY = aRect.Bottom()-HEAD_ARROWSIZE2-1;
				else
					nArrowY = aRect.Top()+((aRect.GetHeight()-HEAD_ARROWSIZE2)/2);;
			}
			nArrowY -= HEAD_ARROWSIZE1-1;
			if ( nBits & HIB_DOWNARROW )
			{
				pDev->SetLineColor( rStyleSettings.GetLightColor() );
				pDev->DrawLine( Point( nArrowX, nArrowY ),
								Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
				pDev->DrawLine( Point( nArrowX, nArrowY ),
								Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ) );
				pDev->SetLineColor( rStyleSettings.GetShadowColor() );
				pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE1, nArrowY+HEAD_ARROWSIZE2 ),
								Point( nArrowX+HEAD_ARROWSIZE2, nArrowY ) );
			}
			else
			{
				pDev->SetLineColor( rStyleSettings.GetLightColor() );
				pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
								Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
				pDev->SetLineColor( rStyleSettings.GetShadowColor() );
				pDev->DrawLine( Point( nArrowX, nArrowY+HEAD_ARROWSIZE2 ),
								Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ) );
				pDev->DrawLine( Point( nArrowX+HEAD_ARROWSIZE2, nArrowY+HEAD_ARROWSIZE2 ),
								Point( nArrowX+HEAD_ARROWSIZE1, nArrowY ) );
			}
		}
	}

	// Gegebenenfalls auch UserDraw aufrufen
	if ( nBits & HIB_USERDRAW )
	{
		Region aRegion( aRect );
		if ( pRect )
			aRegion.Intersect( *pRect );
		pDev->SetClipRegion( aRegion );
		UserDrawEvent aODEvt( pDev, aRect, pItem->mnId );
		UserDraw( aODEvt );
		pDev->SetClipRegion();
	}
}

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

void HeaderBar::ImplDrawItem( sal_uInt16 nPos, sal_Bool bHigh, sal_Bool bDrag,
							  const Rectangle* pRect )
{
	Rectangle aRect = ImplGetItemRect( nPos );
	ImplDrawItem( this, nPos, bHigh, bDrag, aRect, pRect, 0 );
}

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

void HeaderBar::ImplUpdate( sal_uInt16 nPos, sal_Bool bEnd, sal_Bool bDirect )
{
	if ( IsVisible() && IsUpdateMode() )
	{
		if ( !bDirect )
		{
			Rectangle	aRect;
			sal_uInt16		nItemCount = (sal_uInt16)(mpItemList->Count());
			if ( nPos < nItemCount )
				aRect = ImplGetItemRect( nPos );
			else
			{
				aRect.Bottom() = mnDY-1;
				if ( nItemCount )
					aRect.Left() = ImplGetItemRect( nItemCount-1 ).Right();
			}
			if ( bEnd )
				aRect.Right() = mnDX-1;
			aRect.Top() 	+= mnBorderOff1;
			aRect.Bottom()	-= mnBorderOff2;
			Invalidate( aRect );
		}
		else
		{
			for ( sal_uInt16 i = nPos; i < mpItemList->Count(); i++ )
				ImplDrawItem( i );
			if ( bEnd )
			{
				Rectangle aRect = ImplGetItemRect( (sal_uInt16)mpItemList->Count() );
				aRect.Left()  = aRect.Right();
				aRect.Right() = mnDX-1;
				if ( aRect.Left() < aRect.Right() )
				{
					aRect.Top() 	+= mnBorderOff1;
					aRect.Bottom()	-= mnBorderOff2;
					Erase( aRect );
				}
			}
		}
	}
}

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

void HeaderBar::ImplStartDrag( const Point& rMousePos, sal_Bool bCommand )
{
	sal_uInt16	nPos;
	sal_uInt16	nHitTest = ImplHitTest( rMousePos, mnMouseOff, nPos );
	if ( nHitTest )
	{
		mbDrag = sal_False;
		ImplHeadItem* pItem = mpItemList->GetObject( nPos );
		if ( nHitTest & HEAD_HITTEST_DIVIDER )
			mbDrag = sal_True;
		else
		{
			if ( ((pItem->mnBits & HIB_CLICKABLE) && !(pItem->mnBits & HIB_FLAT)) ||
				 (mbDragable && !(pItem->mnBits & HIB_FIXEDPOS)) )
			{
				mbItemMode = sal_True;
				mbDrag = sal_True;
				if ( bCommand )
				{
					if ( mbDragable )
						mbItemDrag = sal_True;
					else
					{
						mbItemMode = sal_False;
						mbDrag = sal_False;
					}
				}
			}
			else
			{
				if ( !bCommand )
				{
					mnCurItemId = pItem->mnId;
					Select();
					mnCurItemId = 0;
				}
			}
		}

		if ( mbDrag )
		{
			mbOutDrag = sal_False;
			mnCurItemId = pItem->mnId;
			mnItemDragPos = nPos;
			StartTracking();
			mnStartPos = rMousePos.X()-mnMouseOff;
			mnDragPos = mnStartPos;
			StartDrag();
			if ( mbItemMode )
				ImplDrawItem( nPos, sal_True, mbItemDrag );
			else
			{
				Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
				ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
			}
		}
		else
			mnMouseOff = 0;
	}
}

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

void HeaderBar::ImplDrag( const Point& rMousePos )
{
	sal_Bool	bNewOutDrag;
	sal_uInt16	nPos = GetItemPos( mnCurItemId );

	mnDragPos = rMousePos.X()-mnMouseOff;
	if ( mbItemMode )
	{
		Rectangle aItemRect = ImplGetItemRect( nPos );
		if ( aItemRect.IsInside( rMousePos ) )
			bNewOutDrag = sal_False;
		else
			bNewOutDrag = sal_True;

		// Evt. ItemDrag anschalten
		if ( bNewOutDrag && mbDragable && !mbItemDrag &&
			 !(mpItemList->GetObject(nPos)->mnBits & HIB_FIXEDPOS) )
		{
			if ( (rMousePos.Y() >= aItemRect.Top()) && (rMousePos.Y() <= aItemRect.Bottom()) )
			{
				mbItemDrag = sal_True;
				ImplDrawItem( nPos, sal_True, mbItemDrag );
			}
		}

		sal_uInt16 nOldItemDragPos = mnItemDragPos;
		if ( mbItemDrag )
		{
			if ( (rMousePos.Y() < -HEADERBAR_DRAGOUTOFF) || (rMousePos.Y() > mnDY+HEADERBAR_DRAGOUTOFF) )
				bNewOutDrag = sal_True;
			else
				bNewOutDrag = sal_False;

			if ( bNewOutDrag )
				mnItemDragPos = HEADERBAR_ITEM_NOTFOUND;
			else
			{
				sal_uInt16 nTempId = GetItemId( Point( rMousePos.X(), 2 ) );
				if ( nTempId )
					mnItemDragPos = GetItemPos( nTempId );
				else
				{
					if ( rMousePos.X() <= 0 )
						mnItemDragPos = 0;
					else
						mnItemDragPos = GetItemCount()-1;
				}

				// Nicht verschiebbare Items aussparen
				if ( mnItemDragPos < nPos )
				{
					while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
							(mnItemDragPos < nPos) )
						mnItemDragPos++;
				}
				else if ( mnItemDragPos > nPos )
				{
					while ( (mpItemList->GetObject(mnItemDragPos)->mnBits & HIB_FIXEDPOS) &&
							(mnItemDragPos > nPos) )
						mnItemDragPos--;
				}
			}

			if ( (mnItemDragPos != nOldItemDragPos) &&
				 (nOldItemDragPos != nPos) &&
				 (nOldItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
			{
				ImplInvertDrag( nPos, nOldItemDragPos );
				ImplDrawItem( nOldItemDragPos );
			}
		}

		if ( bNewOutDrag != mbOutDrag )
			ImplDrawItem( nPos, !bNewOutDrag, mbItemDrag );

		if ( mbItemDrag  )
		{
			if ( (mnItemDragPos != nOldItemDragPos) &&
				 (mnItemDragPos != nPos) &&
				 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
			{
				ImplDrawItem( mnItemDragPos, sal_False, sal_True );
				ImplInvertDrag( nPos, mnItemDragPos );
			}
		}

		mbOutDrag = bNewOutDrag;
	}
	else
	{
		Rectangle aItemRect = ImplGetItemRect( nPos );
		if ( mnDragPos < aItemRect.Left() )
			mnDragPos = aItemRect.Left();
		if ( (mnDragPos < 0) || (mnDragPos > mnDX-1) )
			HideTracking();
		else
		{
			Rectangle aSizeRect( mnDragPos, 0, mnDragPos, mnDragSize+mnDY );
			ShowTracking( aSizeRect, SHOWTRACK_SPLIT );
		}
	}

	Drag();
}

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

void HeaderBar::ImplEndDrag( sal_Bool bCancel )
{
	HideTracking();

	if ( bCancel || mbOutDrag )
	{
		if ( mbItemMode && (!mbOutDrag || mbItemDrag) )
		{
			sal_uInt16 nPos = GetItemPos( mnCurItemId );
			ImplDrawItem( nPos );
		}

		mnCurItemId = 0;
	}
	else
	{
		sal_uInt16 nPos = GetItemPos( mnCurItemId );
		if ( mbItemMode )
		{
			if ( mbItemDrag )
			{
				Pointer aPointer( POINTER_ARROW );
				SetPointer( aPointer );
				if ( (mnItemDragPos != nPos) &&
					 (mnItemDragPos != HEADERBAR_ITEM_NOTFOUND) )
				{
					ImplInvertDrag( nPos, mnItemDragPos );
					MoveItem( mnCurItemId, mnItemDragPos );
				}
				else
					ImplDrawItem( nPos );
			}
			else
			{
				Select();
				ImplUpdate( nPos );
			}
		}
		else
		{
			long nDelta = mnDragPos - mnStartPos;
			if ( nDelta )
			{
				ImplHeadItem* pItem = mpItemList->GetObject( nPos );
				pItem->mnSize += nDelta;
				ImplUpdate( nPos, sal_True );
			}
		}
	}

	mbDrag			= sal_False;
	EndDrag();
	mnCurItemId 	= 0;
	mnItemDragPos	= HEADERBAR_ITEM_NOTFOUND;
	mbOutDrag		= sal_False;
	mbItemMode		= sal_False;
	mbItemDrag		= sal_False;
}

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

void HeaderBar::MouseButtonDown( const MouseEvent& rMEvt )
{
	if ( rMEvt.IsLeft() )
	{
		if ( rMEvt.GetClicks() == 2 )
		{
			long	nTemp;
			sal_uInt16	nPos;
			sal_uInt16	nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp, nPos );
			if ( nHitTest )
			{
				ImplHeadItem* pItem = mpItemList->GetObject( nPos );
				if ( nHitTest & HEAD_HITTEST_DIVIDER )
					mbItemMode = sal_False;
				else
					mbItemMode = sal_True;
				mnCurItemId = pItem->mnId;
				DoubleClick();
				mbItemMode = sal_False;
				mnCurItemId = 0;
			}
		}
		else
			ImplStartDrag( rMEvt.GetPosPixel(), sal_False );
	}
}

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

void HeaderBar::MouseMove( const MouseEvent& rMEvt )
{
	long			nTemp1;
	sal_uInt16			nTemp2;
	PointerStyle	eStyle = POINTER_ARROW;
	sal_uInt16			nHitTest = ImplHitTest( rMEvt.GetPosPixel(), nTemp1, nTemp2 );

	if ( nHitTest & HEAD_HITTEST_DIVIDER )
		eStyle = POINTER_HSIZEBAR;
	Pointer aPtr( eStyle );
	SetPointer( aPtr );
}

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

void HeaderBar::Tracking( const TrackingEvent& rTEvt )
{
	Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();

	if ( rTEvt.IsTrackingEnded() )
		ImplEndDrag( rTEvt.IsTrackingCanceled() );
	else
		ImplDrag( aMousePos );
}

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

void HeaderBar::Paint( const Rectangle& rRect )
{
	if ( mnBorderOff1 || mnBorderOff2 )
	{
		SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
		if ( mnBorderOff1 )
			DrawLine( Point( 0, 0 ), Point( mnDX-1, 0 ) );
		if ( mnBorderOff2 )
			DrawLine( Point( 0, mnDY-1 ), Point( mnDX-1, mnDY-1 ) );
        // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
        if ( mnBorderOff1 && mnBorderOff2 )
        {
            DrawLine( Point( 0, 0 ), Point( 0, mnDY-1 ) );
            DrawLine( Point( mnDX-1, 0 ), Point( mnDX-1, mnDY-1 ) );
        }
	}

	sal_uInt16 nCurItemPos;
	if ( mbDrag )
		nCurItemPos = GetItemPos( mnCurItemId );
	else
		nCurItemPos = HEADERBAR_ITEM_NOTFOUND;
	sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count();
	for ( sal_uInt16 i = 0; i < nItemCount; i++ )
		ImplDrawItem( i, (i == nCurItemPos) ? sal_True : sal_False, sal_False, &rRect );
}

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

void HeaderBar::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
					  sal_uLong nFlags )
{
	Point		aPos  = pDev->LogicToPixel( rPos );
	Size		aSize = pDev->LogicToPixel( rSize );
	Rectangle	aRect( aPos, aSize );
	Font		aFont = GetDrawPixelFont( pDev );

	pDev->Push();
	pDev->SetMapMode();
	pDev->SetFont( aFont );
	if ( nFlags & WINDOW_DRAW_MONO )
		pDev->SetTextColor( Color( COL_BLACK ) );
	else
		pDev->SetTextColor( GetTextColor() );
	pDev->SetTextFillColor();

	if ( !(nFlags & WINDOW_DRAW_NOBACKGROUND) )
	{
		pDev->DrawWallpaper( aRect, GetBackground() );
		if ( mnBorderOff1 || mnBorderOff2 )
		{
			pDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
			if ( mnBorderOff1 )
				pDev->DrawLine( aRect.TopLeft(), Point( aRect.Right(), aRect.Top() ) );
			if ( mnBorderOff2 )
				pDev->DrawLine( Point( aRect.Left(), aRect.Bottom() ), Point( aRect.Right(), aRect.Bottom() ) );
            // #i40393# draw left and right border, if WB_BORDER was set in ImplInit()
            if ( mnBorderOff1 && mnBorderOff2 )
            {
                pDev->DrawLine( aRect.TopLeft(), Point( aRect.Left(), aRect.Bottom() ) );
                pDev->DrawLine( Point( aRect.Right(), aRect.Top() ), Point( aRect.Right(), aRect.Bottom() ) );                
            }
		}
	}

	Rectangle aItemRect( aRect );
//	  aItemRect.Bottom()--;
	sal_uInt16 nItemCount = (sal_uInt16)mpItemList->Count();
	for ( sal_uInt16 i = 0; i < nItemCount; i++ )
	{
		aItemRect.Left() = aRect.Left()+ImplGetItemPos( i );
		aItemRect.Right() = aItemRect.Left() + mpItemList->GetObject( i )->mnSize - 1;
		// Gegen Ueberlauf auf einigen Systemen testen
		if ( aItemRect.Right() > 16000 )
			aItemRect.Right() = 16000;
		Region aRegion( aRect );
		pDev->SetClipRegion( aRegion );
		ImplDrawItem( pDev, i, sal_False, sal_False, aItemRect, &aRect, nFlags );
		pDev->SetClipRegion();
	}

	pDev->Pop();
}

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

void HeaderBar::Resize()
{
	Size aSize = GetOutputSizePixel();
	if ( IsVisible() && (mnDY != aSize.Height()) )
		Invalidate();
	mnDX = aSize.Width();
	mnDY = aSize.Height();
}

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

void HeaderBar::Command( const CommandEvent& rCEvt )
{
	if ( rCEvt.IsMouseEvent() && (rCEvt.GetCommand() == COMMAND_STARTDRAG) && !mbDrag )
	{
		ImplStartDrag( rCEvt.GetMousePosPixel(), sal_True );
		return;
	}

	Window::Command( rCEvt );
}

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

void HeaderBar::RequestHelp( const HelpEvent& rHEvt )
{
	sal_uInt16 nItemId = GetItemId( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ) );
	if ( nItemId )
	{
		if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
		{
			Rectangle aItemRect = GetItemRect( nItemId );
			Point aPt = OutputToScreenPixel( aItemRect.TopLeft() );
			aItemRect.Left()   = aPt.X();
			aItemRect.Top()    = aPt.Y();
			aPt = OutputToScreenPixel( aItemRect.BottomRight() );
			aItemRect.Right()  = aPt.X();
			aItemRect.Bottom() = aPt.Y();

			XubString aStr = GetHelpText( nItemId );
			if ( !aStr.Len() || !(rHEvt.GetMode() & HELPMODE_BALLOON) )
			{
				ImplHeadItem* pItem = mpItemList->GetObject( GetItemPos( nItemId ) );
				// Wir zeigen die Quick-Hilfe nur an, wenn Text nicht
				// vollstaendig sichtbar, ansonsten zeigen wir den Hilfetext
				// an, wenn das Item keinen Text besitzt
				if ( pItem->maOutText != pItem->maText )
					aStr = pItem->maText;
				else if ( pItem->maText.Len() )
					aStr.Erase();
			}

			if ( aStr.Len() )
			{
				if ( rHEvt.GetMode() & HELPMODE_BALLOON )
					Help::ShowBalloon( this, aItemRect.Center(), aItemRect, aStr );
				else
					Help::ShowQuickHelp( this, aItemRect, aStr );
				return;
			}
		}
		else if ( rHEvt.GetMode() & HELPMODE_EXTENDED )
		{
		    rtl::OUString aHelpId( rtl::OStringToOUString( GetHelpId( nItemId ), RTL_TEXTENCODING_UTF8 ) );
			if ( aHelpId.getLength() )
			{
				// Wenn eine Hilfe existiert, dann ausloesen
				Help* pHelp = Application::GetHelp();
				if ( pHelp )
					pHelp->Start( aHelpId, this );
				return;
			}
		}
	}

	Window::RequestHelp( rHEvt );
}

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

void HeaderBar::StateChanged( StateChangedType nType )
{
	Window::StateChanged( nType );

	if ( nType == STATE_CHANGE_ENABLE )
		Invalidate();
	else if ( (nType == STATE_CHANGE_ZOOM) ||
			  (nType == STATE_CHANGE_CONTROLFONT) )
	{
		ImplInitSettings( sal_True, sal_False, sal_False );
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
	{
		ImplInitSettings( sal_False, sal_True, sal_False );
		Invalidate();
	}
	else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
	{
		ImplInitSettings( sal_False, sal_False, sal_True );
		Invalidate();
	}
}

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

void HeaderBar::DataChanged( const DataChangedEvent& rDCEvt )
{
	Window::DataChanged( rDCEvt );

	if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
		 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
		 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
		  (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
	{
		ImplInitSettings( sal_True, sal_True, sal_True );
		Invalidate();
	}
}

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

void HeaderBar::UserDraw( const UserDrawEvent& )
{
}

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

void HeaderBar::StartDrag()
{
	maStartDragHdl.Call( this );
}

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

void HeaderBar::Drag()
{
	maDragHdl.Call( this );
}

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

void HeaderBar::EndDrag()
{
	maEndDragHdl.Call( this );
}

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

void HeaderBar::Select()
{
	maSelectHdl.Call( this );
}

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

void HeaderBar::DoubleClick()
{
	maDoubleClickHdl.Call( this );
}

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

void HeaderBar::InsertItem( sal_uInt16 nItemId, const Image& rImage,
							long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
{
	DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
	DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
				"HeaderBar::InsertItem(): ItemId already exists" );

	// Item anlegen und in die Liste einfuegen
	ImplHeadItem* pItem = new ImplHeadItem;
	pItem->mnId 		= nItemId;
	pItem->mnBits		= nBits;
	pItem->mnSize		= nSize;
	pItem->maImage		= rImage;
	pItem->mpUserData	= 0;
	mpItemList->Insert( pItem, nPos );

	// Ausgabe updaten
	ImplUpdate( nPos, sal_True );
}

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

void HeaderBar::InsertItem( sal_uInt16 nItemId, const XubString& rText,
							long nSize, HeaderBarItemBits nBits, sal_uInt16 nPos )
{
	DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
	DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
				"HeaderBar::InsertItem(): ItemId already exists" );

	// Item anlegen und in die Liste einfuegen
	ImplHeadItem* pItem = new ImplHeadItem;
	pItem->mnId 		= nItemId;
	pItem->mnBits		= nBits;
	pItem->mnSize		= nSize;
	pItem->maText		= rText;
	pItem->mpUserData	= 0;
	mpItemList->Insert( pItem, nPos );

	// Ausgabe updaten
	ImplUpdate( nPos, sal_True );
}

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

void HeaderBar::InsertItem( sal_uInt16 nItemId,
							const Image& rImage, const XubString& rText,
							long nSize, HeaderBarItemBits nBits,
							sal_uInt16 nPos )
{
	DBG_ASSERT( nItemId, "HeaderBar::InsertItem(): ItemId == 0" );
	DBG_ASSERT( GetItemPos( nItemId ) == HEADERBAR_ITEM_NOTFOUND,
				"HeaderBar::InsertItem(): ItemId already exists" );

	// Item anlegen und in die Liste einfuegen
	ImplHeadItem* pItem = new ImplHeadItem;
	pItem->mnId 		= nItemId;
	pItem->mnBits		= nBits;
	pItem->mnSize		= nSize;
	pItem->maImage		= rImage;
	pItem->maText		= rText;
	pItem->mpUserData	= 0;
	mpItemList->Insert( pItem, nPos );

	// Ausgabe updaten
	ImplUpdate( nPos, sal_True );
}

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

void HeaderBar::RemoveItem( sal_uInt16 nItemId )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		ImplHeadItem* pItem = mpItemList->Remove( nPos );
		delete pItem;
		ImplUpdate( nPos, sal_True );
	}
}

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

void HeaderBar::MoveItem( sal_uInt16 nItemId, sal_uInt16 nNewPos )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		if ( nPos != nNewPos )
		{
			ImplHeadItem* pItem = mpItemList->Remove( nPos );
			if ( nNewPos < nPos )
				nPos = nNewPos;
			mpItemList->Insert( pItem, nNewPos );
			ImplUpdate( nPos, sal_True );
		}
	}
}

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

void HeaderBar::Clear()
{
	// Alle Items loeschen
	ImplHeadItem* pItem = mpItemList->First();
	while ( pItem )
	{
		delete pItem;
		pItem = mpItemList->Next();
	}
	mpItemList->Clear();

	ImplUpdate( 0, sal_True );
}

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

void HeaderBar::SetOffset( long nNewOffset )
{
	// Hier erstmal neu zeichnen, damit mit alten Offset noch das
	// richtige gemalt wird
	//Update();

	// Bereich verschieben
	Rectangle aRect( 0, mnBorderOff1, mnDX-1, mnDY-mnBorderOff1-mnBorderOff2-1 );
	long nDelta = mnOffset-nNewOffset;
	mnOffset = nNewOffset;
	Scroll( nDelta, 0, aRect );
}

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

sal_uInt16 HeaderBar::GetItemCount() const
{
	return (sal_uInt16)mpItemList->Count();
}

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

sal_uInt16 HeaderBar::GetItemPos( sal_uInt16 nItemId ) const
{
	ImplHeadItem* pItem = mpItemList->First();
	while ( pItem )
	{
		if ( pItem->mnId == nItemId )
			return (sal_uInt16)mpItemList->GetCurPos();
		pItem = mpItemList->Next();
	}

	return HEADERBAR_ITEM_NOTFOUND;
}

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

sal_uInt16 HeaderBar::GetItemId( sal_uInt16 nPos ) const
{
	ImplHeadItem* pItem = mpItemList->GetObject( nPos );
	if ( pItem )
		return pItem->mnId;
	else
		return 0;
}

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

sal_uInt16 HeaderBar::GetItemId( const Point& rPos ) const
{
	sal_uInt16 nPos = 0;
	while ( nPos < mpItemList->Count() )
	{
		if ( ImplGetItemRect( nPos ).IsInside( rPos ) )
			return GetItemId( nPos );

		nPos++;
	}

	return 0;
}

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

Rectangle HeaderBar::GetItemRect( sal_uInt16 nItemId ) const
{
	Rectangle aRect;
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		aRect = ImplGetItemRect( nPos );
	return aRect;
}

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

void HeaderBar::SetItemSize( sal_uInt16 nItemId, long nNewSize )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		ImplHeadItem* pItem = mpItemList->GetObject( nPos );
		if ( pItem->mnSize != nNewSize )
		{
			pItem->mnSize = nNewSize;
			ImplUpdate( nPos, sal_True );
		}
	}
}

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

long HeaderBar::GetItemSize( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		return mpItemList->GetObject( nPos )->mnSize;
	else
		return 0;
}

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

void HeaderBar::SetItemBits( sal_uInt16 nItemId, HeaderBarItemBits nNewBits )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		ImplHeadItem* pItem = mpItemList->GetObject( nPos );
		if ( pItem->mnBits != nNewBits )
		{
			pItem->mnBits = nNewBits;
			ImplUpdate( nPos );
		}
	}
}

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

HeaderBarItemBits HeaderBar::GetItemBits( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		return mpItemList->GetObject( nPos )->mnBits;
	else
		return 0;
}

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

void HeaderBar::SetItemData( sal_uInt16 nItemId, void* pNewData )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		mpItemList->GetObject( nPos )->mpUserData = pNewData;
		ImplUpdate( nPos );
	}
}

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

void* HeaderBar::GetItemData( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		return mpItemList->GetObject( nPos )->mpUserData;
	else
		return NULL;
}

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

void HeaderBar::SetItemImage( sal_uInt16 nItemId, const Image& rImage )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		mpItemList->GetObject( nPos )->maImage = rImage;
		ImplUpdate( nPos );
	}
}

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

Image HeaderBar::GetItemImage( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		return mpItemList->GetObject( nPos )->maImage;
	else
		return Image();
}

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

void HeaderBar::SetItemText( sal_uInt16 nItemId, const XubString& rText )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		mpItemList->GetObject( nPos )->maText = rText;
		ImplUpdate( nPos );
	}
}

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

XubString HeaderBar::GetItemText( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		return mpItemList->GetObject( nPos )->maText;
	else
		return String();
}

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

void HeaderBar::SetHelpText( sal_uInt16 nItemId, const XubString& rText )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		mpItemList->GetObject( nPos )->maHelpText = rText;
}

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

XubString HeaderBar::GetHelpText( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
	{
		ImplHeadItem* pItem = mpItemList->GetObject( nPos );
		if ( !pItem->maHelpText.Len() && pItem->maHelpId.getLength() )
		{
			Help* pHelp = Application::GetHelp();
			if ( pHelp )
				pItem->maHelpText = pHelp->GetHelpText( rtl::OStringToOUString( pItem->maHelpId, RTL_TEXTENCODING_UTF8 ), this );
		}

		return pItem->maHelpText;
	}
	else
		return XubString();
}

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

void HeaderBar::SetHelpId( sal_uInt16 nItemId, const rtl::OString& rHelpId )
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		mpItemList->GetObject( nPos )->maHelpId = rHelpId;
}

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

rtl::OString HeaderBar::GetHelpId( sal_uInt16 nItemId ) const
{
	sal_uInt16 nPos = GetItemPos( nItemId );
	rtl::OString aRet;
	if ( nPos != HEADERBAR_ITEM_NOTFOUND )
		aRet = mpItemList->GetObject( nPos )->maHelpId;
	return aRet;
}

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

Size HeaderBar::CalcWindowSizePixel() const
{
	long nMaxImageSize = 0;
	Size aSize( 0, GetTextHeight() );

	ImplHeadItem* pItem = mpItemList->First();
	while ( pItem )
	{
		// Image-Groessen beruecksichtigen
		long nImageHeight = pItem->maImage.GetSizePixel().Height();
		if ( !(pItem->mnBits & (HIB_LEFTIMAGE | HIB_RIGHTIMAGE)) && pItem->maText.Len() )
			nImageHeight += aSize.Height();
		if ( nImageHeight > nMaxImageSize )
			nMaxImageSize = nImageHeight;

		// Breite aufaddieren
		aSize.Width() += pItem->mnSize;

		pItem = mpItemList->Next();
	}

	if ( nMaxImageSize > aSize.Height() )
		aSize.Height() = nMaxImageSize;

	// Border aufaddieren
	if ( mbButtonStyle )
		aSize.Height() += 4;
	else
		aSize.Height() += 2;
	aSize.Height() += mnBorderOff1+mnBorderOff2;

	return aSize;
}

::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > HeaderBar::CreateAccessible()
{
	if ( !mxAccessible.is() )
	{
		if ( maCreateAccessibleHdl.IsSet() )
			maCreateAccessibleHdl.Call( this );

		if ( !mxAccessible.is() )
			mxAccessible = Window::CreateAccessible();
	}

	return mxAccessible;
}

void HeaderBar::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > _xAccessible )
{
    mxAccessible = _xAccessible;
}

::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > HeaderBar::GetComponentInterface( sal_Bool bCreate )
{
    ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xPeer 
		(Window::GetComponentInterface(false));
	if ( !xPeer.is() && bCreate )
    {
		::com::sun::star::awt::XWindowPeer* mxPeer = new VCLXHeaderBar(this);
		m_pVCLXHeaderBar = (VCLXHeaderBar*)(mxPeer);
		SetComponentInterface(mxPeer);
		return mxPeer;
    }
	else
		return xPeer;
}

