/**************************************************************
 * 
 * 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_vcl.hxx"
#include <vcl/settings.hxx>
#include <tools/poly.hxx>
#include <vcl/outdev.hxx>
#include <vcl/bmpacc.hxx>
#include <vcl/decoview.hxx>
#include <vcl/window.hxx>
#include <vcl/ctrl.hxx>

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

#define BUTTON_DRAW_FLATTEST	(BUTTON_DRAW_FLAT | 			\
								 BUTTON_DRAW_PRESSED |			\
								 BUTTON_DRAW_CHECKED |			\
								 BUTTON_DRAW_HIGHLIGHT)

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

static void ImplDrawSymbol( OutputDevice* pDev, const Rectangle& rRect,
							SymbolType eType  )
{
	// Groessen vorberechnen
	long	nMin	= Min( rRect.GetWidth(), rRect.GetHeight() );
	long	nSize	= nMin;

	if ( nMin & 0x01 )
		nMin--;
	Point	aCenter = rRect.Center();
	long	nCenterX = aCenter.X();
	long	nCenterY = aCenter.Y();
	long	n2 = nMin / 2;
	long	n4 = nMin / 4;
	long	nLeft;
	long	nTop;
	long	nRight;
	long	nBottom;
	long	nTemp;
	long	i;

	switch ( eType )
	{
		case SYMBOL_ARROW_UP:
			{
			if ( !(nMin & 0x01) )
			{
				n2--;
				n4--;
			}
			nTop = nCenterY-n2;
			nBottom = nCenterY;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nTop++;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			pDev->DrawRect( Rectangle( nCenterX-n4, nBottom,
									   nCenterX+n4, nBottom+n2 ) );
			}
			break;

		case SYMBOL_ARROW_DOWN:
			{
			if ( !(nMin & 0x01) )
			{
				n2--;
				n4--;
			}
			nTop = nCenterY;
			nBottom = nCenterY+n2;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nBottom--;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			pDev->DrawRect( Rectangle( nCenterX-n4, nTop-n2,
									   nCenterX+n4, nTop ) );
			}
			break;

		case SYMBOL_ARROW_LEFT:
			{
			if ( !(nMin & 0x01) )
			{
				n2--;
				n4--;
			}
			nLeft = nCenterX-n2;
			nRight = nCenterX;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			i = 1;
			while ( i <= n2 )
			{
				nLeft++;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				i++;
			}
			pDev->DrawRect( Rectangle( nRight, nCenterY-n4,
									   nRight+n2, nCenterY+n4 ) );
			}
			break;

		case SYMBOL_ARROW_RIGHT:
			{
			if ( !(nMin & 0x01) )
			{
				n2--;
				n4--;
			}
			nLeft = nCenterX;
			nRight = nCenterX+n2;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			i = 1;
			while ( i <= n2 )
			{
				nRight--;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				i++;
			}
			pDev->DrawRect( Rectangle( nLeft-n2, nCenterY-n4,
									   nLeft, nCenterY+n4 ) );
			}
			break;


		case SYMBOL_SPIN_UP:
			{
			if ( !(nMin & 0x01) )
				n2--;
			nTop = nCenterY-n4;
			nBottom = nTop+n2;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nTop++;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			}
			break;

		case SYMBOL_SPIN_DOWN:
			{
			if ( !(nMin & 0x01) )
				n2--;
			nTop = nCenterY-n4;
			nBottom = nTop+n2;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nBottom--;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			}
			break;

		case SYMBOL_SPIN_LEFT:
		case SYMBOL_FIRST:
		case SYMBOL_PREV:
		case SYMBOL_REVERSEPLAY:
			{
			if ( !(nMin & 0x01) )
				n2--;
			nLeft = nCenterX-n4;
			if ( eType == SYMBOL_FIRST )
				nLeft++;
			nRight = nLeft+n2;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			i = 1;
			while ( i <= n2 )
			{
				nLeft++;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				i++;
			}
			if ( eType == SYMBOL_FIRST )
			{
				pDev->DrawRect( Rectangle( nCenterX-n4-1, nCenterY-n2,
										   nCenterX-n4-1, nCenterY+n2 ) );
			}
			}
			break;

		case SYMBOL_SPIN_RIGHT:
		case SYMBOL_LAST:
		case SYMBOL_NEXT:
		case SYMBOL_PLAY:
			{
			if ( !(nMin & 0x01) )
				n2--;
			nLeft = nCenterX-n4;
			if ( eType == SYMBOL_LAST )
				nLeft--;
			nRight = nLeft+n2;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			i = 1;
			while ( i <= n2 )
			{
				nRight--;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				i++;
			}
			if ( eType == SYMBOL_LAST )
			{
				pDev->DrawRect( Rectangle( nCenterX+n4+1, nCenterY-n2,
										   nCenterX+n4+1, nCenterY+n2 ) );
			}
			}
			break;

		case SYMBOL_PAGEUP:
		case SYMBOL_PAGEDOWN:
		{
			if ( !( nSize & 0x01 ))
			{
				// An even rectangle size means we have to use a smaller size for 
				// our arrows as we want to use one pixel for the spearhead! Otherwise 
				// it will be clipped!
				nCenterX++;
				n2 = ( nMin-1 ) / 2;
				n4 = ( nMin-1 ) / 4;
			}

			nTop = nCenterY-n2;
			nBottom = nCenterY-1;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			pDev->DrawRect( Rectangle( nCenterX, nTop+n2+1, nCenterX, nBottom+n2+1 ) );
			i = 1;
			while ( i < n2 )
			{
				( eType == SYMBOL_PAGEUP ) ? nTop++ : nBottom--;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				pDev->DrawRect( Rectangle( nTemp, nTop+n2+1, nTemp, nBottom+n2+1 ) );
				i++;
			}
		}
		break;

		case SYMBOL_RADIOCHECKMARK:
		case SYMBOL_RECORD:
		{
			const long			nExt = ( n2 << 1 ) + 1;
			Bitmap				aBmp( Size( nExt, nExt ), 1 );
			BitmapWriteAccess*	pWAcc = aBmp.AcquireWriteAccess();

			if( pWAcc )
			{
				const Color aWhite( COL_WHITE );
				const Color aBlack( COL_BLACK );

				pWAcc->Erase( aWhite );
				pWAcc->SetLineColor( aBlack );
				pWAcc->SetFillColor( aBlack );
				pWAcc->DrawPolygon( Polygon( Point( n2, n2 ), n2, n2 ) );
				aBmp.ReleaseAccess( pWAcc );
				pDev->DrawMask( Point( nCenterX - n2, nCenterY - n2 ), aBmp, pDev->GetFillColor() );
			}
			else
				pDev->DrawPolygon( Polygon( Point( nCenterX, nCenterY ), n2, n2 ) );
		}
		break;

		case SYMBOL_STOP:
			{
			nLeft = nCenterX-n2;
			nRight = nCenterX+n2;
			nTop = nCenterY-n2;
			nBottom = nCenterY+n2;
			pDev->DrawRect( Rectangle( nLeft, nTop, nRight, nBottom ) );
			}
			break;

		case SYMBOL_PAUSE:
			{
			nLeft = nCenterX-n2;
			nRight = nCenterX+n2-1;
			nTop = nCenterY-n2;
			nBottom = nCenterY+n2;
			pDev->DrawRect( Rectangle( nLeft, nTop, nCenterX-2, nBottom ) );
			pDev->DrawRect( Rectangle( nCenterX+1, nTop, nRight, nBottom ) );
			}
			break;

		case SYMBOL_WINDSTART:
		case SYMBOL_WINDBACKWARD:
			{
			nLeft = nCenterX-n2+1;
			nRight = nCenterX;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			pDev->DrawRect( Rectangle( nLeft+n2, nCenterY, nRight+n2, nCenterY ) );
			i = 1;
			while ( i < n2 )
			{
				nLeft++;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
				i++;
			}
			if ( eType == SYMBOL_WINDSTART )
			{
				pDev->DrawRect( Rectangle( nCenterX-n2, nCenterY-n2,
										   nCenterX-n2, nCenterY+n2 ) );
			}
			}
			break;

		case SYMBOL_WINDEND:
		case SYMBOL_WINDFORWARD:
			{
			nLeft = nCenterX-n2;
			nRight = nCenterX-1;
			pDev->DrawRect( Rectangle( nLeft, nCenterY, nRight, nCenterY ) );
			pDev->DrawRect( Rectangle( nLeft+n2, nCenterY, nRight+n2, nCenterY ) );
			i = 1;
			while ( i < n2 )
			{
				nRight--;
				nTemp = nCenterY-i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
				nTemp = nCenterY+i;
				pDev->DrawRect( Rectangle( nLeft, nTemp, nRight, nTemp ) );
				pDev->DrawRect( Rectangle( nLeft+n2, nTemp, nRight+n2, nTemp ) );
				i++;
			}
			if ( eType == SYMBOL_WINDEND )
			{
				pDev->DrawRect( Rectangle( nCenterX+n2, nCenterY-n2,
										   nCenterX+n2, nCenterY+n2 ) );
			}
			}
			break;

		case SYMBOL_CLOSE:
			{
			Size aRectSize( 2, 1 );
			if ( nMin < 8 )
				aRectSize.Width() = 1;
			else if ( nMin > 20 )
				aRectSize.Width() = nMin/10;
			nLeft	= nCenterX-n2+1;
			nTop	= nCenterY-n2+1;
			nBottom = nCenterY-n2+nMin-aRectSize.Width()+1;
			i = 0;
			while ( i < nMin-aRectSize.Width()+1 )
			{
				pDev->DrawRect( Rectangle( Point( nLeft+i, nTop+i ), aRectSize ) );
				pDev->DrawRect( Rectangle( Point( nLeft+i, nBottom-i ), aRectSize ) );
				i++;
			}
			}
			break;

		case SYMBOL_ROLLUP:
		case SYMBOL_ROLLDOWN:
			{
			Rectangle aRect( nCenterX-n2, nCenterY-n2,
							 nCenterX+n2, nCenterY-n2+1 );
			pDev->DrawRect( aRect );
			if ( eType == SYMBOL_ROLLDOWN )
			{
				Rectangle aTempRect = aRect;
				aTempRect.Bottom() = nCenterY+n2;
				aTempRect.Right() = aRect.Left();
				pDev->DrawRect( aTempRect );
				aTempRect.Left() = aRect.Right();
				aTempRect.Right() = aRect.Right();
				pDev->DrawRect( aTempRect );
				aTempRect.Top() = aTempRect.Bottom();
				aTempRect.Left() = aRect.Left();
				pDev->DrawRect( aTempRect );
			}
			}
			break;
		case SYMBOL_CHECKMARK:
			{
                // #106953# never mirror checkmarks
                sal_Bool bRTL = pDev->ImplHasMirroredGraphics() && pDev->IsRTLEnabled();
                Point aPos1( bRTL ? rRect.Right() : rRect.Left(),
                    rRect.Bottom() - rRect.GetHeight() / 3 );
                Point aPos2( bRTL ? rRect.Right() - rRect.GetWidth()/3 : rRect.Left() + rRect.GetWidth()/3,
                    rRect.Bottom() );
                Point aPos3( bRTL ? rRect.TopLeft() : rRect.TopRight() );
				Size aRectSize( 1, 2 );
				long nStepsY = aPos2.Y()-aPos1.Y();
				long nX = aPos1.X();
				long nY = aPos1.Y();
				long n;
				for ( n = 0; n <= nStepsY; n++ )
				{
                    if( bRTL )
                        nX--;
					pDev->DrawRect( Rectangle( Point( nX, nY++ ), aRectSize ) );
                    if( !bRTL )
					    nX++;
				}
				nStepsY = aPos2.Y()-aPos3.Y();
				nX = aPos2.X();
				nY = aPos2.Y();
				for ( n = 0; n <= nStepsY; n++ )
				{
                    if( bRTL )
					    if ( --nX < rRect.Left() )
						    break;
					pDev->DrawRect( Rectangle( Point( nX, nY-- ), aRectSize ) );
                    if( !bRTL )
					    if ( ++nX > rRect.Right() )
						    break;
				}
			}
			break;

		case SYMBOL_SPIN_UPDOWN:
			{
			nTop = nCenterY-n2-1;
			nBottom = nTop+n2;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nTop++;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			nTop = nCenterY+1;
			nBottom = nTop+n2;
			pDev->DrawRect( Rectangle( nCenterX, nTop, nCenterX, nBottom ) );
			i = 1;
			while ( i <= n2 )
			{
				nBottom--;
				nTemp = nCenterX-i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				nTemp = nCenterX+i;
				pDev->DrawRect( Rectangle( nTemp, nTop, nTemp, nBottom ) );
				i++;
			}
			}
			break;


		case SYMBOL_FLOAT:
			{
			Rectangle aRect( nCenterX-n2, nCenterY-n2+3,
							 nCenterX+n2-2, nCenterY-n2+4 );
			pDev->DrawRect( aRect );
			Rectangle aTempRect = aRect;
			aTempRect.Bottom() = nCenterY+n2;
			aTempRect.Right() = aRect.Left();
			pDev->DrawRect( aTempRect );
			aTempRect.Left() = aRect.Right();
			aTempRect.Right() = aRect.Right();
			pDev->DrawRect( aTempRect );
			aTempRect.Top() = aTempRect.Bottom();
			aTempRect.Left() = aRect.Left();
			pDev->DrawRect( aTempRect );
			aRect = Rectangle( nCenterX-n2+2, nCenterY-n2,
							 nCenterX+n2, nCenterY-n2+1 );
			pDev->DrawRect( aRect );
			aTempRect = aRect;
			aTempRect.Bottom() = nCenterY+n2-3;
			aTempRect.Right() = aRect.Left();
			pDev->DrawRect( aTempRect );
			aTempRect.Left() = aRect.Right();
			aTempRect.Right() = aRect.Right();
			pDev->DrawRect( aTempRect );
			aTempRect.Top() = aTempRect.Bottom();
			aTempRect.Left() = aRect.Left();
			pDev->DrawRect( aTempRect );
			}
			break;
		case SYMBOL_DOCK:
			{
			Rectangle aRect( nCenterX-n2, nCenterY-n2,
							 nCenterX+n2, nCenterY-n2 );
			pDev->DrawRect( aRect );
			Rectangle aTempRect = aRect;
			aTempRect.Bottom() = nCenterY+n2;
			aTempRect.Right() = aRect.Left();
			pDev->DrawRect( aTempRect );
			aTempRect.Left() = aRect.Right();
			aTempRect.Right() = aRect.Right();
			pDev->DrawRect( aTempRect );
			aTempRect.Top() = aTempRect.Bottom();
			aTempRect.Left() = aRect.Left();
			pDev->DrawRect( aTempRect );
			}
			break;
		case SYMBOL_HIDE:
			{
			long nExtra = nMin / 8;
			Rectangle aRect( nCenterX-n2+nExtra, nCenterY+n2-1,
							 nCenterX+n2-nExtra, nCenterY+n2 );
			pDev->DrawRect( aRect );
			}
			break;
	}
}

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

void DecorationView::DrawSymbol( const Rectangle& rRect, SymbolType eType,
								 const Color& rColor, sal_uInt16 nStyle )
{
	const StyleSettings&	rStyleSettings	= mpOutDev->GetSettings().GetStyleSettings();
	Rectangle				aRect			= mpOutDev->LogicToPixel( rRect );
	Color					aOldLineColor	= mpOutDev->GetLineColor();
	Color					aOldFillColor	= mpOutDev->GetFillColor();
	sal_Bool					bOldMapMode 	= mpOutDev->IsMapModeEnabled();
	mpOutDev->SetLineColor();
	mpOutDev->SetFillColor( rColor );
	mpOutDev->EnableMapMode( sal_False );

	if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
		 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
		nStyle |= BUTTON_DRAW_MONO;

	if ( nStyle & SYMBOL_DRAW_MONO )
	{
		if ( nStyle & SYMBOL_DRAW_DISABLE )
			mpOutDev->SetFillColor( Color( COL_GRAY ) );
		else
			mpOutDev->SetFillColor( Color( COL_BLACK ) );
	}
	else
	{
		if ( nStyle & SYMBOL_DRAW_DISABLE )
		{
			// Als Embosed ausgeben
			mpOutDev->SetFillColor( rStyleSettings.GetLightColor() );
			Rectangle aTempRect = aRect;
			aTempRect.Move( 1, 1 );
			ImplDrawSymbol( mpOutDev, aTempRect, eType );
			mpOutDev->SetFillColor( rStyleSettings.GetShadowColor() );
		}
		else
			mpOutDev->SetFillColor( rColor );
	}

	ImplDrawSymbol( mpOutDev, aRect, eType );

	mpOutDev->SetLineColor( aOldLineColor );
	mpOutDev->SetFillColor( aOldFillColor );
	mpOutDev->EnableMapMode( bOldMapMode );
}

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

void DecorationView::DrawFrame( const Rectangle& rRect,
								const Color& rLeftTopColor,
								const Color& rRightBottomColor )
{
	Rectangle	aRect			= mpOutDev->LogicToPixel( rRect );
	Color		aOldLineColor	= mpOutDev->GetLineColor();
	Color		aOldFillColor	= mpOutDev->GetFillColor();
	sal_Bool		bOldMapMode 	= mpOutDev->IsMapModeEnabled();
	mpOutDev->EnableMapMode( sal_False );
	mpOutDev->SetLineColor();
	mpOutDev->ImplDraw2ColorFrame( aRect, rLeftTopColor, rRightBottomColor );
	mpOutDev->SetLineColor( aOldLineColor );
	mpOutDev->SetFillColor( aOldFillColor );
	mpOutDev->EnableMapMode( bOldMapMode );
}

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

void DecorationView::DrawHighlightFrame( const Rectangle& rRect,
										 sal_uInt16 nStyle )
{
	const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();
	Color aLightColor = rStyleSettings.GetLightColor();
	Color aShadowColor = rStyleSettings.GetShadowColor();

	if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
		 (mpOutDev->GetOutDevType() == OUTDEV_PRINTER) )
	{
		aLightColor = Color( COL_BLACK );
		aShadowColor = Color( COL_BLACK );
	}
	else if ( nStyle & FRAME_HIGHLIGHT_TESTBACKGROUND )
	{
		Wallpaper aBackground = mpOutDev->GetBackground();
		if ( aBackground.IsBitmap() || aBackground.IsGradient() )
		{
			aLightColor = rStyleSettings.GetFaceColor();
			aShadowColor = Color( COL_BLACK );
		}
		else
		{
			Color aBackColor = aBackground.GetColor();
			if ( (aLightColor.GetColorError( aBackColor ) < 32) ||
				 (aShadowColor.GetColorError( aBackColor ) < 32) )
			{
				aLightColor = Color( COL_WHITE );
				aShadowColor = Color( COL_BLACK );

				if ( aLightColor.GetColorError( aBackColor ) < 32 )
					aLightColor.DecreaseLuminance( 64 );
				if ( aShadowColor.GetColorError( aBackColor ) < 32 )
					aShadowColor.IncreaseLuminance( 64 );
			}
		}
	}

	if ( (nStyle & FRAME_HIGHLIGHT_STYLE) == FRAME_HIGHLIGHT_IN )
	{
		Color aTempColor = aLightColor;
		aLightColor = aShadowColor;
		aShadowColor = aTempColor;
	}

	DrawFrame( rRect, aLightColor, aShadowColor );
}

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

static void ImplDrawDPILineRect( OutputDevice* pDev, Rectangle& rRect,
								 const Color* pColor, sal_Bool bRound = sal_False )
{
	long nLineWidth = pDev->ImplGetDPIX()/300;
	long nLineHeight = pDev->ImplGetDPIY()/300;
	if ( !nLineWidth )
		nLineWidth = 1;
	if ( !nLineHeight )
		nLineHeight = 1;

	if ( pColor )
	{
		if ( (nLineWidth == 1) && (nLineHeight == 1) )
		{
			pDev->SetLineColor( *pColor );
			pDev->SetFillColor();
            if( bRound )
            {
			    pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()), Point( rRect.Right()-1, rRect.Top()) );
			    pDev->DrawLine( Point( rRect.Left()+1, rRect.Bottom()), Point( rRect.Right()-1, rRect.Bottom()) );
			    pDev->DrawLine( Point( rRect.Left(), rRect.Top()+1), Point( rRect.Left(), rRect.Bottom()-1) );
			    pDev->DrawLine( Point( rRect.Right(), rRect.Top()+1), Point( rRect.Right(), rRect.Bottom()-1) );
            }
            else
			    pDev->DrawRect( rRect );
		}
		else
		{
			long nWidth = rRect.GetWidth();
			long nHeight = rRect.GetHeight();
			pDev->SetLineColor();
			pDev->SetFillColor( *pColor );
			pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nWidth, nLineHeight ) ) );
			pDev->DrawRect( Rectangle( rRect.TopLeft(), Size( nLineWidth, nHeight ) ) );
			pDev->DrawRect( Rectangle( Point( rRect.Left(), rRect.Bottom()-nLineHeight ),
									   Size( nWidth, nLineHeight ) ) );
			pDev->DrawRect( Rectangle( Point( rRect.Right()-nLineWidth, rRect.Top() ),
									   Size( nLineWidth, nHeight ) ) );
		}
	}

	rRect.Left()	+= nLineWidth;
	rRect.Top() 	+= nLineHeight;
	rRect.Right()	-= nLineWidth;
	rRect.Bottom()	-= nLineHeight;
}

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

static void ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect,
						   const StyleSettings& rStyleSettings, sal_uInt16 nStyle )
{
    // mask menu style
    sal_Bool bMenuStyle = (nStyle & FRAME_DRAW_MENU) ? sal_True : sal_False;
    nStyle &= ~FRAME_DRAW_MENU;

    Window *pWin = NULL;
    if( pDev->GetOutDevType() == OUTDEV_WINDOW )
        pWin = (Window*) pDev;

    // UseFlatBorders disables 3D style for all frames except menus
    // menus may use different border colors (eg on XP)
    // normal frames will be drawn using the shadow color 
    // whereas window frame borders will use black
    sal_Bool bFlatBorders = ( !bMenuStyle && rStyleSettings.GetUseFlatBorders() );

    // no flat borders for standard VCL controls (ie formcontrols that keep their classic look)
    // will not affect frame windows (like dropdowns)
    if( bFlatBorders && pWin && pWin->GetType() == WINDOW_BORDERWINDOW && (pWin != pWin->ImplGetFrameWindow()) )
    {
        // check for formcontrol, i.e., a control without NWF enabled
        Control *pControl = dynamic_cast< Control* >( pWin->GetWindow( WINDOW_CLIENT ) );
        if( pControl && pControl->IsNativeWidgetEnabled() )
            bFlatBorders = sal_True;
        else
            bFlatBorders = sal_False;
    }

    // no round corners for window frame borders
    sal_Bool bRound = (bFlatBorders && !(nStyle & FRAME_DRAW_WINDOWBORDER));

	if ( (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
		 (pDev->GetOutDevType() == OUTDEV_PRINTER) ||
         bFlatBorders )
		nStyle |= FRAME_DRAW_MONO;

	if ( nStyle & FRAME_DRAW_NODRAW )
	{
        sal_uInt16 nValueStyle = bMenuStyle ? nStyle | FRAME_DRAW_MENU : nStyle;
        if( pWin->GetType() == WINDOW_BORDERWINDOW )
            nValueStyle |= FRAME_DRAW_BORDERWINDOWBORDER;
        ImplControlValue aControlValue( nValueStyle );
		Rectangle aBound, aContent;
		Rectangle aNatRgn( rRect );
		if(pWin && pWin->GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
			aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) )
		{
			rRect = aContent;
		}
		else if ( nStyle & FRAME_DRAW_MONO )
			ImplDrawDPILineRect( pDev, rRect, NULL, bRound );
		else
		{
			sal_uInt16 nFrameStyle = nStyle & FRAME_DRAW_STYLE;

			if ( nFrameStyle == FRAME_DRAW_GROUP )
			{
				rRect.Left()	+= 2;
				rRect.Top() 	+= 2;
				rRect.Right()	-= 2;
				rRect.Bottom()	-= 2;
			}
			else if ( (nFrameStyle == FRAME_DRAW_IN) ||
					  (nFrameStyle == FRAME_DRAW_OUT) )
			{
				rRect.Left()++;
				rRect.Top()++;
				rRect.Right()--;
				rRect.Bottom()--;
			}
			else // FRAME_DRAW_DOUBLEIN || FRAME_DRAW_DOUBLEOUT
			{
				rRect.Left()	+= 2;
				rRect.Top() 	+= 2;
				rRect.Right()	-= 2;
				rRect.Bottom()	-= 2;
			}
		}
	}
	else
	{
		if( pWin && pWin->IsNativeControlSupported(CTRL_FRAME, PART_BORDER) )
        {
            sal_uInt16 nValueStyle = bMenuStyle ? nStyle | FRAME_DRAW_MENU : nStyle;
            if( pWin->GetType() == WINDOW_BORDERWINDOW )
                nValueStyle |= FRAME_DRAW_BORDERWINDOWBORDER;
            ImplControlValue aControlValue( nValueStyle );
            Rectangle aBound, aContent;
            Rectangle aNatRgn( rRect );
            if(	pWin->GetNativeControlRegion(CTRL_FRAME, PART_BORDER,
				aNatRgn, 0, aControlValue, rtl::OUString(), aBound, aContent) ) 
            {
                if( pWin->DrawNativeControl( CTRL_FRAME, PART_BORDER, aContent, CTRL_STATE_ENABLED,
                             aControlValue, rtl::OUString()) )
                {
                    rRect = aContent;
                    return;
                }
            }
        }

        if ( nStyle & FRAME_DRAW_MONO )
        {
            Color aColor = bRound ? rStyleSettings.GetShadowColor()
                                  : pDev->GetSettings().GetStyleSettings().GetMonoColor();
            // when the MonoColor wasn't set, check face color
            if (
                (bRound && aColor.IsDark()) ||
                (
                  (aColor == Color(COL_BLACK)) &&
                  (pDev->GetSettings().GetStyleSettings().GetFaceColor().IsDark())
                )
               )
            {
                aColor = Color( COL_WHITE );
            }
            ImplDrawDPILineRect( pDev, rRect, &aColor, bRound );
        }
		else
		{
			sal_uInt16 nFrameStyle = nStyle & FRAME_DRAW_STYLE;
			if ( nFrameStyle == FRAME_DRAW_GROUP )
			{
				pDev->SetFillColor();
				pDev->SetLineColor( rStyleSettings.GetLightColor() );
				rRect.Top()++;
				rRect.Left()++;
				pDev->DrawRect( rRect );
				rRect.Top()--;
				rRect.Left()--;
				pDev->SetLineColor( rStyleSettings.GetShadowColor() );
				rRect.Right()--;
				rRect.Bottom()--;
				pDev->DrawRect( rRect );
				rRect.Right()++;
				rRect.Bottom()++;
			}
			else
			{
				pDev->SetLineColor();

				if ( (nFrameStyle == FRAME_DRAW_IN) ||
					 (nFrameStyle == FRAME_DRAW_OUT) )
				{
					if ( nFrameStyle == FRAME_DRAW_IN )
					{
						pDev->ImplDraw2ColorFrame( rRect,
												   rStyleSettings.GetShadowColor(),
												   rStyleSettings.GetLightColor() );
					}
					else
					{
						pDev->ImplDraw2ColorFrame( rRect,
												   rStyleSettings.GetLightColor(),
												   rStyleSettings.GetShadowColor() );
					}

					rRect.Left()++;
					rRect.Top()++;
					rRect.Right()--;
					rRect.Bottom()--;
				}
				else // FRAME_DRAW_DOUBLEIN || FRAME_DRAW_DOUBLEOUT
				{
					if ( nFrameStyle == FRAME_DRAW_DOUBLEIN )
					{
                        if( bFlatBorders ) // no 3d effect
                            pDev->ImplDraw2ColorFrame( rRect,
												    rStyleSettings.GetShadowColor(),
												    rStyleSettings.GetShadowColor() );
                        else
						    pDev->ImplDraw2ColorFrame( rRect,
												    rStyleSettings.GetShadowColor(),
												    rStyleSettings.GetLightColor() );
					}
					else
					{
                        if( bMenuStyle )
						    pDev->ImplDraw2ColorFrame( rRect,
                                                   rStyleSettings.GetMenuBorderColor(),
												   rStyleSettings.GetDarkShadowColor() );
                        else
						    pDev->ImplDraw2ColorFrame( rRect,
                                                   bFlatBorders ? // no 3d effect
                                                   rStyleSettings.GetDarkShadowColor() :
												   rStyleSettings.GetLightBorderColor(),
												   rStyleSettings.GetDarkShadowColor() );
                                                   
					}

					rRect.Left()++;
					rRect.Top()++;
					rRect.Right()--;
					rRect.Bottom()--;

                    sal_Bool bDrawn = sal_True;
					if ( nFrameStyle == FRAME_DRAW_DOUBLEIN )
					{
                        if( bFlatBorders ) // no 3d effect
						    pDev->ImplDraw2ColorFrame( rRect,
												    rStyleSettings.GetFaceColor(),
												    rStyleSettings.GetFaceColor() );
                        else
						    pDev->ImplDraw2ColorFrame( rRect,
												    rStyleSettings.GetDarkShadowColor(),
												    rStyleSettings.GetLightBorderColor() );
					}
					else
					{
                        // flat menues have no shadow border
                        if( !bMenuStyle || !rStyleSettings.GetUseFlatMenues() )
						    pDev->ImplDraw2ColorFrame( rRect,
												    rStyleSettings.GetLightColor(),
												    rStyleSettings.GetShadowColor() );
                        else
                            bDrawn = sal_False;
					}
                    if( bDrawn )
                    {
					    rRect.Left()++;
					    rRect.Top()++;
					    rRect.Right()--;
					    rRect.Bottom()--;
                    }
				}
			}
		}
	}
}

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

Rectangle DecorationView::DrawFrame( const Rectangle& rRect, sal_uInt16 nStyle )
{
	Rectangle	aRect = rRect;
	sal_Bool		bOldMap = mpOutDev->IsMapModeEnabled();
	if ( bOldMap )
	{
		aRect = mpOutDev->LogicToPixel( aRect );
		mpOutDev->EnableMapMode( sal_False );
	}

	if ( !rRect.IsEmpty() )
	{
		if ( nStyle & FRAME_DRAW_NODRAW )
			 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
		else
		{
			 Color maOldLineColor  = mpOutDev->GetLineColor();
			 Color maOldFillColor  = mpOutDev->GetFillColor();
			 ImplDrawFrame( mpOutDev, aRect, mpOutDev->GetSettings().GetStyleSettings(), nStyle );
			 mpOutDev->SetLineColor( maOldLineColor );
			 mpOutDev->SetFillColor( maOldFillColor );
		}
	}

	if ( bOldMap )
	{
		mpOutDev->EnableMapMode( bOldMap );
		aRect = mpOutDev->PixelToLogic( aRect );
	}

	return aRect;
}

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

static void ImplDrawButton( OutputDevice* pDev, Rectangle& rRect,
							const StyleSettings& rStyleSettings, sal_uInt16 nStyle )
{
	Rectangle aFillRect = rRect;

	if ( nStyle & BUTTON_DRAW_MONO )
	{
		if ( !(nStyle & BUTTON_DRAW_NODRAW) )
		{
			Color aBlackColor( COL_BLACK );

			if ( nStyle & BUTTON_DRAW_DEFAULT )
				ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );

			ImplDrawDPILineRect( pDev, aFillRect, &aBlackColor );

			Size aBrdSize( 1, 1 );
			if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
			{
				MapMode aResMapMode( MAP_100TH_MM );
				aBrdSize = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
				if ( !aBrdSize.Width() )
					aBrdSize.Width() = 1;
				if ( !aBrdSize.Height() )
					aBrdSize.Height() = 1;
			}
			pDev->SetLineColor();
			pDev->SetFillColor( aBlackColor );
			Rectangle aRect1;
			Rectangle aRect2;
			aRect1.Left()	= aFillRect.Left();
			aRect1.Right()	= aFillRect.Right(),
			aRect2.Top()	= aFillRect.Top();
			aRect2.Bottom() = aFillRect.Bottom();
			if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
			{
				aRect1.Top()	= aFillRect.Top();
				aRect1.Bottom() = aBrdSize.Height()-1;
				aRect2.Left()	= aFillRect.Left();
				aRect2.Right()	= aFillRect.Left()+aBrdSize.Width()-1;
				aFillRect.Left() += aBrdSize.Width();
				aFillRect.Top()  += aBrdSize.Height();
			}
			else
			{
				aRect1.Top()	= aFillRect.Bottom()-aBrdSize.Height()+1;
				aRect1.Bottom() = aFillRect.Bottom();
				aRect2.Left()	= aFillRect.Right()-aBrdSize.Width()+1;
				aRect2.Right()	= aFillRect.Right(),
				aFillRect.Right()  -= aBrdSize.Width();
				aFillRect.Bottom() -= aBrdSize.Height();
			}
			pDev->DrawRect( aRect1 );
			pDev->DrawRect( aRect2 );
		}
	}
	else
	{
		if ( !(nStyle & BUTTON_DRAW_NODRAW) )
		{
			if ( nStyle & BUTTON_DRAW_DEFAULT )
			{
				Color aDefBtnColor = rStyleSettings.GetDarkShadowColor();
				ImplDrawDPILineRect( pDev, aFillRect, &aDefBtnColor );
			}
		}

		if ( !(nStyle & BUTTON_DRAW_NODRAW) )
		{
			pDev->SetLineColor();
			if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
			{
				pDev->SetFillColor( rStyleSettings.GetLightBorderColor() );
				pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Top(),
										   aFillRect.Left(), aFillRect.Bottom() ) );
				aFillRect.Left()++;
			}
			if ( (nStyle & BUTTON_DRAW_NOTOPLIGHTBORDER) &&
				 !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) )
			{
				pDev->SetFillColor( rStyleSettings.GetLightBorderColor() );
				pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Top(),
										   aFillRect.Right(), aFillRect.Top() ) );
				aFillRect.Top()++;
			}
			if ( (( (nStyle & BUTTON_DRAW_NOBOTTOMSHADOWBORDER) | BUTTON_DRAW_FLAT) == (BUTTON_DRAW_NOBOTTOMSHADOWBORDER | BUTTON_DRAW_FLAT)) &&
				 !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED | BUTTON_DRAW_HIGHLIGHT)) )
			{
				pDev->SetFillColor( rStyleSettings.GetDarkShadowColor() );
				pDev->DrawRect( Rectangle( aFillRect.Left(), aFillRect.Bottom(),
										   aFillRect.Right(), aFillRect.Bottom() ) );
				aFillRect.Bottom()--;
			}

			Color aColor1;
			Color aColor2;
			if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
			{
				aColor1 = rStyleSettings.GetDarkShadowColor();
				aColor2 = rStyleSettings.GetLightColor();
			}
			else
			{
				if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
					aColor1 = rStyleSettings.GetLightBorderColor();
				else
					aColor1 = rStyleSettings.GetLightColor();
				if ( (nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT )
					aColor2 = rStyleSettings.GetShadowColor();
				else
					aColor2 = rStyleSettings.GetDarkShadowColor();
			}
			pDev->ImplDraw2ColorFrame( aFillRect, aColor1, aColor2 );
			aFillRect.Left()++;
			aFillRect.Top()++;
			aFillRect.Right()--;
			aFillRect.Bottom()--;

			if ( !((nStyle & BUTTON_DRAW_FLATTEST) == BUTTON_DRAW_FLAT) )
			{
				if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
				{
					aColor1 = rStyleSettings.GetShadowColor();
					aColor2 = rStyleSettings.GetLightBorderColor();
				}
				else
				{
					if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
						aColor1 = rStyleSettings.GetLightColor();
					else
						aColor1 = rStyleSettings.GetLightBorderColor();
					aColor2 = rStyleSettings.GetShadowColor();
				}
				pDev->ImplDraw2ColorFrame( aFillRect, aColor1, aColor2 );
				aFillRect.Left()++;
				aFillRect.Top()++;
				aFillRect.Right()--;
				aFillRect.Bottom()--;
			}
		}
	}

	if ( !(nStyle & (BUTTON_DRAW_NOFILL | BUTTON_DRAW_NODRAW)) )
	{
		pDev->SetLineColor();
		if ( nStyle & BUTTON_DRAW_MONO )
		{
			// Hack: Auf Druckern wollen wir im MonoChrom-Modus trotzdem
			// erstmal graue Buttons haben
			if ( pDev->GetOutDevType() == OUTDEV_PRINTER )
				pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
			else
				pDev->SetFillColor( Color( COL_WHITE ) );
		}
		else
		{
			if ( nStyle & (BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW) )
				pDev->SetFillColor( rStyleSettings.GetCheckedColor() );
			else
				pDev->SetFillColor( rStyleSettings.GetFaceColor() );
		}
		pDev->DrawRect( aFillRect );
	}

	// Ein Border freilassen, der jedoch bei Default-Darstellung
	// mitbenutzt wird
	rRect.Left()++;
	rRect.Top()++;
	rRect.Right()--;
	rRect.Bottom()--;

	if ( nStyle & BUTTON_DRAW_NOLIGHTBORDER )
	{
		rRect.Left()++;
		rRect.Top()++;
	}
	else if ( nStyle & BUTTON_DRAW_NOLEFTLIGHTBORDER )
		rRect.Left()++;

	if ( nStyle & BUTTON_DRAW_PRESSED )
	{
		if ( (rRect.GetHeight() > 10) && (rRect.GetWidth() > 10) )
		{
			rRect.Left()	+= 4;
			rRect.Top() 	+= 4;
			rRect.Right()	-= 1;
			rRect.Bottom()	-= 1;
		}
		else
		{
			rRect.Left()	+= 3;
			rRect.Top() 	+= 3;
			rRect.Right()	-= 2;
			rRect.Bottom()	-= 2;
		}
	}
	else if ( nStyle & BUTTON_DRAW_CHECKED )
	{
		rRect.Left()	+= 3;
		rRect.Top() 	+= 3;
		rRect.Right()	-= 2;
		rRect.Bottom()	-= 2;
	}
	else
	{
		rRect.Left()	+= 2;
		rRect.Top() 	+= 2;
		rRect.Right()	-= 3;
		rRect.Bottom()	-= 3;
	}
}

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

Rectangle DecorationView::DrawButton( const Rectangle& rRect, sal_uInt16 nStyle )
{
	Rectangle	aRect = rRect;
	sal_Bool		bOldMap = mpOutDev->IsMapModeEnabled();
	if ( bOldMap )
	{
		aRect = mpOutDev->LogicToPixel( aRect );
		mpOutDev->EnableMapMode( sal_False );
	}

	if ( !rRect.IsEmpty() )
	{
		const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();

		if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
			nStyle |= BUTTON_DRAW_MONO;

		if ( nStyle & BUTTON_DRAW_NODRAW )
			 ImplDrawButton( mpOutDev, aRect, rStyleSettings, nStyle );
		else
		{
			 Color maOldLineColor  = mpOutDev->GetLineColor();
			 Color maOldFillColor  = mpOutDev->GetFillColor();
			 ImplDrawButton( mpOutDev, aRect, rStyleSettings, nStyle );
			 mpOutDev->SetLineColor( maOldLineColor );
			 mpOutDev->SetFillColor( maOldFillColor );
		}
	}

	if ( bOldMap )
	{
		mpOutDev->EnableMapMode( bOldMap );
		aRect = mpOutDev->PixelToLogic( aRect );
	}

	return aRect;
}

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

void DecorationView::DrawSeparator( const Point& rStart, const Point& rStop, bool bVertical )
{
    Point aStart( rStart ), aStop( rStop );
    const StyleSettings& rStyleSettings = mpOutDev->GetSettings().GetStyleSettings();

    mpOutDev->Push( PUSH_LINECOLOR );
    if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
        mpOutDev->SetLineColor( Color( COL_BLACK ) );
    else
        mpOutDev->SetLineColor( rStyleSettings.GetShadowColor() );
    
    mpOutDev->DrawLine( aStart, aStop );
    if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
    {
        mpOutDev->SetLineColor( rStyleSettings.GetLightColor() );
        if( bVertical )
        {
            aStart.X()++;
            aStop.X()++;
        }
        else
        {
            aStart.Y()++;
            aStop.Y()++;
        }
        mpOutDev->DrawLine( aStart, aStop );
    }
    mpOutDev->Pop();
}

