/**************************************************************
 *
 * 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.
 *
 *************************************************************/



#include "vcl/salnativewidgets.hxx"
#include "vcl/decoview.hxx"
#include "vcl/svapp.hxx"
#include "vcl/timer.hxx"

#include "aqua/salconst.h"
#include "aqua/salgdi.h"
#include "aqua/salnativewidgets.h"
#include "aqua/saldata.hxx"
#include "aqua/salframe.h"

#include "premac.h"
#include <Carbon/Carbon.h>
#include "postmac.h"

class AquaBlinker : public Timer
{
    AquaSalFrame*       mpFrame;
    Rectangle           maInvalidateRect;

    AquaBlinker( AquaSalFrame* pFrame, const Rectangle& rRect )
    : mpFrame( pFrame ), maInvalidateRect( rRect )
    {
        mpFrame->maBlinkers.push_back( this );
    }

    public:

    static void Blink( AquaSalFrame*, const Rectangle&, int nTimeout = 80 );

    virtual void Timeout()
    {
        Stop();
        if( AquaSalFrame::isAlive( mpFrame ) && mpFrame->mbShown )
        {
            mpFrame->maBlinkers.remove( this );
            mpFrame->SendPaintEvent( &maInvalidateRect );
        }
        delete this;
    }
};

void AquaBlinker::Blink( AquaSalFrame* pFrame, const Rectangle& rRect, int nTimeout )
{
    // prevent repeated paints from triggering themselves all the time
    for( std::list< AquaBlinker* >::const_iterator it = pFrame->maBlinkers.begin();
         it != pFrame->maBlinkers.end(); ++it )
    {
        if( (*it)->maInvalidateRect == rRect )
            return;
    }
    AquaBlinker* pNew = new AquaBlinker( pFrame, rRect );
    pNew->SetTimeout( nTimeout );
    pNew->Start();
}

ControlPart ImplgetCounterPart( ControlPart nPart )
{
    ControlPart nCounterPart = 0;
    switch (nPart)
    {
        case PART_BUTTON_UP:
            nCounterPart = PART_BUTTON_DOWN;
            break;
        case PART_BUTTON_DOWN:
            nCounterPart = PART_BUTTON_UP;
            break;
        case PART_BUTTON_LEFT:
            nCounterPart = PART_BUTTON_RIGHT;
            break;
        case PART_BUTTON_RIGHT:
            nCounterPart = PART_BUTTON_LEFT;
            break;
    }
    return nCounterPart;
}


// Helper returns an HIRect

static HIRect ImplGetHIRectFromRectangle(Rectangle aRect)
{
    HIRect aHIRect;
    aHIRect.origin.x = static_cast<float>(aRect.Left());
    aHIRect.origin.y = static_cast<float>(aRect.Top());
    aHIRect.size.width = static_cast<float>(aRect.GetWidth());
    aHIRect.size.height = static_cast<float>(aRect.GetHeight());
	return aHIRect;
}

static ThemeButtonValue ImplGetButtonValue( ButtonValue aButtonValue )
{
    switch( aButtonValue )
    {
        case BUTTONVALUE_ON:
            return kThemeButtonOn;
            break;

        case BUTTONVALUE_OFF:
            return kThemeButtonOff;
            break;

        case BUTTONVALUE_MIXED:
        case BUTTONVALUE_DONTKNOW:
        default:
            return kThemeButtonMixed;
            break;
    }
}

// the scrollbar arrows disappeared in OSX>=10.7
#define SCROLL_BUTTON_HEIGHT 0
#define SCROLL_BUTTON_WIDTH 0

static bool AquaGetScrollRect( /* TODO: int nScreen, */  ControlPart nPart,
	const Rectangle& rControlRect, Rectangle& rResultRect )
{
	bool bRetVal = true;
    rResultRect = rControlRect;

    switch( nPart )
    {
        case PART_BUTTON_UP:
			if( GetSalData()->mbIsScrollbarDoubleMax )
				rResultRect.Top() = rControlRect.Bottom() - 2*SCROLL_BUTTON_HEIGHT;
            rResultRect.Bottom() = rResultRect.Top() + SCROLL_BUTTON_HEIGHT;
            break;

        case PART_BUTTON_DOWN:
            rResultRect.Top() = rControlRect.Bottom() - SCROLL_BUTTON_HEIGHT;
            break;

        case PART_BUTTON_LEFT:
			if( GetSalData()->mbIsScrollbarDoubleMax )
				rResultRect.Left() = rControlRect.Right() - 2*SCROLL_BUTTON_WIDTH;
			rResultRect.Right() = rResultRect.Left() + SCROLL_BUTTON_WIDTH;
			break;

        case PART_BUTTON_RIGHT:
			rResultRect.Left() = rControlRect.Right() - SCROLL_BUTTON_WIDTH;
            break;

        case PART_TRACK_HORZ_AREA:
            rResultRect.Right() -= SCROLL_BUTTON_WIDTH + 1;
			if( GetSalData()->mbIsScrollbarDoubleMax )
				rResultRect.Right() -= SCROLL_BUTTON_WIDTH;
			else
				rResultRect.Left() += SCROLL_BUTTON_WIDTH + 1;
            break;

        case PART_TRACK_VERT_AREA:
            rResultRect.Bottom() -= SCROLL_BUTTON_HEIGHT + 1;
			if( GetSalData()->mbIsScrollbarDoubleMax )
				rResultRect.Bottom() -= SCROLL_BUTTON_HEIGHT;
			else
				rResultRect.Top() += SCROLL_BUTTON_HEIGHT + 1;
            break;
        case PART_THUMB_HORZ:
            if( GetSalData()->mbIsScrollbarDoubleMax )
            {
                rResultRect.Left() += 8;
                rResultRect.Right() += 6;
            }
            else
            {
                rResultRect.Left() += 4;
                rResultRect.Right() += 4;
            }
            break;
        case PART_THUMB_VERT:
            if( GetSalData()->mbIsScrollbarDoubleMax )
            {
                rResultRect.Top() += 8;
                rResultRect.Bottom() += 8;
            }
            else
            {
                rResultRect.Top() += 4;
                rResultRect.Bottom() += 4;
            }
            break;
        case PART_TRACK_HORZ_LEFT:
            if( GetSalData()->mbIsScrollbarDoubleMax )
                rResultRect.Right() += 8;
            else
                rResultRect.Right() += 4;
            break;
        case PART_TRACK_HORZ_RIGHT:
            if( GetSalData()->mbIsScrollbarDoubleMax )
                rResultRect.Left() += 6;
            else
                rResultRect.Left() += 4;
            break;
        case PART_TRACK_VERT_UPPER:
            if( GetSalData()->mbIsScrollbarDoubleMax )
                rResultRect.Bottom() += 8;
            else
                rResultRect.Bottom() += 4;
            break;
        case PART_TRACK_VERT_LOWER:
            if( GetSalData()->mbIsScrollbarDoubleMax )
                rResultRect.Top() += 8;
            else
                rResultRect.Top() += 4;
            break;
		default:
			bRetVal = false;
    }

	return bRetVal;
}

/*
 * IsNativeControlSupported()
 * --------------------------
 * Returns sal_True if the platform supports native
 * drawing of the control defined by nPart.
 *
 */
