/*************************************************************************
 *
 *  $RCSfile: field.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: mt $ $Date: 2001/11/05 13:00:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SV_FIELD_HXX
#define _SV_FIELD_HXX

#ifndef _LINK_HXX
#include <tools/link.hxx>
#endif
#ifndef _DATE_HXX
#include <tools/date.hxx>
#endif
#ifndef _TIME_HXX
#include <tools/time.hxx>
#endif
#ifndef _INTN_HXX
#include <tools/intn.hxx>
#endif

#ifndef _SV_SPINFLD_HXX
#include <vcl/spinfld.hxx>
#endif
#ifndef _SV_COMBOBOX_HXX
#include <vcl/combobox.hxx>
#endif
#ifndef _VCL_FLDUNIT_HXX
#include <vcl/fldunit.hxx>
#endif

namespace com { namespace sun { namespace star { namespace lang { struct Locale; } } } }

class CalendarWrapper;
class LocaleDataWrapper;

// -----------------
// - FormatterBase -
// -----------------

class FormatterBase
{
private:
    Edit*                   mpField;
    LocaleDataWrapper*      mpLocaleDataWrapper;
    Link                    maErrorLink;
    BOOL                    mbReformat;
    BOOL                    mbStrictFormat;
    BOOL                    mbEmptyFieldValue;
    BOOL                    mbEmptyFieldValueEnabled;
    BOOL                    mbDefaultLocale;
    ULONG                   mnDummy1;
    BOOL                    mbDummy1;
    BOOL                    mbDummy2;
    BOOL                    mbDummy3;
    BOOL                    mbDummy4;

protected:
#if defined( _SV_FIELD_CXX ) || defined( _SV_FIELD2_CXX ) || defined( VCL_LONGCURR_CXX )
    void                    ImplSetText( const XubString& rText, Selection* pNewSel = NULL );
    BOOL                    ImplGetEmptyFieldValue() const  { return mbEmptyFieldValue; }
#endif

    void                    SetFieldText( const XubString& rText, BOOL bKeepSelection );
    void                    SetEmptyFieldValueData( BOOL bValue ) { mbEmptyFieldValue = bValue; }

    LocaleDataWrapper&      ImplGetLocaleDataWrapper() const;
    BOOL                    IsDefaultLocale() const { return mbDefaultLocale; }

public:
                            FormatterBase( Edit* pField = NULL );
                            ~FormatterBase();

    const LocaleDataWrapper& GetLocaleDataWrapper() const;

    void                    SetField( Edit* pField )    { mpField = pField; }
    Edit*                   GetField() const            { return mpField; }

    BOOL                    MustBeReformatted() const   { return mbReformat; }
    void                    MarkToBeReformatted( BOOL b ) { mbReformat = b; }

    void                    SetStrictFormat( BOOL bStrict );
    BOOL                    IsStrictFormat() const { return mbStrictFormat; }

    virtual void            Reformat();
    virtual void            ReformatAll();

    virtual void            SetLocale( const ::com::sun::star::lang::Locale& rLocale );
    const ::com::sun::star::lang::Locale&   GetLocale() const;

    const AllSettings&      GetFieldSettings() const;

    void                    SetErrorHdl( const Link& rLink )    { maErrorLink = rLink; }
    const Link&             GetErrorHdl() const                 { return maErrorLink; }

    void                    SetEmptyFieldValue();
    BOOL                    IsEmptyFieldValue() const;

    void                    EnableEmptyFieldValue( BOOL bEnable )   { mbEmptyFieldValueEnabled = bEnable; }
    BOOL                    IsEmptyFieldValueEnabled() const        { return mbEmptyFieldValueEnabled; }

    // Here again, only for the next update!
    void                    SetInternational( const International& rInternational );
    const International&    GetInternational() const;
};

// --------------------
// - PatternFormatter -
// --------------------

#define PATTERN_FORMAT_EMPTYLITERALS    ((USHORT)0x0001)

class PatternFormatter : public FormatterBase
{
private:
    ByteString              maEditMask;
    XubString               maFieldString;
    XubString               maLiteralMask;
    USHORT                  mnFormatFlags;
    USHORT                  mnDummy1;
    BOOL                    mbSameMask;
    BOOL                    mbInPattKeyInput;
    BOOL                    mbDummy1;
    BYTE                    mbDummy2;

protected:
                            PatternFormatter();

#ifdef _SV_FIELD2_CXX
    void                    ImplLoadRes( const ResId& rResId );
    void                    ImplSetMask( const ByteString& rEditMask, const XubString& rLiteralMask );
    BOOL                    ImplIsSameMask() const { return mbSameMask; }
    BOOL&                   ImplGetInPattKeyInput() { return mbInPattKeyInput; }
#endif

public:
                            ~PatternFormatter();

    virtual void            Reformat();

    void                    SetMask( const ByteString& rEditMask,
                                     const XubString& rLiteralMask );
    const ByteString&       GetEditMask() const     { return maEditMask; }
    const XubString&        GetLiteralMask() const  { return maLiteralMask; }

    void                    SetFormatFlags( USHORT nFlags ) { mnFormatFlags = nFlags; }
    USHORT                  GetFormatFlags() const { return mnFormatFlags; }

    void                    SetString( const XubString& rStr );
    XubString               GetString() const;
    BOOL                    IsStringModified() const { return !(GetString().Equals( maFieldString )); }

    void                    SelectFixedFont();
};

// --------------------
// - NumericFormatter -
// --------------------

class NumericFormatter : public FormatterBase
{
private:
#ifdef _SV_FIELD_CXX
    void                    ImplInit();
#endif

protected:
    long                    mnFieldValue;
    long                    mnLastValue;
    long                    mnMin;
    long                    mnMax;
    long                    mnCorrectedValue;
    USHORT                  mnType;
    USHORT                  mnDecimalDigits;
    USHORT                  mnDumym1;
    USHORT                  mnDumym2;
    BOOL                    mbThousandSep;
    BOOL                    mbShowTrailingZeros;
    BYTE                    mbDummy2;
    BYTE                    mbDummy3;

    // Eigentlich nur am entsprechenden Feld einstellbar (fuer Interaktion),
    // wird aber in allen Verschiedenen Ableitungen benoetigt
    // Man koennte ja noch ein NumericFormatterFieldBase einfuehren und die
    // Daten und Methoden dort unterbringen, aber dann gibt es noch mehr
    // Mehrfachvererbung
    long                    mnSpinSize;
    long                    mnFirst;
    long                    mnLast;

protected:
                            NumericFormatter();

    virtual XubString       CreateFieldText( long nValue ) const;

    void                    FieldUp();
    void                    FieldDown();
    void                    FieldFirst();
    void                    FieldLast();

#ifdef _SV_FIELD_CXX
    void                    ImplLoadRes( const ResId& rResId );
    BOOL                    ImplNumericReformat( const XubString& rStr, double& rValue, XubString& rOutStr );
    void                    ImplNewFieldValue( long nNewValue );
    void                    ImplSetUserValue( long nNewValue, Selection* pNewSelection = NULL );
#endif

public:
                            ~NumericFormatter();

    virtual void            Reformat();

    void                    SetMin( long nNewMin );
    long                    GetMin() const { return mnMin; }
    void                    SetMax( long nNewMax );
    long                    GetMax() const { return mnMax; }

    void                    SetFirst( long nNewFirst )      { mnFirst = nNewFirst; }
    long                    GetFirst() const                { return mnFirst; }
    void                    SetLast( long nNewLast )        { mnLast = nNewLast; }
    long                    GetLast() const                 { return mnLast; }
    void                    SetSpinSize( long nNewSize )    { mnSpinSize = nNewSize; }
    long                    GetSpinSize() const             { return mnSpinSize; }

    void                    SetDecimalDigits( USHORT nDigits );
    USHORT                  GetDecimalDigits() const;

    void                    SetUseThousandSep( BOOL b );
    BOOL                    IsUseThousandSep() const { return mbThousandSep; }

    void                    SetShowTrailingZeros( BOOL bShowTrailingZeros );
    BOOL                    IsShowTrailingZeros() const { return mbShowTrailingZeros; }

    void                    SetUserValue( long nNewValue );
    virtual void            SetValue( long nNewValue );
    virtual long            GetValue() const;
    BOOL                    IsValueModified() const;
    long                    GetCorrectedValue() const { return mnCorrectedValue; }

    Fraction                ConvertToFraction( long nValue );
    long                    ConvertToLong( const Fraction& rValue );
    long                    Normalize( long nValue ) const;
    long                    Denormalize( long nValue ) const;
};

// -------------------
// - MetricFormatter -
// -------------------

class MetricFormatter : public NumericFormatter
{
private:
#ifdef _SV_FIELD_CXX
    void                    ImplInit();
#endif

protected:
    XubString               maCustomUnitText;
    XubString               maCurUnitText;
    long                    mnBaseValue;
    FieldUnit               meUnit;
    Link                    maCustomConvertLink;

protected:
                            MetricFormatter();

    virtual XubString       CreateFieldText( long nValue ) const;

#ifdef _SV_FIELD_CXX
    void                    ImplLoadRes( const ResId& rResId );
    BOOL                    ImplMetricReformat( const XubString& rStr, double& rValue, XubString& rOutStr );
#endif

public:
                            ~MetricFormatter();

    virtual void            CustomConvert() = 0;
    virtual void            Reformat();

    void                    SetUnit( FieldUnit meUnit );
    FieldUnit               GetUnit() const { return meUnit; }
    void                    SetCustomUnitText( const XubString& rStr );
    const XubString&        GetCustomUnitText() const { return maCustomUnitText; }
    const XubString&        GetCurUnitText() const { return maCurUnitText; }

    void                    SetMax( long nNewMax, FieldUnit eInUnit = FUNIT_NONE );
    long                    GetMax( FieldUnit eOutUnit = FUNIT_NONE ) const;
    void                    SetMin( long nNewMin, FieldUnit eInUnit = FUNIT_NONE );
    long                    GetMin( FieldUnit eOutUnit = FUNIT_NONE ) const;
    void                    SetBaseValue( long nNewBase, FieldUnit eInUnit = FUNIT_NONE );
    long                    GetBaseValue( FieldUnit eOutUnit = FUNIT_NONE ) const;

    virtual void            SetValue( long nNewValue, FieldUnit eInUnit );
    virtual void            SetValue( long nValue );
    void                    SetUserValue( long nNewValue, FieldUnit eInUnit = FUNIT_NONE );
    virtual long            GetValue( FieldUnit eOutUnit ) const;
    virtual long            GetValue() const;
    long                    GetCorrectedValue( FieldUnit eOutUnit = FUNIT_NONE ) const;

    void                    SetCustomConvertHdl( const Link& rLink ) { maCustomConvertLink = rLink; }
    const Link&             GetCustomConvertHdl() const { return maCustomConvertLink; }
};

// ---------------------
// - CurrencyFormatter -
// ---------------------

class CurrencyFormatter : public NumericFormatter
{
private:
    String                  maCurrencySymbol;
    BOOL                    mbDummy1;
    BOOL                    mbDummy2;
    BYTE                    mbDummy3;
    BYTE                    mbDummy4;

#ifdef _SV_FIELD_CXX
    void                    ImplInit();
#endif

protected:
                            CurrencyFormatter();

    virtual XubString       CreateFieldText( long nValue ) const;

#ifdef _SV_FIELD_CXX
    BOOL                    ImplCurrencyReformat( const XubString& rStr, XubString& rOutStr );
#endif

public:
                            ~CurrencyFormatter();

    virtual void            Reformat();

    void                    SetCurrencySymbol( const String& rStr );
    String                  GetCurrencySymbol() const;

    virtual void            SetValue( long nNewValue );
    virtual long            GetValue() const;
};

// -----------------
// - DateFormatter -
// -----------------

class DateFormatter : public FormatterBase
{
private:
    CalendarWrapper*        mpCalendarWrapper;
    Date                    maFieldDate;
    Date                    maLastDate;
    Date                    maMin;
    Date                    maMax;
    Date                    maCorrectedDate;
    BOOL                    mbLongFormat;
    BOOL                    mbEmptyDate;
    BOOL                    mbShowDateCentury;
    USHORT                  mnDateFormat;
    ULONG                   mnExtDateFormat;
    BOOL                    mbDummy1;
    BOOL                    mbDummy2;
    BYTE                    mbDummy3;
    BYTE                    mbDummy4;

#ifdef _SV_FIELD2_CXX
    void                    ImplInit();
#endif

protected:
                            DateFormatter();

#ifdef _SV_FIELD2_CXX
    void                    ImplLoadRes( const ResId& rResId );
    const Date&             ImplGetFieldDate() const    { return maFieldDate; }
    BOOL                    ImplDateReformat( const XubString& rStr, XubString& rOutStr,
                                              const AllSettings& rSettings );
    void                    ImplSetUserDate( const Date& rNewDate,
                                             Selection* pNewSelection = NULL );
    XubString               ImplGetDateAsText( const Date& rDate,
                                               const AllSettings& rSettings ) const;
    void                    ImplNewFieldValue( const Date& rDate );
    CalendarWrapper&        GetCalendarWrapper() const;
#endif

public:
                            ~DateFormatter();

    virtual void            Reformat();
    virtual void            ReformatAll();

    virtual void            SetLocale( const ::com::sun::star::lang::Locale& rLocale );

#if SUPD < 651
    // MT 11/01: Seems that nobody uses them, I only want to use the ExtDateFormat now ( ## )
    void                    SetDateFormat( DateFormat eFormat );
    DateFormat              GetDateFormat() const;
#endif

    void                    SetExtDateFormat( ExtDateFieldFormat eFormat );
    ExtDateFieldFormat      GetExtDateFormat( BOOL bResolveSystemFormat = FALSE ) const;

    void                    SetMin( const Date& rNewMin );
    const Date&             GetMin() const { return maMin; }

    void                    SetMax( const Date& rNewMax );
    const Date&             GetMax() const { return maMax; }

    // --------------------------------------------------------------
    // MT: Remove these methods too, ExtDateFormat should be enough!
    //     What should happen if using DDMMYYYY, but ShowCentury=FALSE?
    // --------------------------------------------------------------
    void                    SetLongFormat( BOOL bLong );
    BOOL                    IsLongFormat() const { return mbLongFormat; }
    void                    SetShowDateCentury( BOOL bShowCentury );
    BOOL                    IsShowDateCentury() const { return mbShowDateCentury; }
    // --------------------------------------------------------------

    void                    SetDate( const Date& rNewDate );
    void                    SetUserDate( const Date& rNewDate );
    Date                    GetDate() const;
    Date                    GetRealDate() const;
    BOOL                    IsDateModified() const;
    void                    SetEmptyDate();
    BOOL                    IsEmptyDate() const;
    Date                    GetCorrectedDate() const { return maCorrectedDate; }

    void                    ResetLastDate() { maLastDate = Date( 0, 0, 0 ); }

    static void             ExpandCentury( Date& rDate );
    static void             ExpandCentury( Date& rDate, USHORT nTwoDigitYearStart );
};

// -----------------
// - TimeFormatter -
// -----------------

class TimeFormatter : public FormatterBase
{
private:
    Time                    maLastTime;
    Time                    maMin;
    Time                    maMax;
    Time                    maCorrectedTime;
    TimeFieldFormat         meFormat;
    USHORT                  mnTimeFormat;
    BOOL                    mbDuration;
    BOOL                    mbEmptyTime;
    ULONG                   mnDummy1;
    BOOL                    mbDummy1;
    BOOL                    mbDummy2;
    BYTE                    mbDummy3;
    BYTE                    mbDummy4;

#ifdef _SV_FIELD2_CXX
    void                    ImplInit();
#endif

protected:
    Time                    maFieldTime;

                            TimeFormatter();

#ifdef _SV_FIELD2_CXX
    void                    ImplLoadRes( const ResId& rResId );
    BOOL                    ImplTimeReformat( const XubString& rStr, XubString& rOutStr );
    void                    ImplNewFieldValue( const Time& rTime );
    void                    ImplSetUserTime( const Time& rNewTime, Selection* pNewSelection = NULL );
#endif

public:
                            ~TimeFormatter();

    virtual void            Reformat();
    virtual void            ReformatAll();

    void                    SetMin( const Time& rNewMin );
    const Time&             GetMin() const { return maMin; }
    void                    SetMax( const Time& rNewMax );
    const Time&             GetMax() const { return maMax; }

    void                    SetTimeFormat( TimeFormat eNewFormat );
    TimeFormat              GetTimeFormat() const;

    void                    SetFormat( TimeFieldFormat eNewFormat );
    TimeFieldFormat         GetFormat() const { return meFormat; }

    void                    SetDuration( BOOL mbDuration );
    BOOL                    IsDuration() const { return mbDuration; }

    void                    SetTime( const Time& rNewTime );
    void                    SetUserTime( const Time& rNewTime );
    Time                    GetTime() const;
    Time                    GetRealTime() const;
    BOOL                    IsTimeModified() const;
    void                    SetEmptyTime() { FormatterBase::SetEmptyFieldValue(); }
    BOOL                    IsEmptyTime() const { return FormatterBase::IsEmptyFieldValue(); }
    Time                    GetCorrectedTime() const { return maCorrectedTime; }
};

// ----------------
// - PatternField -
// ----------------

class PatternField : public SpinField, public PatternFormatter
{
public:
                            PatternField( Window* pParent, WinBits nWinStyle );
                            PatternField( Window* pParent, const ResId& rResId );
                            ~PatternField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            Modify();
};

// ----------------
// - NumericField -
// ----------------

class NumericField : public SpinField, public NumericFormatter
{
#ifdef _SV_FIELD_CXX
protected:
    void                    ImplLoadRes( const ResId& rResId );
#endif

public:
                            NumericField( Window* pParent, WinBits nWinStyle );
                            NumericField( Window* pParent, const ResId& rResId );
                            ~NumericField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            Up();
    virtual void            Down();
    virtual void            First();
    virtual void            Last();
};

// ----------------
// - MetricField  -
// ----------------

class MetricField : public SpinField, public MetricFormatter
{
#ifdef _SV_FIELD_CXX
protected:
    void                    ImplLoadRes( const ResId& rResId );
#endif

public:
                            MetricField( Window* pParent, WinBits nWinStyle );
                            MetricField( Window* pParent, const ResId& rResId );
                            ~MetricField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            Up();
    virtual void            Down();
    virtual void            First();
    virtual void            Last();
    virtual void            CustomConvert();

    void                    SetFirst( long nNewFirst, FieldUnit eInUnit=FUNIT_NONE );
    long                    GetFirst( FieldUnit eOutUnit=FUNIT_NONE ) const;
    void                    SetLast( long nNewLast, FieldUnit eInUnit=FUNIT_NONE );
    long                    GetLast( FieldUnit eOutUnit=FUNIT_NONE ) const;

    static void             SetDefaultUnit( FieldUnit eDefaultUnit );
    static FieldUnit        GetDefaultUnit();
    static long             ConvertValue( long nValue, long mnBaseValue, USHORT nDecDigits,
                                          FieldUnit eInUnit, FieldUnit eOutUnit );
    static long             ConvertValue( long nValue, USHORT nDecDigits,
                                          FieldUnit eInUnit, MapUnit eOutUnit );
    static long             ConvertValue( long nValue, USHORT nDecDigits,
                                          MapUnit eInUnit, FieldUnit eOutUnit );

    static double           ConvertDoubleValue( double nValue, long mnBaseValue, USHORT nDecDigits,
                                                FieldUnit eInUnit, FieldUnit eOutUnit );
    static double           ConvertDoubleValue( double nValue, USHORT nDecDigits,
                                                FieldUnit eInUnit, MapUnit eOutUnit );
    static double           ConvertDoubleValue( double nValue, USHORT nDecDigits,
                                                MapUnit eInUnit, FieldUnit eOutUnit );
};

// -----------------
// - CurrencyField -
// -----------------

class CurrencyField : public SpinField, public CurrencyFormatter
{
#ifdef _SV_FIELD_CXX
protected:
    void                    ImplLoadRes( const ResId& rResId );
#endif

public:
                            CurrencyField( Window* pParent, WinBits nWinStyle );
                            CurrencyField( Window* pParent, const ResId& rResId );
                            ~CurrencyField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            Up();
    virtual void            Down();
    virtual void            First();
    virtual void            Last();
};

// -------------
// - DateField -
// -------------

class DateField : public SpinField, public DateFormatter
{
private:
    Date                    maFirst;
    Date                    maLast;

#ifdef _SV_FIELD2_CXX
protected:
    void                    ImplDateSpinArea( BOOL bUp );
    void                    ImplLoadRes( const ResId& rResId );
#endif

public:
                            DateField( Window* pParent, WinBits nWinStyle );
                            DateField( Window* pParent, const ResId& rResId );
                            ~DateField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            Up();
    virtual void            Down();
    virtual void            First();
    virtual void            Last();

    void                    SetFirst( const Date& rNewFirst )   { maFirst = rNewFirst; }
    Date                    GetFirst() const                    { return maFirst; }
    void                    SetLast( const Date& rNewLast )     { maLast = rNewLast; }
    Date                    GetLast() const                     { return maLast; }

#if SUPD < 651
    // MT 11/01: Moved to DateFormatter
    void                    SetExtFormat( ExtDateFieldFormat eFormat );
#endif
};

// -------------
// - TimeField -
// -------------

class TimeField : public SpinField, public TimeFormatter
{
private:
    Time                    maFirst;
    Time                    maLast;

#ifdef _SV_FIELD2_CXX
protected:
    void                    ImplTimeSpinArea( BOOL bUp );
    void                    ImplLoadRes( const ResId& rResId );
#endif

public:
                            TimeField( Window* pParent, WinBits nWinStyle );
                            TimeField( Window* pParent, const ResId& rResId );
                            ~TimeField();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            Up();
    virtual void            Down();
    virtual void            First();
    virtual void            Last();

    void                    SetFirst( const Time& rNewFirst )   { maFirst = rNewFirst; }
    Time                    GetFirst() const                    { return maFirst; }
    void                    SetLast( const Time& rNewLast )     { maLast = rNewLast; }
    Time                    GetLast() const                     { return maLast; }

    void                    SetExtFormat( ExtTimeFieldFormat eFormat );
};

// --------------
// - PatternBox -
// --------------

class PatternBox : public ComboBox, public PatternFormatter
{
public:
                            PatternBox( Window* pParent, WinBits nWinStyle );
                            PatternBox( Window* pParent, const ResId& rResId );
                            ~PatternBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );

    virtual void            Modify();

    virtual void            ReformatAll();

    void                    InsertString( const XubString& rStr,
                                          USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveString( const XubString& rStr );
    XubString               GetString( USHORT nPos ) const;
    USHORT                  GetStringPos( const XubString& rStr ) const;
};

// --------------
// - NumericBox -
// --------------

class NumericBox : public ComboBox, public NumericFormatter
{
public:
                            NumericBox( Window* pParent, WinBits nWinStyle );
                            NumericBox( Window* pParent, const ResId& rResId );
                            ~NumericBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            ReformatAll();

    void                    InsertValue( long nValue, USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveValue( long nValue );
    long                    GetValue( USHORT nPos ) const;
    USHORT                  GetValuePos( long nPos ) const;

    // Needed, because GetValue() with nPos hide these functions
    virtual long            GetValue() const;
};

// -------------
// - MetricBox -
// -------------

class MetricBox : public ComboBox, public MetricFormatter
{
public:
                            MetricBox( Window* pParent, WinBits nWinStyle );
                            MetricBox( Window* pParent, const ResId& rResId );
                            ~MetricBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            CustomConvert();
    virtual void            ReformatAll();

    void                    InsertValue( long nValue, FieldUnit eInUnit = FUNIT_NONE,
                                         USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveValue( long nValue, FieldUnit eInUnit = FUNIT_NONE );
    long                    GetValue( USHORT nPos, FieldUnit eOutUnit = FUNIT_NONE ) const;
    USHORT                  GetValuePos( long nValue,
                                         FieldUnit eInUnit = FUNIT_NONE ) const;

    // Needed, because GetValue() with nPos hide these functions
    virtual long            GetValue( FieldUnit eOutUnit ) const;
    virtual long            GetValue() const;
};

// ---------------
// - CurrencyBox -
// ---------------

class CurrencyBox : public ComboBox, public CurrencyFormatter
{
public:
                            CurrencyBox( Window* pParent, WinBits nWinStyle );
                            CurrencyBox( Window* pParent, const ResId& rResId );
                            ~CurrencyBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            ReformatAll();

    void                    InsertValue( long nValue, USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveValue( long nValue );
    long                    GetValue( USHORT nPos ) const;
    USHORT                  GetValuePos( long nValue ) const;

    // Needed, because GetValue() with nPos hide this function
    virtual long            GetValue() const;
};

// -----------
// - DateBox -
// -----------

class DateBox : public ComboBox, public DateFormatter
{
public:
                            DateBox( Window* pParent, WinBits nWinStyle );
                            DateBox( Window* pParent, const ResId& rResId );
                            ~DateBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            ReformatAll();

    void                    InsertDate( const Date& rDate, USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveDate( const Date& rDate );
    Date                    GetDate( USHORT nPos ) const;
    USHORT                  GetDatePos( const Date& rDate ) const;
};

// -----------
// - TimeBox -
// -----------

class TimeBox : public ComboBox, public TimeFormatter
{
public:
                            TimeBox( Window* pParent, WinBits nWinStyle );
                            TimeBox( Window* pParent, const ResId& rResId );
                            ~TimeBox();

    virtual long            PreNotify( NotifyEvent& rNEvt );
    virtual long            Notify( NotifyEvent& rNEvt );
    virtual void            DataChanged( const DataChangedEvent& rDCEvt );

    virtual void            Modify();

    virtual void            ReformatAll();

    void                    InsertTime( const Time& rTime, USHORT nPos = COMBOBOX_APPEND );
    void                    RemoveTime( const Time& rTime );
    Time                    GetTime( USHORT nPos ) const;
    USHORT                  GetTimePos( const Time& rTime ) const;
};

#endif // _SV_FIELD_HXX
