/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <vcl/svapp.hxx>
#include <tools/table.hxx>
#include <vcl/help.hxx>
#include <vcl/menu.hxx>
#include <vcl/decoview.hxx>
#include <vcl/floatwin.hxx>
#include <vcl/button.hxx>
#include <vcl/fixed.hxx>
#include <unotools/calendarwrapper.hxx>
#include <unotools/localedatawrapper.hxx>
#include <com/sun/star/i18n/Weekdays.hpp>
#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
#include <com/sun/star/i18n/CalendarFieldIndex.hpp>

#define _SV_CALENDAR_CXX
#include <svtools/svtools.hrc>
#include <svtools/svtdata.hxx>
#include <svtools/calendar.hxx>

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

#define DAY_OFFX						4
#define DAY_OFFY						2
#define MONTH_BORDERX					4
#define MONTH_OFFY						3
#define WEEKNUMBER_OFFX 				4
#define WEEKDAY_OFFY					3
#define TITLE_OFFY						3
#define TITLE_BORDERY					2
#define SPIN_OFFX						4
#define SPIN_OFFY						TITLE_BORDERY

#define WEEKNUMBER_HEIGHT				85

#define CALENDAR_HITTEST_DAY			((sal_uInt16)0x0001)
#define CALENDAR_HITTEST_WEEK			((sal_uInt16)0x0002)
#define CALENDAR_HITTEST_MONTHTITLE 	((sal_uInt16)0x0004)
#define CALENDAR_HITTEST_PREV			((sal_uInt16)0x0008)
#define CALENDAR_HITTEST_NEXT			((sal_uInt16)0x0010)
#define CALENDAR_HITTEST_OUTSIDE		((sal_uInt16)0x1000)

#define MENU_YEAR_COUNT 				3

#define TABLE_DATE_SELECTED 			((void*)0x00000001)

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

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

struct ImplDateInfo
{
	XubString	maText;
	Color*		mpTextColor;
	Color*		mpFrameColor;
	sal_uInt16		mnFlags;

				ImplDateInfo( const XubString& rText ) :
					maText( rText )
				{ mpTextColor = mpFrameColor = NULL; mnFlags = 0; }
				~ImplDateInfo() { delete mpTextColor; delete mpFrameColor; }
};

DECLARE_TABLE( ImplDateTable, ImplDateInfo* )

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

static void ImplCalendarSelectDate( Table* pTable, const Date& rDate, sal_Bool bSelect )
{
	if ( bSelect )
		pTable->Insert( rDate.GetDate(), TABLE_DATE_SELECTED );
	else
		pTable->Remove( rDate.GetDate() );
}

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

static void ImplCalendarSelectDateRange( Table* pTable,
										 const Date& rStartDate,
										 const Date& rEndDate,
										 sal_Bool bSelect )
{
	Date aStartDate = rStartDate;
	Date aEndDate = rEndDate;
	if ( aStartDate > aEndDate )
	{
		Date aTempDate = aStartDate;
		aStartDate = aEndDate;
		aEndDate = aTempDate;
	}

	if ( bSelect )
	{
		while ( aStartDate <= aEndDate )
		{
			pTable->Insert( aStartDate.GetDate(), TABLE_DATE_SELECTED );
			aStartDate++;
		}
	}
	else
	{
		void* p = pTable->First();
		while ( p )
		{
			Date aDate( pTable->GetCurKey() );
			if ( aDate > aEndDate )
				break;

			if ( aDate >= aStartDate )
				pTable->Remove( aDate.GetDate() );
			else
				p = pTable->Next();
		}
	}
}

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

static void ImplCalendarUnSelectDateRange( Table* pTable,
										   Table* pOldTable,
										   const Date& rStartDate,
										   const Date& rEndDate )
{
	Date aStartDate = rStartDate;
	Date aEndDate = rEndDate;
	if ( aStartDate > aEndDate )
	{
		Date aTempDate = aStartDate;
		aStartDate = aEndDate;
		aEndDate = aTempDate;
	}

	void* p = pTable->First();
	while ( p )
	{
		Date aDate( pTable->GetCurKey() );
		if ( aDate > aEndDate )
			break;

		if ( aDate >= aStartDate )
			pTable->Remove( aDate.GetDate() );
		else
			p = pTable->Next();
	}

	p = pOldTable->First();
	while ( p )
	{
		Date aDate( pOldTable->GetCurKey() );
		if ( aDate > aEndDate )
			break;
		if ( aDate >= aStartDate )
			pTable->Insert( aDate.GetDate(), TABLE_DATE_SELECTED );

		p = pOldTable->Next();
	}
}

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

inline void ImplCalendarClearSelectDate( Table* pTable )
{
	pTable->Clear();
}

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

void Calendar::ImplInit( WinBits nWinStyle )
{
	mpDateTable 			= NULL;
	mpSelectTable			= new Table;
	mpOldSelectTable		= NULL;
	mpRestoreSelectTable	= NULL;
	mpStandardColor 		= NULL;
	mpSaturdayColor 		= NULL;
	mpSundayColor			= NULL;
	mnDayCount				= 0;
	mnWinStyle				= nWinStyle;
	mnFirstYear 			= 0;
	mnLastYear				= 0;
	mnRequestYear			= 0;
	mbCalc					= sal_True;
	mbFormat				= sal_True;
	mbDrag					= sal_False;
	mbSelection 			= sal_False;
	mbMultiSelection		= sal_False;
	mbWeekSel				= sal_False;
	mbUnSel 				= sal_False;
	mbMenuDown				= sal_False;
	mbSpinDown				= sal_False;
	mbPrevIn				= sal_False;
	mbNextIn				= sal_False;
	mbDirect				= sal_False;
	mbInSelChange			= sal_False;
	mbTravelSelect			= sal_False;
	mbScrollDateRange		= sal_False;
	mbSelLeft				= sal_False;
	mbAllSel				= sal_False;
	mbDropPos				= sal_False;

    ::rtl::OUString aGregorian( RTL_CONSTASCII_USTRINGPARAM( "gregorian"));
    maCalendarWrapper.loadCalendar( aGregorian,
            Application::GetAppLocaleDataWrapper().getLocale());
    if (maCalendarWrapper.getUniqueID() != aGregorian)
    {
#ifdef DBG_UTIL
        ByteString aMsg( "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``");
        lang::Locale aLoc( Application::GetAppLocaleDataWrapper().getLocale());
        aMsg += ByteString( String( aLoc.Language), RTL_TEXTENCODING_UTF8);
        aMsg += '-';
        aMsg += ByteString( String( aLoc.Country), RTL_TEXTENCODING_UTF8);
        aMsg += "'' and other calendars aren't supported. Using en-US fallback.";
        DBG_ERRORFILE( aMsg.GetBuffer());
#endif
        /* If we ever wanted to support other calendars than Gregorian a lot of
         * rewrite would be necessary to internally replace use of class Date
         * with proper class CalendarWrapper methods, get rid of fixed 12
         * months, fixed 7 days, ... */
        maCalendarWrapper.loadCalendar( aGregorian, lang::Locale(
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "en")),
                    ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "US")),
                    ::rtl::OUString()));
    }

	SetFirstDate( maCurDate );
	ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True );

	// Sonstige Strings erzeugen
	maDayText = XubString( SvtResId( STR_SVT_CALENDAR_DAY ) );
	maWeekText = XubString( SvtResId( STR_SVT_CALENDAR_WEEK ) );

	// Tagestexte anlegen
	for ( sal_uInt16 i = 0; i < 31; i++ )
		mpDayText[i] = new UniString( UniString::CreateFromInt32( i+1 ) );

	maDragScrollTimer.SetTimeoutHdl( STATIC_LINK( this, Calendar, ScrollHdl ) );
	maDragScrollTimer.SetTimeout( GetSettings().GetMouseSettings().GetScrollRepeat() );
	mnDragScrollHitTest = 0;

	ImplInitSettings();
}

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

void Calendar::ImplInitSettings()
{
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	maSelColor = rStyleSettings.GetHighlightTextColor();
	SetPointFont( rStyleSettings.GetToolFont() );
	SetTextColor( rStyleSettings.GetFieldTextColor() );
	SetBackground( Wallpaper( rStyleSettings.GetFieldColor() ) );
}

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

Calendar::Calendar( Window* pParent, WinBits nWinStyle ) :
	Control( pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK | WB_RANGESELECT | WB_MULTISELECT) ),
	maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
	maOldFormatFirstDate( 0, 0, 1900 ),
	maOldFormatLastDate( 0, 0, 1900 ),
	maFirstDate( 0, 0, 1900 ),
	maOldFirstDate( 0, 0, 1900 ),
	maOldCurDate( 0, 0, 1900 ),
	maAnchorDate( maCurDate ),
	maDropDate( 0, 0, 1900 )
{
	ImplInit( nWinStyle );
}

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

Calendar::Calendar( Window* pParent, const ResId& rResId ) :
	Control( pParent, rResId ),
	maCalendarWrapper( Application::GetAppLocaleDataWrapper().getServiceFactory() ),
	maOldFormatFirstDate( 0, 0, 1900 ),
	maOldFormatLastDate( 0, 0, 1900 ),
	maFirstDate( 0, 0, 1900 ),
	maOldFirstDate( 0, 0, 1900 ),
	maOldCurDate( 0, 0, 1900 ),
	maAnchorDate( maCurDate ),
	maDropDate( 0, 0, 1900 )
{
	ImplInit( rResId.GetWinBits() );
}

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

Calendar::~Calendar()
{
	delete mpStandardColor;
	delete mpSaturdayColor;
	delete mpSundayColor;

	if ( mpDateTable )
	{
		ImplDateInfo* pDateInfo = mpDateTable->First();
		while ( pDateInfo )
		{
			delete pDateInfo;
			pDateInfo = mpDateTable->Next();
		}

		delete mpDateTable;
	}

	delete mpSelectTable;
	if ( mpOldSelectTable )
		delete mpOldSelectTable;
	if ( mpRestoreSelectTable )
		delete mpRestoreSelectTable;

	for ( sal_uInt16 i = 0; i < 31; i++ )
		delete mpDayText[i];
}

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

void Calendar::SetMinimumNumberOfDaysInWeek( sal_Int16 nDays )
{
    ImplUpdate( sal_True );
    maCalendarWrapper.setMinimumNumberOfDaysForFirstWeek( nDays);
}

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

void Calendar::SetWeekStart( sal_Int16 nDay )
{
    ImplUpdate( sal_True );
    switch (nDay)
    {
        case i18n::Weekdays::SUNDAY :
        case i18n::Weekdays::MONDAY :
        case i18n::Weekdays::TUESDAY :
        case i18n::Weekdays::WEDNESDAY :
        case i18n::Weekdays::THURSDAY :
        case i18n::Weekdays::FRIDAY :
        case i18n::Weekdays::SATURDAY :
            ;   // nothing
        default:
            DBG_ERRORFILE("Calendar::SetWeekStart: unknown value for setFirstDayOfWeek() of a Gregorian calendar");
            nDay = i18n::Weekdays::SUNDAY;
    }
    maCalendarWrapper.setFirstDayOfWeek( nDay);
}

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