sal_Bool AquaSalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
{
    bool bOk = sal_False;

    // Native controls are now defaults
    // If you want to disable experimental native controls code,
    // just set the environment variable SAL_NO_NWF to something
    // and vcl controls will be used as default again.

    switch( nType )
    {
        case CTRL_PUSHBUTTON:
        case CTRL_RADIOBUTTON:
        case CTRL_CHECKBOX:
        case CTRL_LISTNODE:
            if( nPart == PART_ENTIRE_CONTROL )
                return true;
            break;

        case CTRL_SCROLLBAR:
            if( nPart == PART_DRAW_BACKGROUND_HORZ ||
                nPart == PART_DRAW_BACKGROUND_VERT ||
                nPart == PART_ENTIRE_CONTROL       ||
                nPart == HAS_THREE_BUTTONS )
                return true;
            break;

        case CTRL_SLIDER:
            if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
                return true;
            break;

        case CTRL_EDITBOX:
            if( nPart == PART_ENTIRE_CONTROL ||
                nPart == HAS_BACKGROUND_TEXTURE )
                return true;
            break;

        case CTRL_MULTILINE_EDITBOX:
            if( nPart == PART_ENTIRE_CONTROL ||
                nPart == HAS_BACKGROUND_TEXTURE )
                return true;
            break;

        case CTRL_SPINBOX:
            if( nPart == PART_ENTIRE_CONTROL ||
                nPart == PART_ALL_BUTTONS    ||
                nPart == HAS_BACKGROUND_TEXTURE )
                return true;
            break;

        case CTRL_SPINBUTTONS:
                return false;
            break;

		case CTRL_COMBOBOX:
            if( nPart == PART_ENTIRE_CONTROL ||
                nPart == HAS_BACKGROUND_TEXTURE )
                return true;
            break;

        case CTRL_LISTBOX:
            if( nPart == PART_ENTIRE_CONTROL    ||
                nPart == PART_WINDOW            ||
                nPart == HAS_BACKGROUND_TEXTURE ||
                nPart == PART_SUB_EDIT
                )
                return true;
            break;

        case CTRL_TAB_ITEM:
        case CTRL_TAB_PANE:
        case CTRL_TAB_BODY:  // see vcl/source/window/tabpage.cxx
        case CTRL_FIXEDBORDER:
            if( nPart == PART_ENTIRE_CONTROL ||
                nPart == PART_TABS_DRAW_RTL ||
                nPart == HAS_BACKGROUND_TEXTURE )
                return true;
            break;

        // when PART_BUTTON is used, toolbar icons are not highlighted when mouse rolls over.
        // More Aqua compliant
        case CTRL_TOOLBAR:
            if( nPart == PART_ENTIRE_CONTROL       ||
                nPart == PART_DRAW_BACKGROUND_HORZ ||
                nPart == PART_DRAW_BACKGROUND_VERT)
                return true;
            break;

        case  CTRL_WINDOW_BACKGROUND:
            if ( nPart == PART_BACKGROUND_WINDOW ||
                 nPart == PART_BACKGROUND_DIALOG )
                 return true;
            break;

        case CTRL_MENUBAR:
            if( nPart == PART_ENTIRE_CONTROL )
                return true;
            break;

        case CTRL_TOOLTIP: // ** TO DO
            #if 0
            if( nPart == PART_ENTIRE_CONTROL ) // we don't currently support the tooltip
                return true;
            #endif
            break;

        case CTRL_MENU_POPUP:
            if( nPart == PART_ENTIRE_CONTROL       ||
                nPart == PART_MENU_ITEM            ||
                nPart == PART_MENU_ITEM_CHECK_MARK ||
                nPart == PART_MENU_ITEM_RADIO_MARK)
                return true;
            break;
        case CTRL_PROGRESS:
        case CTRL_INTROPROGRESS:
            if( nPart == PART_ENTIRE_CONTROL )
                return true;
            break;
        case CTRL_FRAME:
            if( nPart == PART_BORDER )
                return true;
            break;
        case CTRL_LISTNET:
            if( nPart == PART_ENTIRE_CONTROL )
                return true;
            break;
    }

    return bOk;
}

/*
 * HitTestNativeControl()
 *
 *  If the return value is sal_True, bIsInside contains information whether
 *  aPos was or was not inside the native widget specified by the
 *  nType/nPart combination.
 */
sal_Bool AquaSalGraphics::hitTestNativeControl( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion,
					    const Point& rPos, sal_Bool& rIsInside )
{
    if ( nType == CTRL_SCROLLBAR )
    {
		Rectangle aRect;
		bool bValid = AquaGetScrollRect( /* TODO: m_nScreen */ nPart, rControlRegion, aRect );
		rIsInside = bValid ? aRect.IsInside( rPos ) : sal_False;
        if( GetSalData()->mbIsScrollbarDoubleMax )
        {
            // in double max mode the actual trough is a little smaller than the track
            // there is some visual filler that is not sensitive
            if( bValid && rIsInside )
            {
                if( nPart == PART_TRACK_HORZ_AREA )
                {
                    // the left 4 pixels are not hit sensitive
                    if( rPos.X() - aRect.Left() < 4 )
                        rIsInside = sal_False;
                }
                else if( nPart == PART_TRACK_VERT_AREA )
                {
                    // the top 4 pixels are not hit sensitive
                    if( rPos.Y() - aRect.Top() < 4 )
                        rIsInside = sal_False;
                }
            }
        }
		return bValid;
    }  //  CTRL_SCROLLBAR

    return sal_False;
}

/*
  kThemeStateInactive = 0,
   kThemeStateActive = 1,
   kThemeStatePressed = 2,
   kThemeStateRollover = 6,
   kThemeStateUnavailable = 7,
   kThemeStateUnavailableInactive = 8
   kThemeStatePressedUp = 2,
   kThemeStatePressedDown = 3

#define CTRL_STATE_ENABLED		0x0001
#define CTRL_STATE_FOCUSED		0x0002
#define CTRL_STATE_PRESSED		0x0004
#define CTRL_STATE_ROLLOVER		0x0008
#define CTRL_STATE_HIDDEN		0x0010
#define CTRL_STATE_DEFAULT		0x0020
#define CTRL_STATE_SELECTED		0x0040
#define CTRL_CACHING_ALLOWED	0x8000  // set when the control is completely visible (i.e. not clipped)
*/
UInt32 AquaSalGraphics::getState( ControlState nState )
{
    const bool bDrawActive = mpFrame ? ([mpFrame->getNSWindow() isKeyWindow] ? true : false) : true;
    if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive )
    {
        if( (nState & CTRL_STATE_HIDDEN) == 0 )
            return kThemeStateInactive;
        else
            return kThemeStateUnavailableInactive;
    }

    if( (nState & CTRL_STATE_HIDDEN) != 0 )
        return kThemeStateUnavailable;

    if( (nState & CTRL_STATE_PRESSED) != 0 )
        return kThemeStatePressed;

    return kThemeStateActive;
}

UInt32 AquaSalGraphics::getTrackState( ControlState nState )
{
    const bool bDrawActive = mpFrame ? ([mpFrame->getNSWindow() isKeyWindow] ? true : false) : true;
    if( (nState & CTRL_STATE_ENABLED) == 0 || ! bDrawActive )
            return kThemeTrackInactive;

    return kThemeTrackActive;
}

/*
 * DrawNativeControl()
 *
 *  Draws the requested control described by nPart/nState.
 *
 *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
 *  aValue:		An optional value (tristate/numerical/string)
 *  aCaption:	A caption or title string (like button text etc)
 */
sal_Bool AquaSalGraphics::drawNativeControl(ControlType nType,
					ControlPart nPart,
					const Rectangle& rControlRegion,
					ControlState nState,
					const ImplControlValue& aValue,
					const rtl::OUString& )
{
    sal_Bool bOK = sal_False;

    if( ! CheckContext() )
        return false;

    CGContextSaveGState( mrContext );

    Rectangle buttonRect = rControlRegion;
	HIRect rc = ImplGetHIRectFromRectangle(buttonRect);

    /** Scrollbar parts code equivalent **
    PART_BUTTON_UP 101
    PART_BUTTON_DOWN 102
	PART_THUMB_VERT 211
	PART_TRACK_VERT_UPPER 201
	PART_TRACK_VERT_LOWER 203

	PART_DRAW_BACKGROUND_HORZ 1000
	PART_DRAW_BACKGROUND_VERT 1001
    **/

    switch( nType )
    {

    case  CTRL_COMBOBOX:
        if ( nPart == HAS_BACKGROUND_TEXTURE ||
             nPart == PART_ENTIRE_CONTROL )
        {
            HIThemeButtonDrawInfo aComboInfo;
            aComboInfo.version = 0;
            aComboInfo.kind = kThemeComboBox;
            aComboInfo.state = getState( nState );
            aComboInfo.value = kThemeButtonOn;
            aComboInfo.adornment = kThemeAdornmentNone;

            if( (nState & CTRL_STATE_FOCUSED) != 0 )
                aComboInfo.adornment |= kThemeAdornmentFocus;

            HIThemeDrawButton(&rc, &aComboInfo, mrContext, kHIThemeOrientationNormal,&rc);
            bOK = true;
        }
        break;

    case CTRL_FIXEDBORDER:
    case CTRL_TOOLBAR:
        {
            HIThemeMenuItemDrawInfo aMenuItemDrawInfo;
            aMenuItemDrawInfo.version = 0;
            aMenuItemDrawInfo.state = kThemeMenuActive;
            aMenuItemDrawInfo.itemType = kThemeMenuItemHierBackground;
            HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,NULL);
            bOK = true;
        }
        break;

        case CTRL_WINDOW_BACKGROUND:
        {
            HIThemeBackgroundDrawInfo aThemeBackgroundInfo;
            aThemeBackgroundInfo.version = 0;
            aThemeBackgroundInfo.state = getState( nState );
            aThemeBackgroundInfo.kind = kThemeBrushDialogBackgroundActive;
            // FIXME: without this magical offset there is a 2 pixel black border on the right and bottom
            rc.size.width += 2;
            rc.size.height += 2;

            HIThemeApplyBackground( &rc, &aThemeBackgroundInfo, mrContext, kHIThemeOrientationNormal);
            CGContextFillRect( mrContext, rc );
            bOK = true;
        }
        break;

    case CTRL_MENUBAR:
    case CTRL_MENU_POPUP:
        {
            if ((nPart == PART_ENTIRE_CONTROL) || (nPart == PART_MENU_ITEM )|| (nPart == HAS_BACKGROUND_TEXTURE ))
            {
                // FIXME: without this magical offset there is a 2 pixel black border on the right
                rc.size.width += 2;

                HIThemeMenuDrawInfo aMenuInfo;
                aMenuInfo.version = 0;
                aMenuInfo.menuType = kThemeMenuTypePullDown;

                HIThemeMenuItemDrawInfo aMenuItemDrawInfo;
                // the Aqua grey theme when the item is selected is drawn here.
                aMenuItemDrawInfo.itemType = kThemeMenuItemPlain;

                if ((nPart == PART_MENU_ITEM ) && (nState & CTRL_STATE_SELECTED))
                {
                    // the blue theme when the item is selected is drawn here.
                    aMenuItemDrawInfo.state = kThemeMenuSelected;
                }
                else
                {
                    // normal color for non selected item
                    aMenuItemDrawInfo.state = kThemeMenuActive;
                }

                // repaints the background of the pull down menu
                HIThemeDrawMenuBackground(&rc,&aMenuInfo,mrContext,kHIThemeOrientationNormal);

                // repaints the item either blue (selected) and/or Aqua grey (active only)
                HIThemeDrawMenuItem(&rc,&rc,&aMenuItemDrawInfo,mrContext,kHIThemeOrientationNormal,&rc);

                bOK = true;
            }
            else if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) {
                if( nState & CTRL_STATE_PRESSED ) {//checked, else it is not displayed (see vcl/source/window/menu.cxx)
                    HIThemeTextInfo aTextInfo;
                    aTextInfo.version = 0;
                    aTextInfo.state = ((nState & CTRL_STATE_ENABLED)==0) ? kThemeStateInactive: kThemeStateActive;
                    aTextInfo.fontID = kThemeMenuItemMarkFont;
                    aTextInfo.horizontalFlushness=kHIThemeTextHorizontalFlushCenter;
                    aTextInfo.verticalFlushness=kHIThemeTextVerticalFlushTop;
                    aTextInfo.options=kHIThemeTextBoxOptionNone;
                    aTextInfo.truncationPosition=kHIThemeTextTruncationNone;
                    //aTextInfo.truncationMaxLines unused because of kHIThemeTextTruncationNone

                    if( nState & CTRL_STATE_SELECTED) aTextInfo.state = kThemeStatePressed; //item highlighted

                    UniChar mark=( nPart == PART_MENU_ITEM_CHECK_MARK ) ? kCheckUnicode: kBulletUnicode;//0x2713;
                    CFStringRef cfString = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &mark, 1, kCFAllocatorNull);
                    HIThemeDrawTextBox(cfString, &rc, &aTextInfo, mrContext, kHIThemeOrientationNormal);
					if (cfString)
						CFRelease(cfString);

                    bOK = true;
                }
            }
        }
        break;

    case CTRL_PUSHBUTTON:
        {
            // [ FIXME] : instead of use a value, vcl can retrieve correct values on the fly (to be implemented)
            const int PB_Mini_Height = 15;
            const int PB_Norm_Height = 21;

            HIThemeButtonDrawInfo aPushInfo;
            aPushInfo.version = 0;

            // no animation
            aPushInfo.animation.time.start = 0;
            aPushInfo.animation.time.current = 0;
            PushButtonValue* pPBVal = aValue.getType() == CTRL_PUSHBUTTON ? (PushButtonValue*)&aValue : NULL;
            int nPaintHeight = static_cast<int>(rc.size.height);

            if( pPBVal && pPBVal->mbBevelButton )
            {
                aPushInfo.kind = kThemeRoundedBevelButton;
            }
            else if( rc.size.height <= PB_Norm_Height )
            {
                aPushInfo.kind = kThemePushButtonMini;
                nPaintHeight = PB_Mini_Height;
            }
            else if( pPBVal->mbSingleLine || rc.size.height < (PB_Norm_Height + PB_Norm_Height/2) )
            {
                aPushInfo.kind = kThemePushButtonNormal;
                nPaintHeight = PB_Norm_Height;

                // avoid clipping when focused
                rc.origin.x += FOCUS_RING_WIDTH/2;
                rc.size.width -= FOCUS_RING_WIDTH;

                if( (nState & CTRL_STATE_DEFAULT) != 0 )
                {
                    AquaBlinker::Blink( mpFrame, buttonRect );
                    // show correct animation phase
                    aPushInfo.animation.time.current = CFAbsoluteTimeGetCurrent();
                }
            }
            else
                aPushInfo.kind = kThemeBevelButton;

            // translate the origin for controls with fixed paint height
            // so content ends up somewhere sensible
            int delta_y = static_cast<int>(rc.size.height) - nPaintHeight;
            rc.origin.y += delta_y/2;

            aPushInfo.state = getState( nState );
            aPushInfo.value = ImplGetButtonValue( aValue.getTristateVal() );

            aPushInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ?
            kThemeAdornmentDefault :
            kThemeAdornmentNone;
            if( (nState & CTRL_STATE_FOCUSED) != 0 )
                aPushInfo.adornment |= kThemeAdornmentFocus;

            HIThemeDrawButton( &rc, &aPushInfo, mrContext, kHIThemeOrientationNormal, NULL );
            bOK = true;
        }
        break;

    case CTRL_RADIOBUTTON:
    case CTRL_CHECKBOX:
        {
            HIThemeButtonDrawInfo aInfo;
            aInfo.version = 0;
            switch( nType )
            {
            case CTRL_RADIOBUTTON: if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeRadioButton;
                                    else aInfo.kind = kThemeSmallRadioButton;
                break;
            case CTRL_CHECKBOX:   if(rc.size.width >= BUTTON_HEIGHT) aInfo.kind = kThemeCheckBox;
                                    else aInfo.kind = kThemeSmallCheckBox;
                break;
            }

            aInfo.state = getState( nState );

            ButtonValue aButtonValue = aValue.getTristateVal();
            aInfo.value = ImplGetButtonValue( aButtonValue );

            aInfo.adornment = (( nState & CTRL_STATE_DEFAULT ) != 0) ?
            kThemeAdornmentDefault :
            kThemeAdornmentNone;
            if( (nState & CTRL_STATE_FOCUSED) != 0 )
                aInfo.adornment |= kThemeAdornmentFocus;
            HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL );
            bOK = true;
        }
        break;

    case CTRL_LISTNODE:
        {
            ButtonValue aButtonValue = aValue.getTristateVal();

            if( Application::GetSettings().GetLayoutRTL() && aButtonValue == BUTTONVALUE_OFF )
            {
                // FIXME: a value of kThemeDisclosureLeft
                // should draw a theme compliant left disclosure triangle
                // sadly this does not seem to work, so we'll draw a left
                // grey equilateral triangle here ourselves.
                // Perhaps some other HIThemeButtonDrawInfo setting would do the trick ?

                CGContextSetShouldAntialias( mrContext, true );
                CGFloat aGrey[] = { 0.45, 0.45, 0.45, 1.0 };
                CGContextSetFillColor( mrContext, aGrey );
                CGContextBeginPath( mrContext );
                CGFloat x = rc.origin.x + rc.size.width;
                CGFloat y = rc.origin.y;
                CGContextMoveToPoint( mrContext, x, y );
                y += rc.size.height;
                CGContextAddLineToPoint( mrContext, x, y );
                x -= rc.size.height * 0.866; // cos( 30 degree ) is approx. 0.866
                y -= rc.size.height/2;
                CGContextAddLineToPoint( mrContext, x, y );
                CGContextDrawPath( mrContext, kCGPathEOFill );
            }
            else
            {
                HIThemeButtonDrawInfo aInfo;
                aInfo.version = 0;
                aInfo.kind = kThemeDisclosureTriangle;
                aInfo.value = kThemeDisclosureRight;
                aInfo.state = getState( nState );

                aInfo.adornment = kThemeAdornmentNone;

                switch( aButtonValue ) {
                    case BUTTONVALUE_ON: aInfo.value = kThemeDisclosureDown;//expanded
                        break;
                    case BUTTONVALUE_OFF:
                        // FIXME: this should have drawn a theme compliant disclosure triangle
                        // (see above)
                        if( Application::GetSettings().GetLayoutRTL() )
                        {
                            aInfo.value = kThemeDisclosureLeft;//collapsed, RTL
                        }
                        break;
                    case BUTTONVALUE_DONTKNOW: //what to do?
                    default:
                        break;
                }

                HIThemeDrawButton( &rc, &aInfo, mrContext, kHIThemeOrientationNormal, NULL );
            }
            bOK = true;
        }
        break;

    case CTRL_PROGRESS:
    case CTRL_INTROPROGRESS:
        {
            long nProgressWidth = aValue.getNumericVal();
            HIThemeTrackDrawInfo aTrackInfo;
            aTrackInfo.version              = 0;
            aTrackInfo.kind                 = (rc.size.height > 10) ? kThemeProgressBarLarge : kThemeProgressBarMedium;
            aTrackInfo.bounds               = rc;
            aTrackInfo.min                  = 0;
            aTrackInfo.max                  = static_cast<SInt32>(rc.size.width);
            aTrackInfo.value                = nProgressWidth;
            aTrackInfo.reserved             = 0;
            aTrackInfo.bounds.origin.y     -= 2; // FIXME: magic for shadow
            aTrackInfo.bounds.size.width   -= 2; // FIXME: magic for shadow
            aTrackInfo.attributes           = kThemeTrackHorizontal;
            if( Application::GetSettings().GetLayoutRTL() )
                aTrackInfo.attributes      |= kThemeTrackRightToLeft;
            aTrackInfo.enableState          = getTrackState( nState );
            // the intro bitmap never gets key anyway; we want to draw that enabled
            if( nType == CTRL_INTROPROGRESS )
                aTrackInfo.enableState          = kThemeTrackActive;
            aTrackInfo.filler1              = 0;
            aTrackInfo.trackInfo.progress.phase   = static_cast<UInt8>(CFAbsoluteTimeGetCurrent()*10.0);

            HIThemeDrawTrack( &aTrackInfo, NULL, mrContext, kHIThemeOrientationNormal );
            bOK = true;
        }
        break;

    case CTRL_SLIDER:
        {
            SliderValue* pSLVal = (SliderValue*)&aValue;

            HIThemeTrackDrawInfo aTrackDraw;
            aTrackDraw.kind = kThemeSliderMedium;
            if( nPart == PART_TRACK_HORZ_AREA || nPart == PART_TRACK_VERT_AREA )
            {
                aTrackDraw.bounds = rc;
                aTrackDraw.min   = pSLVal->mnMin;
                aTrackDraw.max   = pSLVal->mnMax;
                aTrackDraw.value = pSLVal->mnCur;
                aTrackDraw.reserved = 0;
                aTrackDraw.attributes = kThemeTrackShowThumb;
                if( nPart == PART_TRACK_HORZ_AREA )
                    aTrackDraw.attributes |= kThemeTrackHorizontal;
                aTrackDraw.enableState = (nState & CTRL_STATE_ENABLED)
                                         ? kThemeTrackActive : kThemeTrackInactive;

                SliderTrackInfo aSlideInfo;
                aSlideInfo.thumbDir = kThemeThumbUpward;
                aSlideInfo.pressState = 0;
                aTrackDraw.trackInfo.slider = aSlideInfo;

                HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal );
                bOK = true;
            }
        }
        break;

    case CTRL_SCROLLBAR:
        {
            const ScrollbarValue* pScrollbarVal = (aValue.getType() == CTRL_SCROLLBAR) ? static_cast<const ScrollbarValue*>(&aValue) : NULL;

            if( nPart == PART_DRAW_BACKGROUND_VERT ||
                nPart == PART_DRAW_BACKGROUND_HORZ )
            {
                HIThemeTrackDrawInfo aTrackDraw;
                aTrackDraw.kind = kThemeMediumScrollBar;
                // FIXME: the scrollbar length must be adjusted
                if (nPart == PART_DRAW_BACKGROUND_VERT)
                    rc.size.height += 2;
                else
                    rc.size.width += 2;

                aTrackDraw.bounds = rc;
                aTrackDraw.min = pScrollbarVal->mnMin;
                aTrackDraw.max = pScrollbarVal->mnMax - pScrollbarVal->mnVisibleSize;
                aTrackDraw.value = pScrollbarVal->mnCur;
                aTrackDraw.reserved = 0;
                aTrackDraw.attributes = kThemeTrackShowThumb;
                if( nPart == PART_DRAW_BACKGROUND_HORZ )
                    aTrackDraw.attributes |= kThemeTrackHorizontal;
                aTrackDraw.enableState = getTrackState( nState );

                ScrollBarTrackInfo aScrollInfo;
                aScrollInfo.viewsize = pScrollbarVal->mnVisibleSize;
                aScrollInfo.pressState = 0;

                if ( pScrollbarVal->mnButton1State & CTRL_STATE_ENABLED )
                {
                    if ( pScrollbarVal->mnButton1State & CTRL_STATE_PRESSED )
                        aScrollInfo.pressState = kThemeTopOutsideArrowPressed;
                }

                if ( pScrollbarVal->mnButton2State & CTRL_STATE_ENABLED )
                {
                    if ( pScrollbarVal->mnButton2State & CTRL_STATE_PRESSED )
                        aScrollInfo.pressState = kThemeBottomOutsideArrowPressed;
                }

                if ( pScrollbarVal->mnThumbState & CTRL_STATE_ENABLED )
                {
                    if ( pScrollbarVal->mnThumbState & CTRL_STATE_PRESSED )
                        aScrollInfo.pressState = kThemeThumbPressed;
                }

                aTrackDraw.trackInfo.scrollbar = aScrollInfo;

                HIThemeDrawTrack( &aTrackDraw, NULL, mrContext, kHIThemeOrientationNormal );
                bOK = true;
            }
        }
        break;