DayOfWeek Calendar::ImplGetWeekStart() const
{
    // Map i18n::Weekdays to Date DayOfWeek
    DayOfWeek eDay;
    sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
    switch (nDay)
    {
        case i18n::Weekdays::SUNDAY :
            eDay = SUNDAY;
            break;
        case i18n::Weekdays::MONDAY :
            eDay = MONDAY;
            break;
        case i18n::Weekdays::TUESDAY :
            eDay = TUESDAY;
            break;
        case i18n::Weekdays::WEDNESDAY :
            eDay = WEDNESDAY;
            break;
        case i18n::Weekdays::THURSDAY :
            eDay = THURSDAY;
            break;
        case i18n::Weekdays::FRIDAY :
            eDay = FRIDAY;
            break;
        case i18n::Weekdays::SATURDAY :
            eDay = SATURDAY;
            break;
        default:
            DBG_ERRORFILE("Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
            eDay = SUNDAY;
    }
    return eDay;
}

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

void Calendar::ImplGetWeekFont( Font& rFont ) const
{
	// Wochennummer geben wir in WEEKNUMBER_HEIGHT%-Fonthoehe aus
	Size aFontSize = rFont.GetSize();
	aFontSize.Height() *= WEEKNUMBER_HEIGHT;
	aFontSize.Height() /= 100;
	rFont.SetSize( aFontSize );
	rFont.SetWeight( WEIGHT_NORMAL );
}

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

void Calendar::ImplFormat()
{
	if ( !mbFormat )
		return;

	if ( mbCalc )
	{
		Size aOutSize = GetOutputSizePixel();

		if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) )
			return;

		XubString a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );

		Font aOldFont = GetFont();

		// Wochenanzeige beruecksichtigen
		if ( mnWinStyle & WB_WEEKNUMBER )
		{
			Font aTempFont = aOldFont;
			ImplGetWeekFont( aTempFont );
			SetFont( aTempFont );
			mnWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
			SetFont( aOldFont );
		}
		else
			mnWeekWidth = 0;

		if ( mnWinStyle & WB_BOLDTEXT )
		{
			Font aFont = aOldFont;
			if ( aFont.GetWeight() < WEIGHT_BOLD )
				aFont.SetWeight( WEIGHT_BOLD );
			else
				aFont.SetWeight( WEIGHT_NORMAL );
			SetFont( aFont );
		}

		long n99TextWidth = GetTextWidth( a99Text );
		long nTextHeight = GetTextHeight();

		// Breiten und X-Positionen berechnen
		mnDayWidth		= n99TextWidth+DAY_OFFX;
		mnMonthWidth	= mnDayWidth*7;
		mnMonthWidth   += mnWeekWidth;
		mnMonthWidth   += MONTH_BORDERX*2;
		mnMonthPerLine	= aOutSize.Width() / mnMonthWidth;
		if ( !mnMonthPerLine )
			mnMonthPerLine = 1;
		long nOver		= ((aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine);
		mnMonthWidth   += nOver;
		mnDaysOffX		= MONTH_BORDERX;
		mnDaysOffX	   += nOver/2;
		mnDaysOffX	   += mnWeekWidth;

		// Hoehen und Y-Positionen berechnen
		mnDayHeight 	= nTextHeight + DAY_OFFY;
		mnWeekDayOffY	= nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
		mnDaysOffY		= mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY;
		mnMonthHeight	= (mnDayHeight*6) + mnDaysOffY;
		mnMonthHeight  += MONTH_OFFY;
		mnLines 		= aOutSize.Height() / mnMonthHeight;
		if ( !mnLines )
			mnLines = 1;
		mnMonthHeight  += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines;

		// Spinfelder berechnen
		long nSpinSize		= nTextHeight+TITLE_BORDERY-SPIN_OFFY;
		maPrevRect.Left()	= SPIN_OFFX;
		maPrevRect.Top()	= SPIN_OFFY;
		maPrevRect.Right()	= maPrevRect.Left()+nSpinSize;
		maPrevRect.Bottom() = maPrevRect.Top()+nSpinSize;
		maNextRect.Left()	= aOutSize.Width()-SPIN_OFFX-nSpinSize-1;
		maNextRect.Top()	= SPIN_OFFY;
		maNextRect.Right()	= maNextRect.Left()+nSpinSize;
		maNextRect.Bottom() = maNextRect.Top()+nSpinSize;

		if ( mnWinStyle & WB_BOLDTEXT )
			SetFont( aOldFont );

		// Calculate DayOfWeekText (gets displayed in a narrow font)
		maDayOfWeekText.Erase();
		long nStartOffX = 0;
		sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
		for ( sal_Int16 nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ )
		{
            // Use first character of full name, since the abbreviated name may
            // be roman digits or similar in some locales. Proper
            // implementation would need narrow one letter month names defined
            // in locale data.
            String aDayOfWeek( maCalendarWrapper.getDisplayName(
                        i18n::CalendarDisplayIndex::DAY, nDay, 1).GetChar(0));
			long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2;
			if ( mnWinStyle & WB_BOLDTEXT )
				nOffX++;
			if ( !nDayOfWeek )
				nStartOffX = nOffX;
			else
				nOffX -= nStartOffX;
			nOffX += nDayOfWeek * mnDayWidth;
			mnDayOfWeekAry[nDayOfWeek] = nOffX;
			maDayOfWeekText += aDayOfWeek;
			nDay++;
			nDay %= 7;
		}

		mbCalc = sal_False;
	}

	// Anzahl Tage berechnen

    DayOfWeek eStartDay = ImplGetWeekStart();

	sal_uInt16 nWeekDay;
	Date aTempDate = GetFirstMonth();
	maFirstDate = aTempDate;
	nWeekDay = (sal_uInt16)aTempDate.GetDayOfWeek();
	nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
	maFirstDate -= (sal_uLong)nWeekDay;
	mnDayCount = nWeekDay;
	sal_uInt16 nDaysInMonth;
	sal_uInt16 nMonthCount = (sal_uInt16)(mnMonthPerLine*mnLines);
	for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
	{
		nDaysInMonth = aTempDate.GetDaysInMonth();
		mnDayCount += nDaysInMonth;
		aTempDate += nDaysInMonth;
	}
	Date aTempDate2 = aTempDate;
	aTempDate2--;
	nDaysInMonth = aTempDate2.GetDaysInMonth();
	aTempDate2 -= nDaysInMonth-1;
	nWeekDay = (sal_uInt16)aTempDate2.GetDayOfWeek();
	nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
	mnDayCount += 42-nDaysInMonth-nWeekDay;

	// Farben festlegen
	maOtherColor = Color( COL_LIGHTGRAY );
	if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) )
		maOtherColor.SetColor( COL_GRAY );

	Date aLastDate = GetLastDate();
	if ( (maOldFormatLastDate != aLastDate) ||
		 (maOldFormatFirstDate != maFirstDate) )
	{
		maOldFormatFirstDate = maFirstDate;
		maOldFormatLastDate  = aLastDate;
		DateRangeChanged();
	}

	// DateInfo besorgen
	sal_uInt16 nNewFirstYear = maFirstDate.GetYear();
	sal_uInt16 nNewLastYear = GetLastDate().GetYear();
	if ( mnFirstYear )
	{
		if ( nNewFirstYear < mnFirstYear )
		{
			for ( mnRequestYear = nNewFirstYear; mnRequestYear < mnFirstYear; mnRequestYear++ )
				RequestDateInfo();
			mnFirstYear = nNewFirstYear;
		}
		if ( nNewLastYear > mnLastYear )
		{
			for ( mnRequestYear = mnLastYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
				RequestDateInfo();
			mnLastYear = nNewLastYear;
		}
	}
	else
	{
		for ( mnRequestYear = nNewFirstYear; mnRequestYear < nNewLastYear; mnRequestYear++ )
			RequestDateInfo();
		mnFirstYear = nNewFirstYear;
		mnLastYear = nNewLastYear;
	}
	mnRequestYear = 0;

	mbFormat = sal_False;
}

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

sal_uInt16 Calendar::ImplHitTest( const Point& rPos, Date& rDate ) const
{
	if ( mbFormat )
		return 0;

	if ( maPrevRect.IsInside( rPos ) )
		return CALENDAR_HITTEST_PREV;
	else if ( maNextRect.IsInside( rPos ) )
		return CALENDAR_HITTEST_NEXT;

	long		nX;
	long		nY;
	long		nOffX;
	long		nYMonth;
	sal_uInt16		nDay;
	DayOfWeek	eStartDay = ImplGetWeekStart();

	rDate = GetFirstMonth();
	nY = 0;
	for ( long i = 0; i < mnLines; i++ )
	{
		if ( rPos.Y() < nY )
			return 0;

		nX = 0;
		nYMonth = nY+mnMonthHeight;
		for ( long j = 0; j < mnMonthPerLine; j++ )
		{
			if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) )
				return 0;

			sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth();

			// Entsprechender Monat gefunden
			if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) &&
				 (rPos.X() < nX+mnMonthWidth) )
			{
				if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight))
					return CALENDAR_HITTEST_MONTHTITLE;
				else
				{
					long nDayX = nX+mnDaysOffX;
					long nDayY = nY+mnDaysOffY;
					if ( rPos.Y() < nDayY )
						return 0;
					sal_uInt16 nDayIndex = (sal_uInt16)rDate.GetDayOfWeek();
					nDayIndex = (nDayIndex+(7-(sal_uInt16)eStartDay)) % 7;
					if ( (i == 0) && (j == 0) )
					{
						Date aTempDate = rDate;
						aTempDate -= nDayIndex;
						for ( nDay = 0; nDay < nDayIndex; nDay++ )
						{
							nOffX = nDayX + (nDay*mnDayWidth);
							if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
								 (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
							{
								rDate = aTempDate;
								rDate += nDay;
								return CALENDAR_HITTEST_DAY;
							}
						}
					}
					for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
					{
						if ( rPos.Y() < nDayY )
						{
							rDate += nDayIndex;
							return 0;
						}
						nOffX = nDayX + (nDayIndex*mnDayWidth);
						if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
							 (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
						{
							rDate += nDay-1;
							return CALENDAR_HITTEST_DAY;
						}
						if ( nDayIndex == 6 )
						{
							nDayIndex = 0;
							nDayY += mnDayHeight;
						}
						else
							nDayIndex++;
					}
					if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
					{
						sal_uInt16 nWeekDay = (sal_uInt16)rDate.GetDayOfWeek();
						nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
						sal_uInt16 nDayCount = 42-nDaysInMonth-nWeekDay;
						Date aTempDate = rDate;
						aTempDate += nDaysInMonth;
						for ( nDay = 1; nDay <= nDayCount; nDay++ )
						{
							if ( rPos.Y() < nDayY )
							{
								rDate += nDayIndex;
								return 0;
							}
							nOffX = nDayX + (nDayIndex*mnDayWidth);
							if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
								 (rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
							{
								rDate = aTempDate;
								rDate += nDay-1;
								return CALENDAR_HITTEST_DAY;
							}
							if ( nDayIndex == 6 )
							{
								nDayIndex = 0;
								nDayY += mnDayHeight;
							}
							else
								nDayIndex++;
						}
					}
				}
			}

			rDate += nDaysInMonth;
			nX += mnMonthWidth;
		}

		nY += mnMonthHeight;
	}

	return 0;
}

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