//#define OLD_TAB_STYLE
#ifdef OLD_TAB_STYLE
    case CTRL_TAB_PANE:
        {
            HIThemeTabPaneDrawInfo aTabPaneDrawInfo;
            aTabPaneDrawInfo.version = 0;
            aTabPaneDrawInfo.state = kThemeStateActive;
            aTabPaneDrawInfo.direction=kThemeTabNorth;
            aTabPaneDrawInfo.size=kHIThemeTabSizeNormal;

            //the border is outside the rect rc for Carbon
            //but for VCL it should be inside
            rc.origin.x+=1;
            rc.size.width-=2;

            HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal);
            bOK = true;
        }
        break;

    case CTRL_TAB_ITEM:
        {
            HIThemeTabDrawInfo aTabItemDrawInfo;
            aTabItemDrawInfo.version=0;
            aTabItemDrawInfo.style=kThemeTabNonFront;
            aTabItemDrawInfo.direction=kThemeTabNorth;
            aTabItemDrawInfo.size=kHIThemeTabSizeNormal;
            aTabItemDrawInfo.adornment=kHIThemeTabAdornmentNone;

            if(nState & CTRL_STATE_SELECTED) {
                aTabItemDrawInfo.style=kThemeTabFront;
            }
            if(nState & CTRL_STATE_FOCUSED) {
                aTabItemDrawInfo.adornment=kHIThemeTabAdornmentFocus;
            }

            /*if(rc.size.height>=TAB_HEIGHT_NORMAL) rc.size.height=TAB_HEIGHT_NORMAL;
            else if(rc.size.height>=TAB_HEIGHT_SMALL) rc.size.height=TAB_HEIGHT_SMALL;
            else rc.size.height=TAB_HEIGHT_MINI;*/
            //now we only use the default size
            rc.size.height=TAB_HEIGHT_NORMAL;

            HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc );

            bOK=true;
        }
        break;
#else
    case CTRL_TAB_PANE:
        {
            HIThemeTabPaneDrawInfo aTabPaneDrawInfo;
            aTabPaneDrawInfo.version = 1;
            aTabPaneDrawInfo.state = kThemeStateActive;
            aTabPaneDrawInfo.direction=kThemeTabNorth;
            aTabPaneDrawInfo.size=kHIThemeTabSizeNormal;
            aTabPaneDrawInfo.kind=kHIThemeTabKindNormal;

            //the border is outside the rect rc for Carbon
            //but for VCL it should be inside
            rc.origin.x+=1;
            rc.origin.y-=TAB_HEIGHT_NORMAL/2;
            rc.size.height+=TAB_HEIGHT_NORMAL/2;
            rc.size.width-=2;

            HIThemeDrawTabPane(&rc, &aTabPaneDrawInfo, mrContext, kHIThemeOrientationNormal);

            bOK = true;
        }
        break;

    case CTRL_TAB_ITEM:
        {
            HIThemeTabDrawInfo aTabItemDrawInfo;
            aTabItemDrawInfo.version=1;
            aTabItemDrawInfo.style=kThemeTabNonFront;
            aTabItemDrawInfo.direction=kThemeTabNorth;
            aTabItemDrawInfo.size=kHIThemeTabSizeNormal;
            aTabItemDrawInfo.adornment=kHIThemeTabAdornmentTrailingSeparator;
            //State
            if(nState & CTRL_STATE_SELECTED) {
                aTabItemDrawInfo.style=kThemeTabFront;
            }
            if(nState & CTRL_STATE_FOCUSED) {
                aTabItemDrawInfo.adornment|=kHIThemeTabAdornmentFocus;
            }

            //first, last or middle tab
            aTabItemDrawInfo.position=kHIThemeTabPositionMiddle;

            TabitemValue* pTabValue = (TabitemValue *) &aValue;
            unsigned int nAlignment = pTabValue->mnAlignment;
            //TABITEM_LEFTALIGNED (and TABITEM_RIGHTALIGNED) for the leftmost (or rightmost) tab
            //when there are several lines of tabs because there is only one first tab and one
            //last tab and TABITEM_FIRST_IN_GROUP (and TABITEM_LAST_IN_GROUP) because when the
            //line width is different from window width, there may not be TABITEM_RIGHTALIGNED
            if( ( (nAlignment & TABITEM_LEFTALIGNED)&&(nAlignment & TABITEM_RIGHTALIGNED) ) ||
                ( (nAlignment & TABITEM_FIRST_IN_GROUP)&&(nAlignment & TABITEM_LAST_IN_GROUP) )
               ) //tab alone
                aTabItemDrawInfo.position=kHIThemeTabPositionOnly;
            else if((nAlignment & TABITEM_LEFTALIGNED)||(nAlignment & TABITEM_FIRST_IN_GROUP))
                aTabItemDrawInfo.position=kHIThemeTabPositionFirst;
            else if((nAlignment & TABITEM_RIGHTALIGNED)||(nAlignment & TABITEM_LAST_IN_GROUP))
                aTabItemDrawInfo.position=kHIThemeTabPositionLast;

            //support for RTL
            //see issue 79748
            if( Application::GetSettings().GetLayoutRTL() ) {
                if( aTabItemDrawInfo.position == kHIThemeTabPositionFirst )
                        aTabItemDrawInfo.position = kHIThemeTabPositionLast;
                else if( aTabItemDrawInfo.position == kHIThemeTabPositionLast )
                        aTabItemDrawInfo.position = kHIThemeTabPositionFirst;
            }

            rc.size.width+=2;//because VCL has 2 empty pixels between 2 tabs
            rc.origin.x-=1;

            HIThemeDrawTab(&rc, &aTabItemDrawInfo, mrContext, kHIThemeOrientationNormal, &rc );

            bOK=true;
        }
        break;