static void ImplDrawSpinArrow( OutputDevice* pDev, const Rectangle& rRect,
							   sal_Bool bPrev )
{
	long	i;
	long	n;
	long	nLines;
	long	nHeight = rRect.GetHeight();
	long	nWidth = rRect.GetWidth();
	if ( nWidth < nHeight )
		n = nWidth;
	else
		n = nHeight;
	if ( !(n & 0x01) )
		n--;
	nLines = n/2;

	Rectangle aRect( Point( rRect.Left()+(nWidth/2)-(nLines/2),
							rRect.Top()+(nHeight/2) ),
					 Size( 1, 1 ) );
	if ( !bPrev )
	{
		aRect.Left()  += nLines;
		aRect.Right() += nLines;
	}

	pDev->DrawRect( aRect );
	for ( i = 0; i < nLines; i++ )
	{
		if ( bPrev )
		{
			aRect.Left()++;
			aRect.Right()++;
		}
		else
		{
			aRect.Left()--;
			aRect.Right()--;
		}
		aRect.Top()--;
		aRect.Bottom()++;
		pDev->DrawRect( aRect );
	}
}

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

void Calendar::ImplDrawSpin( sal_Bool bDrawPrev, sal_Bool bDrawNext )
{
	if ( !bDrawPrev && !bDrawNext )
		return;

	SetLineColor();
	SetFillColor( GetSettings().GetStyleSettings().GetButtonTextColor() );
	if ( bDrawPrev )
	{
		Rectangle aOutRect = maPrevRect;
		aOutRect.Left()   += 3;
		aOutRect.Top()	  += 3;
		aOutRect.Right()  -= 3;
		aOutRect.Bottom() -= 3;
		ImplDrawSpinArrow( this, aOutRect, sal_True );
	}
	if ( bDrawNext )
	{
		Rectangle aOutRect = maNextRect;
		aOutRect.Left()   += 3;
		aOutRect.Top()	  += 3;
		aOutRect.Right()  -= 3;
		aOutRect.Bottom() -= 3;
		ImplDrawSpinArrow( this, aOutRect, sal_False );
	}
}

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

void Calendar::ImplDrawDate( long nX, long nY,
							 sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear,
							 DayOfWeek eDayOfWeek,
							 sal_Bool bBack, sal_Bool bOther, sal_uLong nToday )
{
	ImplDateInfo*	pDateInfo;
	Color*			pTextColor = NULL;
	const String&	rDay = *(mpDayText[nDay-1]);
	Rectangle		aDateRect( nX, nY, nX+mnDayWidth-1, nY+mnDayHeight-1 );

	sal_Bool bSel = sal_False;
	sal_Bool bFocus = sal_False;
	// Aktueller Tag
	if ( (nDay	 == maCurDate.GetDay()) &&
		 (nMonth == maCurDate.GetMonth()) &&
		 (nYear  == maCurDate.GetYear()) )
		bFocus = sal_True;
	if ( mpSelectTable )
	{
		if ( mpSelectTable->IsKeyValid( Date( nDay, nMonth, nYear ).GetDate() ) )
			bSel = sal_True;
	}

	// Dateinfo ermitteln
	if ( mpDateTable )
	{
		pDateInfo = mpDateTable->Get( Date( nDay, nMonth, nYear ).GetDate() );
		if ( !pDateInfo )
			pDateInfo = mpDateTable->Get( Date( nDay, nMonth, 0 ).GetDate() );
	}
	else
		pDateInfo = NULL;

	// Textfarbe ermitteln
	if ( bSel )
		pTextColor = &maSelColor;
	else if ( bOther )
		pTextColor = &maOtherColor;
	else
	{
		if ( pDateInfo && pDateInfo->mpTextColor )
			pTextColor = pDateInfo->mpTextColor;
		else
		{
			if ( eDayOfWeek == SATURDAY )
				pTextColor = mpSaturdayColor;
			else if ( eDayOfWeek == SUNDAY )
				pTextColor = mpSundayColor;
			if ( !pTextColor )
				pTextColor = mpStandardColor;
		}
	}

	if ( bFocus )
		HideFocus();

	// Font ermitteln
	Font aOldFont = GetFont();
	sal_Bool bBoldFont = sal_False;
	if ( (mnWinStyle & WB_BOLDTEXT) &&
		 pDateInfo && (pDateInfo->mnFlags & DIB_BOLD) )
	{
		bBoldFont = sal_True;
		Font aFont = aOldFont;
		if ( aFont.GetWeight() < WEIGHT_BOLD )
			aFont.SetWeight( WEIGHT_BOLD );
		else
			aFont.SetWeight( WEIGHT_NORMAL );
		SetFont( aFont );
	}

	// Hintergrund ausgeben
	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	if ( bSel || bBack )
	{
		if ( bSel )
		{
			SetLineColor();
			SetFillColor( rStyleSettings.GetHighlightColor() );
			DrawRect( aDateRect );
		}
		else
			Erase( aDateRect );
	}

	// Text ausgeben
	long nTextX = nX+(mnDayWidth-GetTextWidth( rDay ))-(DAY_OFFX/2);
	long nTextY = nY+(mnDayHeight-GetTextHeight())/2;
	if ( pTextColor )
	{
		Color aOldColor = GetTextColor();
		SetTextColor( *pTextColor );
		DrawText( Point( nTextX, nTextY ), rDay );
		SetTextColor( aOldColor );
	}
	else
		DrawText( Point( nTextX, nTextY ), rDay );

	// Heute
	Date aTodayDate( maCurDate );
	if ( nToday )
		aTodayDate.SetDate( nToday );
	else
		aTodayDate = Date();
	if ( (nDay	 == aTodayDate.GetDay()) &&
		 (nMonth == aTodayDate.GetMonth()) &&
		 (nYear  == aTodayDate.GetYear()) )
	{
		SetLineColor( rStyleSettings.GetWindowTextColor() );
		SetFillColor();
		DrawRect( aDateRect );
	}

	// Evt. DateInfo ausgeben
	if ( (mnWinStyle & WB_FRAMEINFO) && pDateInfo && pDateInfo->mpFrameColor )
	{
		SetLineColor( *(pDateInfo->mpFrameColor) );
		SetFillColor();
		Rectangle aFrameRect( aDateRect );
		aFrameRect.Left()++;
		aFrameRect.Top()++;
		long nFrameWidth = aFrameRect.GetWidth();
		long nFrameHeight = aFrameRect.GetHeight();
		long nFrameOff;
		if ( nFrameWidth < nFrameHeight )
		{
			nFrameOff = nFrameHeight-nFrameWidth;
			aFrameRect.Top() += nFrameOff/2;
			nFrameOff %= 2;
			aFrameRect.Bottom() -= nFrameOff;
		}
		else if ( nFrameWidth > nFrameHeight )
		{
			nFrameOff = nFrameWidth-nFrameHeight;
			aFrameRect.Left() += nFrameOff/2;
			nFrameOff %= 2;
			aFrameRect.Right() -= nFrameOff;
		}
		DrawEllipse( aFrameRect );
	}

	// Evt. noch FocusRect
	if ( bFocus && HasFocus() )
		ShowFocus( aDateRect );

	if( mbDropPos && maDropDate == Date( nDay, nMonth, nYear ) )
		ImplInvertDropPos();

	if ( bBoldFont )
		SetFont( aOldFont );
}

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