#endif

    case  CTRL_LISTBOX:
        switch( nPart)
        {
            case PART_ENTIRE_CONTROL:
            case PART_BUTTON_DOWN:
            {
                HIThemeButtonDrawInfo aListInfo;
                aListInfo.version = 0;
                aListInfo.kind = kThemePopupButton;
                aListInfo.state = getState( nState );//kThemeStateInactive -> greyed
                aListInfo.value = kThemeButtonOn;

                aListInfo.adornment = kThemeAdornmentDefault;
                if( (nState & CTRL_STATE_FOCUSED) != 0 )
                    aListInfo.adornment |= kThemeAdornmentFocus;

                HIThemeDrawButton(&rc, &aListInfo, mrContext, kHIThemeOrientationNormal,&rc);
                bOK = true;
                break;
            }
            case PART_WINDOW:
            {
                HIThemeFrameDrawInfo aTextDrawInfo;
                aTextDrawInfo.version=0;
                aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
                aTextDrawInfo.state=getState( nState );
                aTextDrawInfo.isFocused=false;

                rc.size.width+=1;//else there's a white space because aqua theme hasn't a 3D border
                rc.size.height+=1;
                HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);

                if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);

                bOK=true;
                break;
            }
        }
        break;

    case CTRL_EDITBOX:
    case CTRL_MULTILINE_EDITBOX:
        {
            HIThemeFrameDrawInfo aTextDrawInfo;
            aTextDrawInfo.version=0;
            aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
            aTextDrawInfo.state=getState( nState );
            aTextDrawInfo.isFocused=false;

            rc.size.width  += 1; // else there may be a white space because aqua theme hasn't a 3D border
            // change rc so that the frame will encompass only the content region
            // see counterpart in GetNativeControlRegion
            rc.size.width  += 2;
            rc.size.height += 2;

            //CGContextSetFillColorWithColor
            CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height));
            //fill a white background, because drawFrame only draws the border

            HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);

            if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);

            bOK=true;
        }
        break;

    case CTRL_SPINBOX:
        {
            if(nPart == PART_ENTIRE_CONTROL)
            {
                //text field:
                HIThemeFrameDrawInfo aTextDrawInfo;
                aTextDrawInfo.version=0;
                aTextDrawInfo.kind=kHIThemeFrameTextFieldSquare;
                aTextDrawInfo.state=getState( nState );
                aTextDrawInfo.isFocused=false;

                //rc.size.width contains the full size of the spinbox ie textfield + button
                //so we remove the button width and the space between the button and the textfield
                rc.size.width -= SPIN_BUTTON_SPACE + SPIN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH;
                rc.origin.x += FOCUS_RING_WIDTH;
                rc.origin.y += FOCUS_RING_WIDTH;

                //CGContextSetFillColorWithColor
                CGContextFillRect (mrContext, CGRectMake(rc.origin.x, rc.origin.y, rc.size.width, rc.size.height));
                //fill a white background, because drawFrame only draws the border

                HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);

                if(nState & CTRL_STATE_FOCUSED) HIThemeDrawFocusRect(&rc, true, mrContext, kHIThemeOrientationNormal);

                //buttons:
                const SpinbuttonValue* pSpinButtonVal = (aValue.getType() == CTRL_SPINBUTTONS) ? static_cast<const SpinbuttonValue*>(&aValue) : NULL;
                ControlState nUpperState = CTRL_STATE_ENABLED;//state of the upper button
                ControlState nLowerState = CTRL_STATE_ENABLED;//and of the lower button
                if(pSpinButtonVal) {//pSpinButtonVal is sometimes null
                    nUpperState = (ControlState) pSpinButtonVal->mnUpperState;
                    nLowerState = (ControlState) pSpinButtonVal->mnLowerState;

                    HIThemeButtonDrawInfo aSpinInfo;
                    aSpinInfo.kind = kThemeIncDecButton;
                    aSpinInfo.state = kThemeStateActive;
                    if(nUpperState & CTRL_STATE_PRESSED)
                        aSpinInfo.state = kThemeStatePressedUp;
                    else if(nLowerState & CTRL_STATE_PRESSED)
                        aSpinInfo.state = kThemeStatePressedDown;
                    else if((nUpperState & ~CTRL_STATE_ENABLED)||(nLowerState & ~CTRL_STATE_ENABLED))
                        aSpinInfo.state = kThemeStateInactive;
                    else if((nUpperState & CTRL_STATE_ROLLOVER)||(nLowerState & CTRL_STATE_ROLLOVER))
                        aSpinInfo.state = kThemeStateRollover;

                    Rectangle aSpinRect( pSpinButtonVal->maUpperRect );
                    aSpinRect.Union( pSpinButtonVal->maLowerRect );
                    HIRect buttonRc = ImplGetHIRectFromRectangle(aSpinRect);

                    // FIXME: without this fuzz factor there is some unwanted clipping
                    if( Application::GetSettings().GetLayoutRTL() )
                        buttonRc.origin.x -= FOCUS_RING_WIDTH - CLIP_FUZZ;
                    else
                        buttonRc.origin.x += FOCUS_RING_WIDTH + CLIP_FUZZ;

                    switch( aValue.getTristateVal() )
                    {
                        case BUTTONVALUE_ON:        aSpinInfo.value = kThemeButtonOn;
                                                    break;
                        case BUTTONVALUE_OFF:       aSpinInfo.value = kThemeButtonOff;
                                                    break;
                        case BUTTONVALUE_MIXED:
                        case BUTTONVALUE_DONTKNOW:
                        default:                    aSpinInfo.value = kThemeButtonMixed;
                                                    break;
                    }

                    aSpinInfo.adornment = ( ((nUpperState & CTRL_STATE_DEFAULT) != 0 ) ||
                                            ((nLowerState & CTRL_STATE_DEFAULT) != 0 )) ?
                                       kThemeAdornmentDefault :
                                       kThemeAdornmentNone;
                    if( ((nUpperState & CTRL_STATE_FOCUSED) != 0 ) || ((nLowerState & CTRL_STATE_FOCUSED) != 0 ))
                        aSpinInfo.adornment |= kThemeAdornmentFocus;

                    HIThemeDrawButton( &buttonRc, &aSpinInfo, mrContext, kHIThemeOrientationNormal, NULL );
                }

                bOK=true;
            }

        }
        break;

    case CTRL_FRAME:
        {
            sal_uInt16 nStyle = aValue.getNumericVal();
            if( nPart == PART_BORDER ) {
                if(!( nStyle & FRAME_DRAW_MENU ) && !(nStyle & FRAME_DRAW_WINDOWBORDER) )
                {
                    // #i84756# strange effects start to happen when HIThemeDrawFrame
                    // meets the border of the window. These can be avoided by clipping
                    // to the boundary of the frame
                    if( rc.origin.y + rc.size.height >= mpFrame->maGeometry.nHeight-3 )
                    {
                        CGMutablePathRef rPath = CGPathCreateMutable();
                        CGPathAddRect( rPath, NULL, CGRectMake( 0, 0, mpFrame->maGeometry.nWidth-1, mpFrame->maGeometry.nHeight-1 ) );

                        CGContextBeginPath( mrContext );
                        CGContextAddPath( mrContext, rPath );
                        CGContextClip( mrContext );
                        CGPathRelease( rPath );
                    }

                    HIThemeFrameDrawInfo aTextDrawInfo;
                    aTextDrawInfo.version=0;
                    aTextDrawInfo.kind=kHIThemeFrameListBox;
                    aTextDrawInfo.state=kThemeStateActive;
                    aTextDrawInfo.isFocused=false;

                    HIThemeDrawFrame(&rc, &aTextDrawInfo, mrContext, kHIThemeOrientationNormal);

                    bOK=true;
                }
            }
        }
        break;

    case CTRL_LISTNET:
        {
           //do nothing as there isn't net for listviews on macos
            bOK=true;
        }
        break;

    }

    CGContextRestoreGState( mrContext );

    /* #i90291# in most cases invalidating the whole control region instead
       of just the unclipped part of it is sufficient (and probably faster).
       However for the window background we should not unnecessarily enlarge
       the really changed rectangle since the difference is usually quite high
       (the background is always drawn as a whole since we don't know anything
       about its possible contents)
    */
    if( nType == CTRL_WINDOW_BACKGROUND )
    {
        CGRect aRect = { { 0, 0 }, { 0, 0 } };
        if( mxClipPath )
            aRect = CGPathGetBoundingBox( mxClipPath );
        if( aRect.size.width != 0 && aRect.size.height != 0 )
            buttonRect.Intersection( Rectangle( Point( static_cast<long int>(aRect.origin.x),
							static_cast<long int>(aRect.origin.y) ),
                                                Size( 	static_cast<long int>(aRect.size.width),
							static_cast<long int>(aRect.size.height) ) ) );
    }

    RefreshRect( buttonRect.Left(), buttonRect.Top(), buttonRect.GetWidth(), buttonRect.GetHeight() );

    return bOK;
}

/*
 * DrawNativeControlText()
 *
 *  OPTIONAL.  Draws the requested text for the control described by nPart/nState.
 *     Used if text not drawn by DrawNativeControl().
 *
 *  rControlRegion:	The bounding region of the complete control in VCL frame coordinates.
 *  aValue:		An optional value (tristate/numerical/string)
 *  aCaption:	A caption or title string (like button text etc)
 */
sal_Bool AquaSalGraphics::drawNativeControlText( ControlType /*nType*/, ControlPart /*nPart*/, const Rectangle& /*rControlRegion*/,
                                               ControlState /*nState*/, const ImplControlValue& /*aValue*/,
                                               const rtl::OUString& )
{
	return( sal_False );
}


/*
 * GetNativeControlRegion()
 *
 *  If the return value is sal_True, rNativeBoundingRegion
 *  contains the true bounding region covered by the control
 *  including any adornment, while rNativeContentRegion contains the area
 *  within the control that can be safely drawn into without drawing over
 *  the borders of the control.
 *
 *  rControlRegion:	The bounding region of the control in VCL frame coordinates.
 *  aValue:		An optional value (tristate/numerical/string)
 *  aCaption:		A caption or title string (like button text etc)
 */
sal_Bool AquaSalGraphics::getNativeControlRegion( ControlType nType, ControlPart nPart, const Rectangle& rControlRegion, ControlState /*nState*/,
                                               const ImplControlValue& aValue, const rtl::OUString&,
                                                Rectangle &rNativeBoundingRegion, Rectangle &rNativeContentRegion )

{
	sal_Bool toReturn = sal_False;

	Rectangle aCtrlBoundRect( rControlRegion );
    short x = aCtrlBoundRect.Left();
    short y = aCtrlBoundRect.Top();
    short w, h;

    sal_uInt8 nBorderCleanup = 0;

    switch (nType)
    {
        case CTRL_SLIDER:
            {
                if( nPart == PART_THUMB_HORZ )
                {
                    w = 19; // taken from HIG
                    h = aCtrlBoundRect.GetHeight();
                    rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    toReturn = true;
                }
                else if( nPart == PART_THUMB_VERT )
                {
                    w = aCtrlBoundRect.GetWidth();
                    h = 18; // taken from HIG
                    rNativeBoundingRegion = rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    toReturn = true;
                }
            }
            break;

        case CTRL_SCROLLBAR:
            {
				Rectangle aRect;
				if( AquaGetScrollRect( /* m_nScreen */ nPart, aCtrlBoundRect, aRect ) )
                {
					toReturn = sal_True;
					rNativeBoundingRegion = aRect;
					rNativeContentRegion = aRect;
                }
            }
            break;

        case CTRL_PUSHBUTTON:
        case CTRL_RADIOBUTTON:
        case CTRL_CHECKBOX:
            {
                if ( nType == CTRL_PUSHBUTTON )
                {
                    w = aCtrlBoundRect.GetWidth();
                    h = aCtrlBoundRect.GetHeight();
                }
                else
                {
                    // checkbox and radio borders need cleanup after unchecking them
                    nBorderCleanup = 4;

                    // TEXT_SEPARATOR to respect Aqua HIG
                    w = BUTTON_WIDTH + TEXT_SEPARATOR;
                    h = BUTTON_HEIGHT;

                }

                rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h + nBorderCleanup) );
                rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

                toReturn = sal_True;
            }
            break;
        case CTRL_PROGRESS:
            {
                Rectangle aRect( aCtrlBoundRect );
                if( aRect.GetHeight() < 16 )
                    aRect.Bottom() = aRect.Top() + 9; // values taken from HIG for medium progress
                else
                    aRect.Bottom() = aRect.Top() + 15; // values taken from HIG for large progress
                rNativeBoundingRegion = aRect;
                rNativeContentRegion = aRect;
                toReturn = sal_True;
            }
            break;

        case CTRL_INTROPROGRESS:
            {
                Rectangle aRect( aCtrlBoundRect );
                aRect.Bottom() = aRect.Top() + INTRO_PROGRESS_HEIGHT; // values taken from HIG for medium progress
                rNativeBoundingRegion = aRect;
                rNativeContentRegion = aRect;
                toReturn = sal_True;
            }
            break;

         case CTRL_TAB_ITEM:

            w = aCtrlBoundRect.GetWidth() + 2*TAB_TEXT_OFFSET - 2*VCL_TAB_TEXT_OFFSET;