void Calendar::ImplDraw( sal_Bool bPaint )
{
	ImplFormat();

	const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
	Size		aOutSize = GetOutputSizePixel();
	long		i;
	long		j;
	long		nX;
	long		nY;
	long		nDeltaX;
	long		nDeltaY;
	long		nDayX;
	long		nDayY;
	sal_uLong		nToday = Date().GetDate();
	sal_uInt16		nDay;
	sal_uInt16		nMonth;
	sal_uInt16		nYear;
	Date		aDate = GetFirstMonth();
	DayOfWeek	eStartDay = ImplGetWeekStart();

	HideFocus();

	nY = 0;
	for ( i = 0; i < mnLines; i++ )
	{
		// Titleleiste ausgeben
		SetLineColor();
		SetFillColor( rStyleSettings.GetFaceColor() );
		Rectangle aTitleRect( 0, nY, aOutSize.Width()-1, nY+mnDayHeight-DAY_OFFY+TITLE_BORDERY*2 );
		if ( !bPaint )
		{
			Rectangle aTempRect( 1, aTitleRect.Top()+TITLE_BORDERY,
								 aOutSize.Width()-2,
								 aTitleRect.Bottom()-TITLE_BORDERY );
			if ( !i )
			{
				aTempRect.Left()  = maPrevRect.Right()+1;
				aTempRect.Right() = maNextRect.Left()-1;
			}
			DrawRect( aTempRect );
		}
		else
		{
			DrawRect( aTitleRect );
			Point aTopLeft1( aTitleRect.Left(), aTitleRect.Top() );
			Point aTopLeft2( aTitleRect.Left(), aTitleRect.Top()+1 );
			Point aBottomRight1( aTitleRect.Right(), aTitleRect.Bottom() );
			Point aBottomRight2( aTitleRect.Right(), aTitleRect.Bottom()-1 );
			SetLineColor( rStyleSettings.GetDarkShadowColor() );
			DrawLine( aTopLeft1, Point( aBottomRight1.X(), aTopLeft1.Y() ) );
			SetLineColor( rStyleSettings.GetLightColor() );
			DrawLine( aTopLeft2, Point( aBottomRight2.X(), aTopLeft2.Y() ) );
			DrawLine( aTopLeft2, Point( aTopLeft2.X(), aBottomRight2.Y() ) );
			SetLineColor( rStyleSettings.GetShadowColor() );
			DrawLine( Point( aTopLeft2.X(), aBottomRight2.Y() ), aBottomRight2 );
			DrawLine( Point( aBottomRight2.X(), aTopLeft2.Y() ), aBottomRight2 );
			SetLineColor( rStyleSettings.GetDarkShadowColor() );
			DrawLine( Point( aTopLeft1.X(), aBottomRight1.Y() ), aBottomRight1 );
		}
		Point aSepPos1( 0, aTitleRect.Top()+TITLE_BORDERY );
		Point aSepPos2( 0, aTitleRect.Bottom()-TITLE_BORDERY );
		for ( j = 0; j < mnMonthPerLine-1; j++ )
		{
			aSepPos1.X() += mnMonthWidth-1;
			aSepPos2.X() = aSepPos1.X();
			SetLineColor( rStyleSettings.GetShadowColor() );
			DrawLine( aSepPos1, aSepPos2 );
			aSepPos1.X()++;
			aSepPos2.X() = aSepPos1.X();
			SetLineColor( rStyleSettings.GetLightColor() );
			DrawLine( aSepPos1, aSepPos2 );
		}

		nX = 0;
		for ( j = 0; j < mnMonthPerLine; j++ )
		{
			nMonth	= aDate.GetMonth();
			nYear	= aDate.GetYear();

			// Monat in der Titleleiste ausgeben
			nDeltaX = nX;
			nDeltaY = nY+TITLE_BORDERY;
            String aMonthText( maCalendarWrapper.getDisplayName(
                        i18n::CalendarDisplayIndex::MONTH, nMonth-1, 1));
			aMonthText += ' ';
			aMonthText += String::CreateFromInt64( nYear );
			long nMonthTextWidth = GetTextWidth( aMonthText );
			long nMonthOffX1 = 0;
			long nMonthOffX2 = 0;
			if ( i == 0 )
			{
				if ( j == 0 )
					nMonthOffX1 = maPrevRect.Right()+1;
				if ( j == mnMonthPerLine-1 )
					nMonthOffX2 = aOutSize.Width()-maNextRect.Left()+1;
			}
			long nMaxMonthWidth = mnMonthWidth-nMonthOffX1-nMonthOffX2-4;
			if ( nMonthTextWidth > nMaxMonthWidth )
			{
				// Abbreviated month name.
                aMonthText  = maCalendarWrapper.getDisplayName(
                        i18n::CalendarDisplayIndex::MONTH, nMonth-1, 0);
				aMonthText += ' ';
				aMonthText += String::CreateFromInt64( nYear );
				nMonthTextWidth = GetTextWidth( aMonthText );
			}
			long nTempOff = (mnMonthWidth-nMonthTextWidth+1)/2;
			if ( nTempOff < nMonthOffX1 )
				nDeltaX += nMonthOffX1+1;
			else
			{
				if ( nTempOff+nMonthTextWidth > mnMonthWidth-nMonthOffX2 )
					nDeltaX += mnMonthWidth-nMonthOffX2-nMonthTextWidth;
				else
					nDeltaX += nTempOff;
			}
			SetTextColor( rStyleSettings.GetButtonTextColor() );
			DrawText( Point( nDeltaX, nDeltaY ), aMonthText );
			SetTextColor( rStyleSettings.GetWindowTextColor() );

			// Weekleiste ausgeben
			if ( bPaint )
			{
				nDayX = nX+mnDaysOffX;
				nDayY = nY+mnWeekDayOffY;
				nDeltaY = nDayY + mnDayHeight;
				SetLineColor( rStyleSettings.GetWindowTextColor() );
				Point aStartPos( nDayX, nDeltaY );
				if ( mnWinStyle & WB_WEEKNUMBER )
					aStartPos.X() -= WEEKNUMBER_OFFX-2;
				DrawLine( aStartPos, Point( nDayX+(7*mnDayWidth), nDeltaY ) );
				DrawTextArray( Point( nDayX+mnDayOfWeekAry[0], nDayY ), maDayOfWeekText, &(mnDayOfWeekAry[1]) );
			}

			// Week-Numbers ausgeben
			if ( mnWinStyle & WB_WEEKNUMBER )
			{
				nDayX = nX+mnDaysOffX;
				nDayY = nY+mnWeekDayOffY;
				nDeltaY = nDayY + mnDayHeight;
				long nMonthHeight = mnDayHeight*6;
				if ( bPaint )
					DrawLine( Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY ), Point( nDayX-WEEKNUMBER_OFFX+2, nDeltaY+nMonthHeight ) );
				else
					Erase( Rectangle( nDayX-mnWeekWidth-WEEKNUMBER_OFFX, nDeltaY, nDayX-WEEKNUMBER_OFFX-1, nDeltaY+nMonthHeight ) );

				Font aOldFont = GetFont();
				Font aTempFont = aOldFont;
				ImplGetWeekFont( aTempFont );
				SetFont( aTempFont );
				nDayX -= mnWeekWidth;
				nDayY = nY+mnDaysOffY;
                maCalendarWrapper.setGregorianDateTime( aDate);
				for ( sal_uInt16 nWeekCount = 0; nWeekCount < 6; nWeekCount++ )
				{
                    sal_Int16 nWeek = maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
					String	aWeekText( String::CreateFromInt32( nWeek));
					long	nOffX = (mnWeekWidth-WEEKNUMBER_OFFX)-GetTextWidth( aWeekText );
					long	nOffY = (mnDayHeight-GetTextHeight())/2;
					DrawText( Point( nDayX+nOffX, nDayY+nOffY ), aWeekText );
					nDayY += mnDayHeight;
                    maCalendarWrapper.addValue( i18n::CalendarFieldIndex::DAY_OF_MONTH, 7);
				}
				SetFont( aOldFont );
			}

			// Tage ausgeben
			sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
			nDayX = nX+mnDaysOffX;
			nDayY = nY+mnDaysOffY;
			if ( !bPaint )
			{
				Rectangle aClearRect( nDayX, nDayY,
									  nDayX+(7*mnDayWidth)-1, nDayY+(6*mnDayHeight)-1 );
				Erase( aClearRect );
			}
			sal_uInt16 nDayIndex = (sal_uInt16)aDate.GetDayOfWeek();
			nDayIndex = (nDayIndex+(7-(sal_uInt16)eStartDay)) % 7;
			if ( (i == 0) && (j == 0) )
			{
				Date aTempDate = aDate;
				aTempDate -= nDayIndex;
				for ( nDay = 0; nDay < nDayIndex; nDay++ )
				{
					nDeltaX = nDayX + (nDay*mnDayWidth);
					ImplDrawDate( nDeltaX, nDayY, nDay+aTempDate.GetDay(),
								  aTempDate.GetMonth(), aTempDate.GetYear(),
								  (DayOfWeek)((nDay+(sal_uInt16)eStartDay)%7), sal_False, sal_True, nToday );
				}
			}
			for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
			{
				nDeltaX = nDayX + (nDayIndex*mnDayWidth);
				ImplDrawDate( nDeltaX, nDayY, nDay, nMonth, nYear,
							  (DayOfWeek)((nDayIndex+(sal_uInt16)eStartDay)%7),
							  sal_False, sal_False, nToday );
				if ( nDayIndex == 6 )
				{
					nDayIndex = 0;
					nDayY += mnDayHeight;
				}
				else
					nDayIndex++;
			}
			if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
			{
				sal_uInt16 nWeekDay = (sal_uInt16)aDate.GetDayOfWeek();
				nWeekDay = (nWeekDay+(7-(sal_uInt16)eStartDay)) % 7;
				sal_uInt16 nDayCount = 42-nDaysInMonth-nWeekDay;
				Date aTempDate = aDate;
				aTempDate += nDaysInMonth;
				for ( nDay = 1; nDay <= nDayCount; nDay++ )
				{
					nDeltaX = nDayX + (nDayIndex*mnDayWidth);
					ImplDrawDate( nDeltaX, nDayY, nDay,
								  aTempDate.GetMonth(), aTempDate.GetYear(),
								  (DayOfWeek)((nDayIndex+(sal_uInt16)eStartDay)%7),
								  sal_False, sal_True, nToday );
					if ( nDayIndex == 6 )
					{
						nDayIndex = 0;
						nDayY += mnDayHeight;
					}
					else
						nDayIndex++;
				}
			}

			aDate += nDaysInMonth;
			nX += mnMonthWidth;
		}

		nY += mnMonthHeight;
	}

	// Spin-Buttons zeichnen
	if ( bPaint )
		ImplDrawSpin();
}

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

void Calendar::ImplUpdateDate( const Date& rDate )
{
	if ( IsReallyVisible() && IsUpdateMode() )
	{
		Rectangle aDateRect( GetDateRect( rDate ) );
		if ( !aDateRect.IsEmpty() )
		{
			sal_Bool bOther = (rDate < GetFirstMonth()) || (rDate > GetLastMonth());
			ImplDrawDate( aDateRect.Left(), aDateRect.Top(),
						  rDate.GetDay(), rDate.GetMonth(), rDate.GetYear(),
						  rDate.GetDayOfWeek(), sal_True, bOther );
		}
	}
}

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

void Calendar::ImplUpdateSelection( Table* pOld )
{
	Table*	pNew = mpSelectTable;
	void*	p;
	sal_uLong	nKey;

	p = pOld->First();
	while ( p )
	{
		nKey = pOld->GetCurKey();
		if ( !pNew->Get( nKey ) )
		{
			Date aTempDate( nKey );
			ImplUpdateDate( aTempDate );
		}

		p = pOld->Next();
	}

	p = pNew->First();
	while ( p )
	{
		nKey = pNew->GetCurKey();
		if ( !pOld->Get( nKey ) )
		{
			Date aTempDate( nKey );
			ImplUpdateDate( aTempDate );
		}

		p = pNew->Next();
	}
}

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

void Calendar::ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest,
								sal_Bool bMove, sal_Bool bExpand, sal_Bool bExtended )
{
	Table*	pOldSel = new Table( *mpSelectTable );
	Date	aOldDate = maCurDate;
	Date	aTempDate = rDate;

	if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
		aTempDate--;

	if ( mbMultiSelection )
	{
		maCurDate = aTempDate;
		mbSelLeft = aTempDate < maAnchorDate;

		if ( bMove )
		{
			if ( mbSelLeft )
			{
				ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), aTempDate );
				ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, maAnchorDate, Date( 31, 12, 9999 ) );
			}
			else
			{
				ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, Date( 1, 1, 0 ), maAnchorDate );
				ImplCalendarUnSelectDateRange( mpSelectTable, mpRestoreSelectTable, aTempDate, Date( 31, 12, 9999 ) );
			}
			ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, !mbUnSel );
		}
		else
		{
			if ( bExpand )
			{
				if ( !bExtended )
				{
					if ( mbSelLeft )
					{
						ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aTempDate, sal_False );
						ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), sal_False );
					}
					else
					{
						ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, sal_False );
						ImplCalendarSelectDateRange( mpSelectTable, aTempDate, Date( 31, 12, 9999 ), sal_False );
					}
				}
				ImplCalendarSelectDateRange( mpSelectTable, aTempDate, maAnchorDate, sal_True );
			}
			else if ( bExtended && !(mnWinStyle & WB_RANGESELECT) )
			{
				maAnchorDate = aTempDate;
				if ( IsDateSelected( aTempDate ) )
				{
					mbUnSel = sal_True;
					ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_False );
				}
				else
				{
					ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_True );
				}
			}
			else
			{
				maAnchorDate = aTempDate;
				ImplCalendarClearSelectDate( mpSelectTable );
				ImplCalendarSelectDate( mpSelectTable, aTempDate, sal_True );
			}

			mpRestoreSelectTable = new Table( *mpSelectTable );
		}
	}
	else
	{
		if ( aTempDate < maCurDate )
			mbSelLeft = sal_True;
		else
			mbSelLeft = sal_False;
		if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
			aTempDate = maOldCurDate;
		if ( !bMove )
			maAnchorDate = aTempDate;
		if ( aTempDate != maCurDate )
		{
			maCurDate = aTempDate;
			ImplCalendarSelectDate( mpSelectTable, aOldDate, sal_False );
			ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True );
		}
	}

	sal_Bool bNewSel = *pOldSel != *mpSelectTable;
	if ( (maCurDate != aOldDate) || bNewSel )
	{
		if ( bNewSel )
		{
			mbInSelChange = sal_True;
			SelectionChanging();
			mbInSelChange = sal_False;
		}
		HideFocus();
		if ( bNewSel )
			ImplUpdateSelection( pOldSel );
		if ( !bNewSel || !pOldSel->Get( aOldDate.GetDate() ) )
			ImplUpdateDate( aOldDate );
		// Damit Focus-Rechteck auch wieder neu ausgegeben wird
		if ( HasFocus() || !bNewSel || !mpSelectTable->Get( maCurDate.GetDate() ) )
			ImplUpdateDate( maCurDate );
	}
	delete pOldSel;
}

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

void Calendar::ImplUpdate( sal_Bool bCalcNew )
{
	if ( IsReallyVisible() && IsUpdateMode() )
	{
		if ( bCalcNew && !mbCalc )
			Invalidate();
		else if ( !mbFormat && !mbCalc )
		{
			if ( mbDirect )
			{
				mbFormat = sal_True;
				ImplDraw( sal_False );
				return;
			}
			else
				Invalidate();
		}
	}

	if ( bCalcNew )
		mbCalc = sal_True;
	mbFormat = sal_True;
}

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

void Calendar::ImplInvertDropPos()
{
	Rectangle aRect = GetDateRect( maDropDate );//this is one Pixel to width and one to heigh
	aRect.Bottom() = aRect.Top()+mnDayHeight-1;
	aRect.Right() = aRect.Left()+mnDayWidth-1;
	Invert( aRect );
}

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

void Calendar::ImplScroll( sal_Bool bPrev )
{
	Date aNewFirstMonth = GetFirstMonth();
	if ( bPrev )
	{
		aNewFirstMonth--;
		aNewFirstMonth -= aNewFirstMonth.GetDaysInMonth()-1;
	}
	else
		aNewFirstMonth += aNewFirstMonth.GetDaysInMonth();
	mbDirect = sal_True;
	SetFirstDate( aNewFirstMonth );
	mbDirect = sal_False;
}

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

void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
{
	EndSelection();

	Date		aOldFirstDate = GetFirstMonth();
	PopupMenu	aPopupMenu;
	PopupMenu*	pYearPopupMenus[MENU_YEAR_COUNT];
	sal_uInt16		nMonthOff;
	sal_uInt16		nCurItemId;
	sal_uInt16		nYear = rDate.GetYear()-1;
	sal_uInt16		i;
	sal_uInt16		j;
	sal_uInt16		nYearIdCount = 1000;

	nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
	if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
		nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
	else
		nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();

	// Menu aufbauen (Jahre mit verschiedenen Monaten aufnehmen)
	for ( i = 0; i < MENU_YEAR_COUNT; i++ )
	{
		pYearPopupMenus[i] = new PopupMenu;
		for ( j = 1; j <= 12; j++ )
            pYearPopupMenus[i]->InsertItem( nYearIdCount+j,
                    maCalendarWrapper.getDisplayName(
                        i18n::CalendarDisplayIndex::MONTH, j-1, 1));
		aPopupMenu.InsertItem( 10+i, UniString::CreateFromInt32( nYear+i ) );
		aPopupMenu.SetPopupMenu( 10+i, pYearPopupMenus[i] );
		nYearIdCount += 1000;
	}

	mbMenuDown = sal_True;
	nCurItemId = aPopupMenu.Execute( this, rPos );
	mbMenuDown = sal_False;

	// Menu zerstoeren
	aPopupMenu.SetPopupMenu( 2, NULL );
	for ( i = 0; i < MENU_YEAR_COUNT; i++ )
	{
		aPopupMenu.SetPopupMenu( 10+i, NULL );
		delete pYearPopupMenus[i];
	}

	if ( nCurItemId )
	{
		sal_uInt16 nTempMonthOff = nMonthOff % 12;
		sal_uInt16 nTempYearOff = nMonthOff / 12;
		sal_uInt16 nNewMonth = nCurItemId % 1000;
		sal_uInt16 nNewYear = nYear+((nCurItemId-1000)/1000);
		if ( nTempMonthOff < nNewMonth )
			nNewMonth = nNewMonth - nTempMonthOff;
		else
		{
			nNewYear--;
			nNewMonth = 12-(nTempMonthOff-nNewMonth);
		}
		nNewYear = nNewYear - nTempYearOff;
		SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
	}
}

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

void Calendar::ImplTracking( const Point& rPos, sal_Bool bRepeat )
{
	Date	aTempDate = maCurDate;
	sal_uInt16	nHitTest = ImplHitTest( rPos, aTempDate );

	if ( mbSpinDown )
	{
		mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
		mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;

		if ( bRepeat && (mbPrevIn || mbNextIn) )
		{
			mbScrollDateRange = sal_True;
			ImplScroll( mbPrevIn );
			mbScrollDateRange = sal_False;
		}
	}
	else
		ImplMouseSelect( aTempDate, nHitTest, sal_True, sal_False, sal_False );
}

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

void Calendar::ImplEndTracking( sal_Bool bCancel )
{
	sal_Bool bSelection = mbSelection;
	sal_Bool bSpinDown = mbSpinDown;

	mbDrag				= sal_False;
	mbSelection 		= sal_False;
	mbMultiSelection	= sal_False;
	mbUnSel 			= sal_False;
	mbSpinDown			= sal_False;
	mbPrevIn			= sal_False;
	mbNextIn			= sal_False;

	if ( bCancel )
	{
		if ( maOldFirstDate != maFirstDate )
			SetFirstDate( maOldFirstDate );

		if ( !bSpinDown )
		{
			Table*	pOldSel = new Table( *mpSelectTable );
			Date	aOldDate = maCurDate;
			maCurDate		= maOldCurDate;
			*mpSelectTable	= *mpOldSelectTable;
			HideFocus();
			ImplUpdateSelection( pOldSel );
			if ( !pOldSel->Get( aOldDate.GetDate() ) )
				ImplUpdateDate( aOldDate );
			// Damit Focus-Rechteck auch wieder neu ausgegeben wird
			if ( HasFocus() || !mpSelectTable->Get( maCurDate.GetDate() ) )
				ImplUpdateDate( maCurDate );
			delete pOldSel;
		}
	}

	if ( !bSpinDown )
	{
		if ( !bCancel )
		{
			// Feststellen, ob wir sichtbaren Bereich scrollen sollen
			sal_uLong nSelCount = mpSelectTable->Count();
			if ( nSelCount )
			{
				Date aFirstSelDate( mpSelectTable->GetObjectKey( 0 ) );
				Date aLastSelDate( mpSelectTable->GetObjectKey( nSelCount-1 ) );
				if ( aLastSelDate < GetFirstMonth() )
					ImplScroll( sal_True );
				else if ( GetLastMonth() < aFirstSelDate )
					ImplScroll( sal_False );
			}
		}

		if ( mbAllSel ||
			 (!bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable))) )
			Select();

		if ( !bSelection && (mnWinStyle & WB_TABSTOP) && !bCancel )
			GrabFocus();

		delete mpOldSelectTable;
		mpOldSelectTable = NULL;
		delete mpRestoreSelectTable;
		mpRestoreSelectTable = NULL;
	}
}

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

IMPL_STATIC_LINK( Calendar, ScrollHdl, Timer*, EMPTYARG )
{
	sal_Bool bPrevIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_PREV) != 0;
	sal_Bool bNextIn = (pThis->mnDragScrollHitTest & CALENDAR_HITTEST_NEXT) != 0;
	if( bNextIn || bPrevIn )
	{
		pThis->mbScrollDateRange = sal_True;
		pThis->ImplScroll( bPrevIn );
		pThis->mbScrollDateRange = sal_False;
	}
	return 0;
}

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

void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
{
	if ( rMEvt.IsLeft() && !mbMenuDown )
	{
		Date	aTempDate = maCurDate;
		sal_uInt16	nHitTest = ImplHitTest( rMEvt.GetPosPixel(), aTempDate );
		if ( nHitTest )
		{
			if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
				ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
			else
			{
				maOldFirstDate = maFirstDate;

				mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
				mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
				if ( mbPrevIn || mbNextIn )
				{
					mbSpinDown = sal_True;
					mbScrollDateRange = sal_True;
					ImplScroll( mbPrevIn );
					mbScrollDateRange = sal_False;
					// Hier muss BUTTONREPEAT stehen, also nicht wieder
					// auf SCROLLREPEAT aendern, sondern mit TH abklaeren,
					// warum es evtl. anders sein sollte (71775)
					StartTracking( STARTTRACK_BUTTONREPEAT );
				}
				else
				{
					if ( (rMEvt.GetClicks() == 2) && (nHitTest & CALENDAR_HITTEST_DAY) )
						DoubleClick();
					else
					{
						if ( mpOldSelectTable )
							delete mpOldSelectTable;
						maOldCurDate = maCurDate;
						mpOldSelectTable = new Table( *mpSelectTable );

						if ( !mbSelection )
						{
							mbDrag = sal_True;
							StartTracking();
						}

						mbMultiSelection = (mnWinStyle & (WB_MULTISELECT | WB_RANGESELECT)) != 0;
						if ( (nHitTest & CALENDAR_HITTEST_DAY) && mbMultiSelection )
							mbWeekSel = sal_True;
						else
							mbWeekSel = sal_False;
						ImplMouseSelect( aTempDate, nHitTest, sal_False, rMEvt.IsShift(), rMEvt.IsMod1() );
					}
				}
			}
		}

		return;
	}

	Control::MouseButtonDown( rMEvt );
}

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

void Calendar::MouseButtonUp( const MouseEvent& rMEvt )
{
	if ( rMEvt.IsLeft() && mbSelection )
		ImplEndTracking( sal_False );
	else
		Control::MouseButtonUp( rMEvt );
}

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

void Calendar::MouseMove( const MouseEvent& rMEvt )
{
	if ( mbSelection && rMEvt.GetButtons() )
		ImplTracking( rMEvt.GetPosPixel(), sal_False );
	else
		Control::MouseMove( rMEvt );
}

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

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

	if ( rTEvt.IsTrackingEnded() )
		ImplEndTracking( rTEvt.IsTrackingCanceled() );
	else
		ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
}

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

void Calendar::KeyInput( const KeyEvent& rKEvt )
{
	Date	aNewDate = maCurDate;
	sal_Bool	bMultiSel = (mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) != 0;
	sal_Bool	bExpand = rKEvt.GetKeyCode().IsShift();
	sal_Bool	bExtended = rKEvt.GetKeyCode().IsMod1();

	switch ( rKEvt.GetKeyCode().GetCode() )
	{
		case KEY_HOME:
			aNewDate.SetDay( 1 );
			break;

		case KEY_END:
			aNewDate.SetDay( aNewDate.GetDaysInMonth() );
			break;

		case KEY_LEFT:
			aNewDate--;
			break;

		case KEY_RIGHT:
			aNewDate++;
			break;

		case KEY_UP:
			aNewDate -= 7;
			break;

		case KEY_DOWN:
			aNewDate += 7;
			break;

		case KEY_PAGEUP:
			{
			Date aTempDate = aNewDate;
			aTempDate -= aNewDate.GetDay()+1;
			aNewDate -= aTempDate.GetDaysInMonth();
			}
			break;

		case KEY_PAGEDOWN:
			aNewDate += aNewDate.GetDaysInMonth();
			break;

		case KEY_SPACE:
			if ( bMultiSel && !(mnWinStyle & WB_RANGESELECT) )
			{
				if ( !bExpand )
				{
					sal_Bool bDateSel = IsDateSelected( maCurDate );
					SelectDate( maCurDate, !bDateSel );
					mbSelLeft = sal_False;
					SelectionChanging();
					mbTravelSelect = sal_True;
					Select();
					mbTravelSelect = sal_False;
				}
			}
			else
				Control::KeyInput( rKEvt );
			break;

		default:
			Control::KeyInput( rKEvt );
			break;
	}

	if ( aNewDate != maCurDate )
	{
		if ( bMultiSel && bExpand )
		{
			Table* pOldSel = new Table( *mpSelectTable );
			Date aOldAnchorDate = maAnchorDate;
			mbSelLeft = aNewDate < maAnchorDate;
			if ( !bExtended )
			{
				if ( mbSelLeft )
				{
					ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), aNewDate, sal_False );
					ImplCalendarSelectDateRange( mpSelectTable, maAnchorDate, Date( 31, 12, 9999 ), sal_False );
				}
				else
				{
					ImplCalendarSelectDateRange( mpSelectTable, Date( 1, 1, 0 ), maAnchorDate, sal_False );
					ImplCalendarSelectDateRange( mpSelectTable, aNewDate, Date( 31, 12, 9999 ), sal_False );
				}
			}
			ImplCalendarSelectDateRange( mpSelectTable, aNewDate, maAnchorDate, sal_True );
			mbDirect = sal_True;
			SetCurDate( aNewDate );
			mbDirect = sal_False;
			maAnchorDate = aOldAnchorDate;
			mbInSelChange = sal_True;
			SelectionChanging();
			mbInSelChange = sal_False;
			ImplUpdateSelection( pOldSel );
            delete pOldSel;
		}
		else
		{
			if ( mnWinStyle & WB_RANGESELECT )
			{
				SetNoSelection();
				SelectDate( aNewDate, sal_True );
			}
			mbDirect = sal_True;
			SetCurDate( aNewDate );
			mbDirect = sal_False;
		}
		mbTravelSelect = sal_True;
		Select();
		mbTravelSelect = sal_False;
	}
}

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