#ifdef OLD_TAB_STYLE
            h = TAB_HEIGHT_NORMAL;
#else
            h = TAB_HEIGHT_NORMAL+2;
#endif
            rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
            rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

            toReturn = sal_True;

            break;

        case CTRL_EDITBOX:
            {
                w = aCtrlBoundRect.GetWidth();
                if( w < 3+2*FOCUS_RING_WIDTH )
                    w = 3+2*FOCUS_RING_WIDTH;
                h = TEXT_EDIT_HEIGHT_NORMAL+2*FOCUS_RING_WIDTH;
                if( h < aCtrlBoundRect.GetHeight() )
                    h = aCtrlBoundRect.GetHeight();

                rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*(FOCUS_RING_WIDTH+1), h-2*(FOCUS_RING_WIDTH+1) ) );
                rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

                toReturn = sal_True;
            }
            break;
        case CTRL_LISTBOX:
        case CTRL_COMBOBOX:
            {
                if( nPart == PART_ENTIRE_CONTROL )
                {
                    w = aCtrlBoundRect.GetWidth();
                    h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height

                    rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y+FOCUS_RING_WIDTH ), Size( w-2*FOCUS_RING_WIDTH, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );

                    toReturn = sal_True;
                }
                else if( nPart == PART_BUTTON_DOWN )
                {
                    w = aCtrlBoundRect.GetWidth();
                if( w < 3+2*FOCUS_RING_WIDTH )
                    w = 3+2*FOCUS_RING_WIDTH;
                    h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height

                    x += w-DROPDOWN_BUTTON_WIDTH - FOCUS_RING_WIDTH;
                    y += FOCUS_RING_WIDTH;
                    w = DROPDOWN_BUTTON_WIDTH;

                    rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) );

                    toReturn = true;
                }
                else if( nPart == PART_SUB_EDIT )
                {
                    w = aCtrlBoundRect.GetWidth();
                    h = COMBOBOX_HEIGHT_NORMAL;//listboxes and comboxes have the same height

                    x += FOCUS_RING_WIDTH;
                    x += 3; // add an offset for rounded borders
                    y += 2; // don't draw into upper border
                    y += FOCUS_RING_WIDTH;
                    w -= 3 + DROPDOWN_BUTTON_WIDTH + 2*FOCUS_RING_WIDTH;
                    if( nType == CTRL_LISTBOX )
                        w -= 9; // HIG specifies 9 units distance between dropdown button area and content
                    h -= 4; // don't draw into lower border

                    rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w+FOCUS_RING_WIDTH, h+2*FOCUS_RING_WIDTH ) );

                    toReturn = true;
                }
            }
            break;
        case CTRL_SPINBOX:
                if( nPart == PART_ENTIRE_CONTROL ) {
                    w = aCtrlBoundRect.GetWidth();
                    if( w < 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH )
                        w = 3+2*FOCUS_RING_WIDTH+SPIN_BUTTON_SPACE+SPIN_BUTTON_WIDTH;
                    h = TEXT_EDIT_HEIGHT_NORMAL;

                    rNativeContentRegion = Rectangle( Point( x+FOCUS_RING_WIDTH, y ), Size( w-2*FOCUS_RING_WIDTH, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );

                    toReturn = sal_True;
                }
                else if( nPart == PART_SUB_EDIT ) {
                    w = aCtrlBoundRect.GetWidth() - SPIN_BUTTON_SPACE - SPIN_BUTTON_WIDTH;
                    h = TEXT_EDIT_HEIGHT_NORMAL;
                    x += 4; // add an offset for rounded borders
                    y += 2; // don't draw into upper border
                    w -= 8; // offset for left and right rounded border
                    h -= 4; // don't draw into upper or ower border

                    rNativeContentRegion = Rectangle( Point( x + FOCUS_RING_WIDTH, y + FOCUS_RING_WIDTH ), Size( w - 2* FOCUS_RING_WIDTH, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h+2*FOCUS_RING_WIDTH ) );

                    toReturn = sal_True;
                }
                else if( nPart == PART_BUTTON_UP ) {
                    //aCtrlBoundRect.GetWidth() contains the width of the full control
                    //ie the width of the textfield + button
                    //x is the position of the left corner of the full control
                    x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ;
                    y += FOCUS_RING_WIDTH - CLIP_FUZZ;
                    w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ;
                    h = SPIN_UPPER_BUTTON_HEIGHT + 2*CLIP_FUZZ;

                    rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

                    toReturn = sal_True;
                }
                else if( nPart == PART_BUTTON_DOWN ) {
                    x += aCtrlBoundRect.GetWidth() - SPIN_BUTTON_WIDTH - SPIN_BUTTON_SPACE - CLIP_FUZZ;
                    y += SPIN_UPPER_BUTTON_HEIGHT + FOCUS_RING_WIDTH - CLIP_FUZZ;
                    w = SPIN_BUTTON_WIDTH + 2*CLIP_FUZZ;
                    h = SPIN_LOWER_BUTTON_HEIGHT + 2*CLIP_FUZZ;

                    rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

                    toReturn = sal_True;
                }
            break;
        case CTRL_FRAME:
            {
                sal_uInt16 nStyle = aValue.getNumericVal();
                if(  ( nPart == PART_BORDER ) &&
                    !( nStyle & (FRAME_DRAW_MENU | FRAME_DRAW_WINDOWBORDER | FRAME_DRAW_BORDERWINDOWBORDER) ) )
                {
                    Rectangle aRect(aCtrlBoundRect);
                    if( nStyle & FRAME_DRAW_DOUBLEIN )
                    {
                        aRect.Left()	+= 1;
                        aRect.Top() 	+= 1;
                        //rRect.Right()	-= 1;
                        //rRect.Bottom()	-= 1;
                    }
                    else
                    {
                        aRect.Left()	+= 1;
                        aRect.Top() 	+= 1;
                        aRect.Right()	-= 1;
                        aRect.Bottom()	-= 1;
                    }

                    rNativeContentRegion = aRect;
                    rNativeBoundingRegion = aRect;

                    toReturn = sal_True;
                }
            }
            break;

        case CTRL_MENUBAR:
        case CTRL_MENU_POPUP:
            {
                if(( nPart == PART_MENU_ITEM_CHECK_MARK )||( nPart == PART_MENU_ITEM_RADIO_MARK )) {

                    w=10;
                    h=10;//dimensions of the mark (10px font)

                    rNativeContentRegion = Rectangle( Point( x, y ), Size( w, h ) );
                    rNativeBoundingRegion = Rectangle( Point( x, y ), Size( w, h ) );

                    toReturn = sal_True;
                }
            }
            break;

    }

    return toReturn;
}