void Calendar::Paint( const Rectangle& )
{
	ImplDraw( sal_True );
}

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

void Calendar::GetFocus()
{
	ImplUpdateDate( maCurDate );
	Control::GetFocus();
}

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

void Calendar::LoseFocus()
{
	HideFocus();
	Control::LoseFocus();
}

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

void Calendar::Resize()
{
	ImplUpdate( sal_True );
	Control::Resize();
}

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

void Calendar::RequestHelp( const HelpEvent& rHEvt )
{
	if ( rHEvt.GetMode() & (HELPMODE_QUICK | HELPMODE_BALLOON) )
	{
		Date aDate = maCurDate;
		if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
		{
			Rectangle aDateRect = GetDateRect( aDate );
			Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
			aDateRect.Left()   = aPt.X();
			aDateRect.Top()    = aPt.Y();
			aPt = OutputToScreenPixel( aDateRect.BottomRight() );
			aDateRect.Right()  = aPt.X();
			aDateRect.Bottom() = aPt.Y();

			if ( (rHEvt.GetMode() & HELPMODE_BALLOON) || (mnWinStyle & WB_QUICKHELPSHOWSDATEINFO) )
			{
				ImplDateInfo* pInfo;
				if ( mpDateTable )
				{
					pInfo = mpDateTable->Get( aDate.GetDate() );
					if ( !pInfo )
						pInfo = mpDateTable->Get( Date( aDate.GetDay(), aDate.GetMonth(), 0 ).GetDate() );
				}
				else
					pInfo = NULL;
				if ( pInfo )
				{
					XubString aStr = pInfo->maText;
					if ( aStr.Len() )
					{
						Help::ShowBalloon( this, rHEvt.GetMousePosPixel(), aDateRect, aStr );
						return;
					}
				}
			}

			if ( rHEvt.GetMode() & HELPMODE_QUICK )
			{
                maCalendarWrapper.setGregorianDateTime( aDate);
                sal_uInt16      nWeek = (sal_uInt16) maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR);
				sal_uInt16		nMonth = aDate.GetMonth();
				XubString	aStr( maDayText );
				aStr.AppendAscii( ": " );
				aStr.Append( XubString::CreateFromInt32( aDate.GetDayOfYear() ) );
				aStr.AppendAscii( " / " );
				aStr.Append( maWeekText );
				aStr.AppendAscii( ": " );
				aStr.Append( XubString::CreateFromInt32( nWeek ) );
				// Evt. noch Jahr hinzufuegen, wenn es nicht das gleiche ist
				if ( (nMonth == 12) && (nWeek == 1) )
				{
					aStr.AppendAscii( ",  " );
					aStr.Append( XubString::CreateFromInt32( aDate.GetYear()+1 ) );
				}
				else if ( (nMonth == 1) && (nWeek > 50) )
				{
					aStr.AppendAscii( ", " );
					aStr.Append( XubString::CreateFromInt32( aDate.GetYear()-1 ) );
				}
				Help::ShowQuickHelp( this, aDateRect, aStr );
				return;
			}
		}
	}

	Control::RequestHelp( rHEvt );
}

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

void Calendar::Command( const CommandEvent& rCEvt )
{
	if ( rCEvt.GetCommand() == COMMAND_CONTEXTMENU )
	{
		if ( !mbSelection && rCEvt.IsMouseEvent() )
		{
			Date	aTempDate = maCurDate;
			sal_uInt16	nHitTest = ImplHitTest( rCEvt.GetMousePosPixel(), aTempDate );
			if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
			{
				ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
				return;
			}
		}
	}
	else if ( rCEvt.GetCommand() == COMMAND_WHEEL )
	{
		const CommandWheelData* pData = rCEvt.GetWheelData();
		if ( pData->GetMode() == COMMAND_WHEEL_SCROLL )
		{
			long nNotchDelta = pData->GetNotchDelta();
			if ( nNotchDelta < 0 )
			{
				while ( nNotchDelta < 0 )
				{
					ImplScroll( sal_True );
					nNotchDelta++;
				}
			}
			else
			{
				while ( nNotchDelta > 0 )
				{
					ImplScroll( sal_False );
					nNotchDelta--;
				}
			}

			return;
		}
	}

	Control::Command( rCEvt );
}

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

void Calendar::StateChanged( StateChangedType nType )
{
	Control::StateChanged( nType );

	if ( nType == STATE_CHANGE_INITSHOW )
		ImplFormat();
}

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

void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
{
	Control::DataChanged( rDCEvt );

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

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

void Calendar::SelectionChanging()
{
	maSelectionChangingHdl.Call( this );
}

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

void Calendar::DateRangeChanged()
{
	maDateRangeChangedHdl.Call( this );
}

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

void Calendar::RequestDateInfo()
{
	maRequestDateInfoHdl.Call( this );
}

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

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

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

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

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

void Calendar::SelectDate( const Date& rDate, sal_Bool bSelect )
{
	if ( !rDate.IsValid() )
		return;

	Table* pOldSel;

	if ( !mbInSelChange )
		pOldSel = new Table( *mpSelectTable );
	else
		pOldSel = NULL;

	ImplCalendarSelectDate( mpSelectTable, rDate, bSelect );

	if ( pOldSel )
	{
		ImplUpdateSelection( pOldSel );
		delete pOldSel;
	}
}

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

void Calendar::SelectDateRange( const Date& rStartDate, const Date& rEndDate,
								sal_Bool bSelect )
{
	if ( !rStartDate.IsValid() || !rEndDate.IsValid() )
		return;

	Table* pOldSel;

	if ( !mbInSelChange )
		pOldSel = new Table( *mpSelectTable );
	else
		pOldSel = NULL;

	ImplCalendarSelectDateRange( mpSelectTable, rStartDate, rEndDate, bSelect );

	if ( pOldSel )
	{
		ImplUpdateSelection( pOldSel );
		delete pOldSel;
	}
}

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

void Calendar::SetNoSelection()
{
	Table* pOldSel;

	if ( !mbInSelChange )
		pOldSel = new Table( *mpSelectTable );
	else
		pOldSel = NULL;

	ImplCalendarClearSelectDate( mpSelectTable );

	if ( pOldSel )
	{
		ImplUpdateSelection( pOldSel );
		delete pOldSel;
	}
}

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

sal_Bool Calendar::IsDateSelected( const Date& rDate ) const
{
	return mpSelectTable->IsKeyValid( rDate.GetDate() );
}

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

sal_uLong Calendar::GetSelectDateCount() const
{
	return mpSelectTable->Count();
}

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

Date Calendar::GetSelectDate( sal_uLong nIndex ) const
{
	if ( nIndex < mpSelectTable->Count() )
		return Date( mpSelectTable->GetObjectKey( nIndex ) );
	else
	{
		Date aDate( 0, 0, 0 );
		return aDate;
	}
}

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

void Calendar::SetCurDate( const Date& rNewDate )
{
	if ( !rNewDate.IsValid() )
		return;

	if ( maCurDate != rNewDate )
	{
		sal_Bool bUpdate	= IsVisible() && IsUpdateMode();
		Date aOldDate	= maCurDate;
		maCurDate		= rNewDate;
		maAnchorDate	= maCurDate;

		if ( !(mnWinStyle & (WB_RANGESELECT | WB_MULTISELECT)) )
		{
			ImplCalendarSelectDate( mpSelectTable, aOldDate, sal_False );
			ImplCalendarSelectDate( mpSelectTable, maCurDate, sal_True );
		}
		else if ( !HasFocus() )
			bUpdate = sal_False;

		// Aktuelles Datum noch in den sichtbaren Bereich verschieben
		if ( mbFormat || (maCurDate < GetFirstMonth()) )
			SetFirstDate( maCurDate );
		else if ( maCurDate > GetLastMonth() )
		{
			Date aTempDate = GetLastMonth();
			long nDateOff = maCurDate-aTempDate;
			if ( nDateOff < 365 )
			{
				Date aFirstDate = GetFirstMonth();
				aFirstDate += aFirstDate.GetDaysInMonth();
				aTempDate++;
				while ( nDateOff > aTempDate.GetDaysInMonth() )
				{
					aFirstDate += aFirstDate.GetDaysInMonth();
					long nDaysInMonth = aTempDate.GetDaysInMonth();
					aTempDate += nDaysInMonth;
					nDateOff -= nDaysInMonth;
				}
				SetFirstDate( aFirstDate );
			}
			else
				SetFirstDate( maCurDate );
		}
		else
		{
			if ( bUpdate )
			{
				HideFocus();
				ImplUpdateDate( aOldDate );
				ImplUpdateDate( maCurDate );
			}
		}
	}
}

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

void Calendar::SetFirstDate( const Date& rNewFirstDate )
{
	if ( maFirstDate != rNewFirstDate )
	{
		maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
		mbDropPos = sal_False;
		ImplUpdate();
	}
}

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

Date Calendar::GetFirstMonth() const
{
	if ( maFirstDate.GetDay() > 1 )
	{
		if ( maFirstDate.GetMonth() == 12 )
			return Date( 1, 1, maFirstDate.GetYear()+1 );
		else
			return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
	}
	else
		return maFirstDate;
}

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

Date Calendar::GetLastMonth() const
{
	Date aDate = GetFirstMonth();
	sal_uInt16 nMonthCount = GetMonthCount();
	for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
		aDate += aDate.GetDaysInMonth();
	aDate--;
	return aDate;
}

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

sal_uInt16 Calendar::GetMonthCount() const
{
	if ( mbFormat )
		return 1;
	else
		return (sal_uInt16)(mnMonthPerLine*mnLines);
}

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

sal_Bool Calendar::GetDropDate( Date& rDate ) const
{
	if( mbDropPos )
	{
		rDate = maDropDate;
		return sal_True;
	}
	return sal_False;
}

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

sal_Bool Calendar::GetDate( const Point& rPos, Date& rDate ) const
{
	Date	aDate = maCurDate;
	sal_uInt16	nHitTest = ImplHitTest( rPos, aDate );
	if ( nHitTest & CALENDAR_HITTEST_DAY )
	{
		rDate = aDate;
		return sal_True;
	}
	else
		return sal_False;
}

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

Rectangle Calendar::GetDateRect( const Date& rDate ) const
{
	Rectangle aRect;

	if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
		return aRect;

	long	nX;
	long	nY;
	sal_uLong	nDaysOff;
	sal_uInt16	nDayIndex;
	Date	aDate = GetFirstMonth();

	if ( rDate < aDate )
	{
		aRect = GetDateRect( aDate );
		nDaysOff = aDate-rDate;
		nX = (long)(nDaysOff*mnDayWidth);
		aRect.Left() -= nX;
		aRect.Right() -= nX;
		return aRect;
	}
	else
	{
		Date aLastDate = GetLastMonth();
		if ( rDate > aLastDate )
		{
			sal_uInt16 nWeekDay = (sal_uInt16)aLastDate.GetDayOfWeek();
			nWeekDay = (nWeekDay+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
			aLastDate -= nWeekDay;
			aRect = GetDateRect( aLastDate );
			nDaysOff = rDate-aLastDate;
			nDayIndex = 0;
			for ( sal_uInt16 i = 0; i <= nDaysOff; i++ )
			{
				if ( aLastDate == rDate )
				{
					aRect.Left() += nDayIndex*mnDayWidth;
					aRect.Right() = aRect.Left()+mnDayWidth;
					return aRect;
				}
				if ( nDayIndex == 6 )
				{
					nDayIndex = 0;
					aRect.Top() += mnDayHeight;
					aRect.Bottom() += mnDayHeight;
				}
				else
					nDayIndex++;
				aLastDate++;
			}
		}
	}

	nY = 0;
	for ( long i = 0; i < mnLines; i++ )
	{
		nX = 0;
		for ( long j = 0; j < mnMonthPerLine; j++ )
		{
			sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();

			// Monat gerufen
			if ( (aDate.GetMonth() == rDate.GetMonth()) &&
				 (aDate.GetYear() == rDate.GetYear()) )
			{
				long nDayX = nX+mnDaysOffX;
				long nDayY = nY+mnDaysOffY;
				nDayIndex = (sal_uInt16)aDate.GetDayOfWeek();
				nDayIndex = (nDayIndex+(7-(sal_uInt16)ImplGetWeekStart())) % 7;
				for ( sal_uInt16 nDay = 1; nDay <= nDaysInMonth; nDay++ )
				{
					if ( nDay == rDate.GetDay() )
					{
						aRect.Left()	= nDayX + (nDayIndex*mnDayWidth);
						aRect.Top() 	= nDayY;
						aRect.Right()	= aRect.Left()+mnDayWidth;
						aRect.Bottom()	= aRect.Top()+mnDayHeight;
						break;
					}
					if ( nDayIndex == 6 )
					{
						nDayIndex = 0;
						nDayY += mnDayHeight;
					}
					else
						nDayIndex++;
				}
			}

			aDate += nDaysInMonth;
			nX += mnMonthWidth;
		}

		nY += mnMonthHeight;
	}

	return aRect;
}

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

void Calendar::SetStandardColor( const Color& rColor )
{
	if ( mpStandardColor )
		*mpStandardColor = rColor;
	else
		mpStandardColor = new Color( rColor );
	ImplUpdate();
}

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

void Calendar::SetSaturdayColor( const Color& rColor )
{
	if ( mpSaturdayColor )
		*mpSaturdayColor = rColor;
	else
		mpSaturdayColor = new Color( rColor );
	ImplUpdate();
}

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

void Calendar::SetSundayColor( const Color& rColor )
{
	if ( mpSundayColor )
		*mpSundayColor = rColor;
	else
		mpSundayColor = new Color( rColor );
	ImplUpdate();
}

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

void Calendar::AddDateInfo( const Date& rDate, const String& rText,
							const Color* pTextColor, const Color* pFrameColor,
							sal_uInt16 nFlags )
{
	if ( !mpDateTable )
		mpDateTable = new ImplDateTable( 256, 256 );

	sal_Bool			bChanged = sal_False;
	sal_uLong			nKey = rDate.GetDate();
	ImplDateInfo*	pDateInfo = mpDateTable->Get( nKey );
	if ( pDateInfo )
		pDateInfo->maText = rText;
	else
	{
		pDateInfo = new ImplDateInfo( rText );
		mpDateTable->Insert( nKey, pDateInfo );
	}
	if ( pTextColor )
	{
		if ( pDateInfo->mpTextColor )
		{
			if ( *(pDateInfo->mpTextColor) != *pTextColor )
			{
				*(pDateInfo->mpTextColor) = *pTextColor;
				bChanged = sal_True;
			}
		}
		else
		{
			pDateInfo->mpTextColor = new Color( *pTextColor );
			bChanged = sal_True;
		}
	}
	else
	{
		if ( pDateInfo->mpTextColor )
		{
			delete pDateInfo->mpTextColor;
			pDateInfo->mpTextColor = NULL;
			bChanged = sal_True;
		}
	}
	if ( pFrameColor )
	{
		if ( pDateInfo->mpFrameColor )
		{
			if ( *(pDateInfo->mpFrameColor) != *pFrameColor )
			{
				*(pDateInfo->mpFrameColor) = *pFrameColor;
				bChanged = sal_True;
			}
		}
		else
		{
			pDateInfo->mpFrameColor = new Color( *pFrameColor );
			bChanged = sal_True;
		}
	}
	else
	{
		if ( pDateInfo->mpFrameColor )
		{
			delete pDateInfo->mpFrameColor;
			pDateInfo->mpFrameColor = NULL;
			bChanged = sal_True;
		}
	}
	if ( pDateInfo->mnFlags != nFlags )
	{
		pDateInfo->mnFlags = nFlags;
		bChanged = sal_True;
	}

	if ( bChanged )
		ImplUpdateDate( rDate );
}

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

void Calendar::RemoveDateInfo( const Date& rDate )
{
	if ( mpDateTable )
	{
		ImplDateInfo* pDateInfo = mpDateTable->Remove( rDate.GetDate() );
		if ( pDateInfo )
		{
			delete pDateInfo;
			ImplUpdateDate( rDate );
		}
	}
}

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

void Calendar::ClearDateInfo()
{
	if ( mpDateTable )
	{
		ImplDateInfo* pDateInfo = mpDateTable->First();
		while ( pDateInfo )
		{
			sal_uLong nKey = mpDateTable->GetCurKey();
			mpDateTable->Remove( nKey );
			Date aDate( nKey );
			ImplUpdateDate( aDate );
			delete pDateInfo;
			pDateInfo = mpDateTable->First();
		}
		delete mpDateTable;
		mpDateTable = NULL;
	}
}

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

XubString Calendar::GetDateInfoText( const Date& rDate )
{
	XubString aRet;
	if ( mpDateTable )
	{
		sal_uLong			nKey = rDate.GetDate();
		ImplDateInfo*	pDateInfo = mpDateTable->Get( nKey );
		if ( pDateInfo )
			aRet = pDateInfo->maText;
	}
	return aRet;
}

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

sal_Bool Calendar::ShowDropPos( const Point& rPos, Date& rDate )
{
	Date	aTempDate = maCurDate;
	mnDragScrollHitTest = ImplHitTest( rPos, aTempDate );

	if ( mnDragScrollHitTest )
	{
		if ( mnDragScrollHitTest & (CALENDAR_HITTEST_PREV | CALENDAR_HITTEST_NEXT) )
		{
			if ( !maDragScrollTimer.IsActive() )
				maDragScrollTimer.Start();
		}
		else
		{
			maDragScrollTimer.Stop();
			if ( mnDragScrollHitTest & CALENDAR_HITTEST_DAY )
			{
				if ( !mbDropPos || (aTempDate != maDropDate) )
				{
					if( mbDropPos )
						ImplInvertDropPos();
					maDropDate = aTempDate;
					mbDropPos = sal_True;
					ImplInvertDropPos();
				}

				rDate = maDropDate;
				return sal_True;
			}
		}
	}
	else
		maDragScrollTimer.Stop();

	HideDropPos();
	return sal_False;
}

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

void Calendar::HideDropPos()
{
	if ( mbDropPos )
	{
		ImplInvertDropPos();
		mbDropPos = sal_False;
	}
}

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

void Calendar::StartSelection()
{
	if ( mpOldSelectTable )
		delete mpOldSelectTable;
	maOldCurDate = maCurDate;
	mpOldSelectTable = new Table( *mpSelectTable );

	mbSelection = sal_True;
}

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

void Calendar::EndSelection()
{
	if ( mbDrag || mbSpinDown || mbSelection )
	{
		if ( !mbSelection )
			ReleaseMouse();

		mbDrag				= sal_False;
		mbSelection 		= sal_False;
		mbMultiSelection	= sal_False;
		mbSpinDown			= sal_False;
		mbPrevIn			= sal_False;
		mbNextIn			= sal_False;
	}
}

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

Size Calendar::CalcWindowSizePixel( long nCalcMonthPerLine,
									long nCalcLines ) const
{
	XubString	a99Text( XubString( RTL_CONSTASCII_USTRINGPARAM( "99" ) ) );
	Font		aOldFont = GetFont();

	// Wochenanzeige beruecksichtigen
	long nWeekWidth;
	if ( mnWinStyle & WB_WEEKNUMBER )
	{
		Font aTempFont = aOldFont;
		ImplGetWeekFont( aTempFont );
		((Calendar*)this)->SetFont( aTempFont );
		nWeekWidth = GetTextWidth( a99Text )+WEEKNUMBER_OFFX;
		((Calendar*)this)->SetFont( aOldFont );
	}
	else
		nWeekWidth = 0;

	if ( mnWinStyle & WB_BOLDTEXT )
	{
		Font aFont = aOldFont;
		if ( aFont.GetWeight() < WEIGHT_BOLD )
			aFont.SetWeight( WEIGHT_BOLD );
		else
			aFont.SetWeight( WEIGHT_NORMAL );
		((Calendar*)this)->SetFont( aFont );
	}

	Size	aSize;
	long	n99TextWidth = GetTextWidth( a99Text );
	long	nTextHeight = GetTextHeight();

	if ( mnWinStyle & WB_BOLDTEXT )
		((Calendar*)this)->SetFont( aOldFont );

	aSize.Width()  += ((n99TextWidth+DAY_OFFX)*7) + nWeekWidth;
	aSize.Width()  += MONTH_BORDERX*2;
	aSize.Width()  *= nCalcMonthPerLine;

	aSize.Height()	= nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
	aSize.Height() += nTextHeight + WEEKDAY_OFFY;
	aSize.Height() += ((nTextHeight+DAY_OFFY)*6);
	aSize.Height() += MONTH_OFFY;
	aSize.Height() *= nCalcLines;

	return aSize;
}

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

#define CALFIELD_EXTRA_BUTTON_WIDTH 		14
#define CALFIELD_EXTRA_BUTTON_HEIGHT		8
#define CALFIELD_SEP_X						6
#define CALFIELD_BORDERLINE_X				5
#define CALFIELD_BORDER_YTOP				4
#define CALFIELD_BORDER_Y					5

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

class ImplCFieldFloatWin : public FloatingWindow
{
private:
	Calendar*		mpCalendar;
	PushButton* 	mpTodayBtn;
	PushButton* 	mpNoneBtn;
	FixedLine*		mpFixedLine;

public:
					ImplCFieldFloatWin( Window* pParent );
					~ImplCFieldFloatWin();

	void			SetCalendar( Calendar* pCalendar )
						{ mpCalendar = pCalendar; }

	PushButton* 	EnableTodayBtn( sal_Bool bEnable );
	PushButton* 	EnableNoneBtn( sal_Bool bEnable );
	void			ArrangeButtons();

	long			Notify( NotifyEvent& rNEvt );
};

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

ImplCFieldFloatWin::ImplCFieldFloatWin( Window* pParent ) :
	FloatingWindow( pParent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW  )
{
	mpCalendar	= NULL;
	mpTodayBtn	= NULL;
	mpNoneBtn	= NULL;
	mpFixedLine = NULL;
}

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

ImplCFieldFloatWin::~ImplCFieldFloatWin()
{
	delete mpTodayBtn;
	delete mpNoneBtn;
	delete mpFixedLine;
}

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

PushButton* ImplCFieldFloatWin::EnableTodayBtn( sal_Bool bEnable )
{
	if ( bEnable )
	{
		if ( !mpTodayBtn )
		{
			mpTodayBtn = new PushButton( this, WB_NOPOINTERFOCUS );
			XubString aTodayText( SvtResId( STR_SVT_CALENDAR_TODAY ) );
			mpTodayBtn->SetText( aTodayText );
			Size aSize;
			aSize.Width()	= mpTodayBtn->GetCtrlTextWidth( mpTodayBtn->GetText() );
			aSize.Height()	= mpTodayBtn->GetTextHeight();
			aSize.Width()  += CALFIELD_EXTRA_BUTTON_WIDTH;
			aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
			mpTodayBtn->SetSizePixel( aSize );
			mpTodayBtn->Show();
		}
	}
	else
	{
		if ( mpTodayBtn )
		{
			delete mpTodayBtn;
			mpTodayBtn = NULL;
		}
	}

	return mpTodayBtn;
}

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

PushButton* ImplCFieldFloatWin::EnableNoneBtn( sal_Bool bEnable )
{
	if ( bEnable )
	{
		if ( !mpNoneBtn )
		{
			mpNoneBtn = new PushButton( this, WB_NOPOINTERFOCUS );
			XubString aNoneText( SvtResId( STR_SVT_CALENDAR_NONE ) );
			mpNoneBtn->SetText( aNoneText );
			Size aSize;
			aSize.Width()	= mpNoneBtn->GetCtrlTextWidth( mpNoneBtn->GetText() );
			aSize.Height()	= mpNoneBtn->GetTextHeight();
			aSize.Width()  += CALFIELD_EXTRA_BUTTON_WIDTH;
			aSize.Height() += CALFIELD_EXTRA_BUTTON_HEIGHT;
			mpNoneBtn->SetSizePixel( aSize );
			mpNoneBtn->Show();
		}
	}
	else
	{
		if ( mpNoneBtn )
		{
			delete mpNoneBtn;
			mpNoneBtn = NULL;
		}
	}

	return mpNoneBtn;
}

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

void ImplCFieldFloatWin::ArrangeButtons()
{
	long nBtnHeight = 0;
	long nBtnWidth	= 0;
	Size aOutSize	= GetOutputSizePixel();
	if ( mpTodayBtn && mpNoneBtn )
	{
		Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
		Size aNoneBtnSize  = mpNoneBtn->GetSizePixel();
		if ( aTodayBtnSize.Width() < aNoneBtnSize.Width() )
			aTodayBtnSize.Width() = aNoneBtnSize.Width();
		else
			aNoneBtnSize.Width() = aTodayBtnSize.Width();
		if ( aTodayBtnSize.Height() < aNoneBtnSize.Height() )
			aTodayBtnSize.Height() = aNoneBtnSize.Height();
		else
			aNoneBtnSize.Height() = aTodayBtnSize.Height();

		nBtnWidth  = aTodayBtnSize.Width() + aNoneBtnSize.Width() + CALFIELD_SEP_X;
		nBtnHeight = aTodayBtnSize.Height();
		long nX = (aOutSize.Width()-nBtnWidth)/2;
		long nY = aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP;
		mpTodayBtn->SetPosSizePixel( Point( nX, nY ), aTodayBtnSize );
		nX += aTodayBtnSize.Width() + CALFIELD_SEP_X;
		mpNoneBtn->SetPosSizePixel( Point( nX, nY ), aNoneBtnSize );
	}
	else if ( mpTodayBtn )
	{
		Size aTodayBtnSize = mpTodayBtn->GetSizePixel();
		nBtnWidth  = aTodayBtnSize.Width();
		nBtnHeight = aTodayBtnSize.Height();
		mpTodayBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
	}
	else if ( mpNoneBtn )
	{
		Size aNoneBtnSize  = mpNoneBtn->GetSizePixel();
		nBtnWidth  = aNoneBtnSize.Width();
		nBtnHeight = aNoneBtnSize.Height();
		mpNoneBtn->SetPosPixel( Point( (aOutSize.Width()-nBtnWidth)/2, aOutSize.Height()+CALFIELD_BORDER_Y+CALFIELD_BORDER_YTOP ) );
	}

	if ( nBtnHeight )
	{
		if ( !mpFixedLine )
		{
			mpFixedLine = new FixedLine( this );
			mpFixedLine->Show();
		}
		long nLineWidth = aOutSize.Width()-(CALFIELD_BORDERLINE_X*2);
		mpFixedLine->SetPosSizePixel( (aOutSize.Width()-nLineWidth)/2, aOutSize.Height()+((CALFIELD_BORDER_YTOP-2)/2),
									  nLineWidth, 2, WINDOW_POSSIZE_POSSIZE );
		aOutSize.Height() += nBtnHeight + (CALFIELD_BORDER_Y*2) + CALFIELD_BORDER_YTOP;
		SetOutputSizePixel( aOutSize );
	}
	else
	{
		if ( mpFixedLine )
		{
			delete mpFixedLine;
			mpFixedLine = NULL;
		}
	}
}

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

long ImplCFieldFloatWin::Notify( NotifyEvent& rNEvt )
{
	if ( rNEvt.GetType() == EVENT_KEYINPUT )
	{
		const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
		if ( pKEvt->GetKeyCode().GetCode() == KEY_RETURN )
			mpCalendar->Select();
	}

	return FloatingWindow::Notify( rNEvt );
}

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

CalendarField::CalendarField( Window* pParent, WinBits nWinStyle ) :
	DateField( pParent, nWinStyle ),
	maDefaultDate( 0, 0, 0 )
{
	mpFloatWin		= NULL;
	mpCalendar		= NULL;
	mnCalendarStyle = 0;
	mbToday 		= sal_False;
	mbNone			= sal_False;
}

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

CalendarField::CalendarField( Window* pParent, const ResId& rResId ) :
	DateField( pParent, rResId ),
	maDefaultDate( 0, 0, 0 )
{
	mpFloatWin		= NULL;
	mpCalendar		= NULL;
	mnCalendarStyle = 0;
	mbToday 		= sal_False;
	mbNone			= sal_False;
}

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

CalendarField::~CalendarField()
{
	if ( mpFloatWin )
	{
		delete mpCalendar;
		delete mpFloatWin;
	}
}

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

IMPL_LINK( CalendarField, ImplSelectHdl, Calendar*, pCalendar )
{
	if ( !pCalendar->IsTravelSelect() )
	{
		mpFloatWin->EndPopupMode();
		EndDropDown();
		GrabFocus();
		Date aNewDate = mpCalendar->GetSelectDate( 0 );
		if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
		{
			SetDate( aNewDate );
			SetModifyFlag();
			Modify();
		}
		Select();
	}
	return 0;
}

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

IMPL_LINK( CalendarField, ImplClickHdl, PushButton*, pBtn )
{
	mpFloatWin->EndPopupMode();
	EndDropDown();
	GrabFocus();

	if ( pBtn == mpTodayBtn )
	{
		Date aToday;
		if ( (aToday != GetDate()) || IsEmptyDate() )
		{
			SetDate( aToday );
			SetModifyFlag();
			Modify();
		}
	}
	else if ( pBtn == mpNoneBtn )
	{
		if ( !IsEmptyDate() )
		{
			SetEmptyDate();
			SetModifyFlag();
			Modify();
		}
	}
	Select();

	return 0;
}

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

IMPL_LINK( CalendarField, ImplPopupModeEndHdl, FloatingWindow*, EMPTYARG )
{
	EndDropDown();
	GrabFocus();
	mpCalendar->EndSelection();
	return 0;
}

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

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

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

sal_Bool CalendarField::ShowDropDown( sal_Bool bShow )
{
	if ( bShow )
	{
		Calendar* pCalendar = GetCalendar();

		Date aDate = GetDate();
		if ( IsEmptyDate() || !aDate.IsValid() )
		{
			if ( maDefaultDate.IsValid() )
				aDate = maDefaultDate;
			else
				aDate = Date();
		}
		if ( pCalendar->GetStyle() & (WB_RANGESELECT | WB_MULTISELECT) )
		{
			pCalendar->SetNoSelection();
			pCalendar->SelectDate( aDate );
		}
		pCalendar->SetCurDate( aDate );
		Point		aPos( GetParent()->OutputToScreenPixel( GetPosPixel() ) );
		Rectangle	aRect( aPos, GetSizePixel() );
		aRect.Bottom() -= 1;
		mpCalendar->SetOutputSizePixel( mpCalendar->CalcWindowSizePixel() );
		mpFloatWin->SetOutputSizePixel( mpCalendar->GetSizePixel() );
		mpFloatWin->SetCalendar( mpCalendar );
		mpTodayBtn = mpFloatWin->EnableTodayBtn( mbToday );
		mpNoneBtn = mpFloatWin->EnableNoneBtn( mbNone );
		if ( mpTodayBtn )
			mpTodayBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
		if ( mpNoneBtn )
			mpNoneBtn->SetClickHdl( LINK( this, CalendarField, ImplClickHdl ) );
		mpFloatWin->ArrangeButtons();
		mpCalendar->EnableCallEverySelect();
		mpCalendar->StartSelection();
		mpCalendar->GrabFocus();
		mpCalendar->Show();
		mpFloatWin->StartPopupMode( aRect, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_DOWN );
	}
	else
	{
		mpFloatWin->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
		mpCalendar->EndSelection();
		EndDropDown();
	}
	return sal_True;
}

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

Calendar* CalendarField::CreateCalendar( Window* pParent )
{
	return new Calendar( pParent, mnCalendarStyle | WB_TABSTOP );
}

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

Calendar* CalendarField::GetCalendar()
{
	if ( !mpFloatWin )
	{
		mpFloatWin = new ImplCFieldFloatWin( this );
		mpFloatWin->SetPopupModeEndHdl( LINK( this, CalendarField, ImplPopupModeEndHdl ) );
		mpCalendar = CreateCalendar( mpFloatWin );
		mpCalendar->SetPosPixel( Point() );
		mpCalendar->SetSelectHdl( LINK( this, CalendarField, ImplSelectHdl ) );
	}

	return mpCalendar;
}

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

void CalendarField::StateChanged( StateChangedType nStateChange )
{
	DateField::StateChanged( nStateChange );

	if ( ( nStateChange == STATE_CHANGE_STYLE ) && GetSubEdit() )
	{
        WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM );
        WinBits nMyAlignment = GetStyle() & nAllAlignmentBits;
        GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment );
	}
}

