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



#ifndef _LAYOUT_HXX
#define _LAYOUT_HXX

#include <com/sun/star/awt/XLayoutContainer.hpp>
#include <com/sun/star/uno/XInterface.hpp>
#include <com/sun/star/util/Color.hpp>
#include <i18npool/lang.h>
#include <toolkit/dllapi.h>
#include <tools/gen.hxx>
#include <tools/link.hxx>
#include <tools/string.hxx>
#include <vcl/bitmap.hxx>
#include <vcl/combobox.h>
#include <tools/fldunit.hxx>
#include <vcl/lstbox.h>
#include <tools/wintypes.hxx>

class Button;
class ComboBox;
class Color;
class Control;
class Dialog;
class Edit;
class Font;
class Image;
class ListBox;
class MapMode;
class MultiListBox;
class NotifyEvent;
class Pointer;
class PushButton;
class RadioButton;
class ResId;
struct SfxChildWinInfo;
//class SvxFontListBox;
//class SvxLanguageBox;
class TabControl;
class TabPage;
class VCLXRadioButton;
class VCLXWindow;
class Window;

namespace layoutimpl
{
class VCLXTabControl;
}

class VCLXTabControl;

namespace com { namespace sun { namespace star { namespace awt { class XWindow; } } } }

namespace layout
{

namespace css = ::com::sun::star;

typedef css::uno::Reference< css::uno::XInterface > PeerHandle;
class ContextImpl;
class TOOLKIT_DLLPUBLIC Context
{
    ContextImpl *pImpl;
public:
    Context( char const* pPath );
    virtual ~Context();
    PeerHandle GetPeerHandle( char const* id, sal_uInt32 nId = 0 ) const;
    void setToplevel( PeerHandle xToplevel );
    PeerHandle getToplevel();
    PeerHandle getRoot();
};

// make declaring wrappers easier ...
#define DECL_CONSTRUCTORS(t,par,defaultWinBit) \
    protected:                                 \
        explicit t( WindowImpl *pImpl ) : \
            par( pImpl ) {} \
        char const* GetUnoName() const; \
    public: \
        t( Context *context, char const* id, sal_uInt32 nId = 0 ); \
        t( Window *parent, WinBits nStyle = defaultWinBit ); \
        t (Window *parent, ResId const &res)
#define DECL_GET_IMPL(t) \
        inline t##Impl *getImpl() const

#define DECL_GET_WINDOW( cls ) ::cls* Get##cls() const
#define IMPL_GET_WINDOW( cls ) ::cls* cls::Get##cls() const { return dynamic_cast< ::cls*>( GetWindow() ); }

#define DECL_GET_VCLXWINDOW( cls ) ::VCLX##cls* GetVCLX##cls() const
#define IMPL_GET_VCLXWINDOW( cls ) ::VCLX##cls* cls::Get##VCLX##cls() const { return dynamic_cast< ::VCLX##cls*>( GetVCLXWindow() ); }

#define DECL_GET_LAYOUT_VCLXWINDOW( cls ) ::layoutimpl::VCLX##cls* GetVCLX##cls() const
#define IMPL_GET_LAYOUT_VCLXWINDOW( cls ) ::layoutimpl::VCLX##cls* cls::Get##VCLX##cls() const { return dynamic_cast< ::layoutimpl::VCLX##cls*>( GetVCLXWindow() ); }

// follows the VCL inheritance hierarchy ...

class WindowImpl;
class TOOLKIT_DLLPUBLIC Window
{
protected:
    friend class WindowImpl;
    WindowImpl *mpImpl;
    static PeerHandle CreatePeer( Window *parent, WinBits nStyle,
                                  char const* pName);

    virtual void setRes (ResId const& res);

public:
    DECL_GET_IMPL( Window );
    explicit Window( WindowImpl *pImpl );
    virtual ~Window();

    PeerHandle GetPeer() const;
    Context *getContext();

    void Enable( bool bEnable = true );
    inline void Disable() { Enable( false ); }
    void Show( bool bVisible = true );
    inline void Hide() { Show( false ); }
    void GrabFocus();
    void FreeResource() {}

    void SetParent( ::Window *parent );
    virtual void ParentSet (Window *window);
    void SetParent( Window *parent );

    css::uno::Reference<css::awt::XWindow> GetRef() const;
    VCLXWindow* GetVCLXWindow() const;
    ::Window* GetWindow() const;
    ::Window* GetParent() const;

    void SetPointer( Pointer const& pointer );
    Pointer const& GetPointer() const;
    WinBits GetStyle();
    void SetText( rtl::OUString const& str );
    String GetText() const;
    void SetStyle( WinBits style );
    void SetUpdateMode( bool mode );
    void SetHelpId( const rtl::OString& id );
    const rtl::OString& GetHelpId() const;
    void EnterWait ();
    void LeaveWait ();
    bool IsWait () const;
    //void Enable (bool enable=true, bool child=true);
    //void Disable (bool child=true);
    bool IsEnabled () const;
    void EnableInput (bool enable=true, bool child=true);
    bool IsInputEnabled () const;

    bool IsVisible () const;
    bool HasChildPathFocus (bool systemWindow=false) const;
    void SetPosPixel (Point const&);
    Point GetPosPixel () const;
    void SetSizePixel (Size const&);
    Size GetSizePixel () const;
    void SetPosSizePixel (Point const&, Size const&);
    sal_Int32 GetCtrlTextWidth (rtl::OUString const& str) const;
    sal_Int32 GetTextHeight () const;

    Size LogicToPixel( Size const& size ) const;
    Size LogicToPixel( Size const& size, MapMode const& mapMode ) const;

    bool HasFocus () const;
    Font& GetFont () const;
    void SetFont (Font const& font);
    virtual void Invalidate (sal_uInt8 flags=0);
};

class ControlImpl;
class TOOLKIT_DLLPUBLIC Control : public Window
{
    DECL_GET_IMPL( Control );
    DECL_CONSTRUCTORS( Control, Window, 0 );

public:
    ~Control ();
    void SetGetFocusHdl (Link const& link);
    Link& GetGetFocusHdl ();
    void SetLoseFocusHdl (Link const& link);
    Link& GetLoseFocusHdl ();
};

class FixedLineImpl;
class TOOLKIT_DLLPUBLIC FixedLine : public Control
{
    DECL_GET_IMPL( FixedLine );
    DECL_CONSTRUCTORS( FixedLine, Control, WB_HORZ );

public:
    bool IsEnabled() const;
};

class FixedTextImpl;
class TOOLKIT_DLLPUBLIC FixedText : public Control
{
    DECL_GET_IMPL( FixedText );
    DECL_CONSTRUCTORS( FixedText, Control, 0 );

public:
    ~FixedText ();
    void SetText( rtl::OUString const& rStr );
};

class FixedImageImpl;
class TOOLKIT_DLLPUBLIC FixedImage : public Control
{
    DECL_GET_IMPL( FixedImage );
    DECL_CONSTRUCTORS( FixedImage, Control, 0 );
public:
    void setImage( ::Image const& );
};

class FixedInfoImpl;
class TOOLKIT_DLLPUBLIC FixedInfo : public FixedText
{
    DECL_GET_IMPL( FixedInfo );
    DECL_CONSTRUCTORS( FixedInfo, FixedText, 0 );
};

class ImageImpl;
class TOOLKIT_DLLPUBLIC Image
{
    ImageImpl *pImpl;
public:
    Image( char const* pName );
    ~Image();
    ImageImpl &getImpl() const { return *pImpl; }
};

class ButtonImpl;
class TOOLKIT_DLLPUBLIC Button : public Control
{
    DECL_GET_IMPL( Button );
    DECL_CONSTRUCTORS( Button, Control, 0 );
    DECL_GET_WINDOW (Button);

public:
    ~Button ();
    static String GetStandardText (sal_uInt16 button_type);
    void SetText( rtl::OUString const& rStr );
    bool SetModeImage (Image const& image);
    bool SetModeImage (::Image const& image, BmpColorMode mode=BMP_COLOR_NORMAL);
    void SetImageAlign( ImageAlign eAlign );

    void SetClickHdl( Link const& rLink );
    virtual void Click() /* pure virtual? */;
    Link& GetClickHdl ();
};

class PushButtonImpl;
class TOOLKIT_DLLPUBLIC PushButton : public Button
{
    DECL_GET_IMPL( PushButton );
    DECL_CONSTRUCTORS( PushButton, Button, 0 );
    DECL_GET_WINDOW (PushButton);

public:
    ~PushButton ();
    void Check( bool bCheck=true );
    bool IsChecked() const;

    void Toggle();
    void SetToggleHdl( Link const& rLink );
};

class TOOLKIT_DLLPUBLIC OKButton : public PushButton
{
    DECL_CONSTRUCTORS( OKButton, PushButton, WB_DEFBUTTON );
};
class TOOLKIT_DLLPUBLIC CancelButton : public PushButton
{
    DECL_CONSTRUCTORS( CancelButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC YesButton : public PushButton
{
    DECL_CONSTRUCTORS( YesButton, PushButton, WB_DEFBUTTON );
};
class TOOLKIT_DLLPUBLIC NoButton : public PushButton
{
    DECL_CONSTRUCTORS( NoButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC RetryButton : public PushButton
{
    DECL_CONSTRUCTORS( RetryButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC IgnoreButton : public PushButton
{
    DECL_CONSTRUCTORS( IgnoreButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC ResetButton : public PushButton
{
    DECL_CONSTRUCTORS( ResetButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC ApplyButton : public PushButton
{
    DECL_CONSTRUCTORS( ApplyButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC HelpButton : public PushButton
{
    DECL_CONSTRUCTORS( HelpButton, PushButton, 0 );
};
class TOOLKIT_DLLPUBLIC ImageButton : public PushButton
{
    DECL_CONSTRUCTORS( ImageButton, PushButton, 0 );
};

class AdvancedButtonImpl;
class TOOLKIT_DLLPUBLIC AdvancedButton : public PushButton
{
    DECL_CONSTRUCTORS( AdvancedButton, PushButton, 0 );
    DECL_GET_IMPL( AdvancedButton );

    void AddAdvanced( Window* w );
    void AddSimple( Window* w );
    void RemoveAdvanced( Window* w );
    void RemoveSimple( Window* w );

    void SetAdvancedText (rtl::OUString const& text);
    void SetSimpleText (rtl::OUString const& text);
    rtl::OUString GetAdvancedText () const;
    rtl::OUString GetSimpleText () const;
    void SetDelta (int);
};

class MoreButtonImpl;
class TOOLKIT_DLLPUBLIC MoreButton : public AdvancedButton
{
    DECL_CONSTRUCTORS( MoreButton, AdvancedButton, 0 );
    DECL_GET_IMPL( MoreButton );
    void AddWindow( Window* w );
    void RemoveWindow( Window* w );

    void SetMoreText (rtl::OUString const& text);
    void SetLessText (rtl::OUString const& text);
    rtl::OUString GetMoreText () const;
    rtl::OUString GetLessText () const;
};

class RadioButtonImpl;
class TOOLKIT_DLLPUBLIC RadioButton : public Button
{
    DECL_GET_IMPL( RadioButton );
    DECL_CONSTRUCTORS( RadioButton, Button, 0 );
    DECL_GET_WINDOW( RadioButton );
    DECL_GET_VCLXWINDOW( RadioButton );
public:
    ~RadioButton ();
    void Check( bool bCheck=true );
    bool IsChecked() const;

    void Toggle();
    void SetToggleHdl( Link const& rLink );
};

class CheckBoxImpl;
class TOOLKIT_DLLPUBLIC CheckBox : public Button
{
    DECL_GET_IMPL( CheckBox );
    DECL_CONSTRUCTORS( CheckBox, Button, 0 );

public:
    ~CheckBox ();
    void Check( bool bCheck=true );
    bool IsChecked() const;

    void Toggle();
    void SetToggleHdl( Link const& rLink );
};

class EditImpl;
class TOOLKIT_DLLPUBLIC Edit : public Control
{
    DECL_GET_IMPL( Edit );
    DECL_CONSTRUCTORS( Edit, Control, WB_BORDER );
    DECL_GET_WINDOW (Edit);

public:
    ~Edit ();
    void SetText( rtl::OUString const& rStr );
    String GetText() const;
    void SetModifyHdl( Link const& rLink );
    void SetSelection( Selection const& rSelection );
};

class MultiLineEditImpl;
class TOOLKIT_DLLPUBLIC MultiLineEdit : public Edit
{
    DECL_GET_IMPL( MultiLineEdit );
    DECL_CONSTRUCTORS( MultiLineEdit, Edit, WB_LEFT|WB_BORDER );
};

class SpinFieldImpl;
class TOOLKIT_DLLPUBLIC SpinField : public Edit
{
    DECL_GET_IMPL( SpinField );
    DECL_CONSTRUCTORS( SpinField, Edit, 0 );
};

class FormatterBaseImpl;
class TOOLKIT_DLLPUBLIC FormatterBase
{
protected:
    FormatterBaseImpl *mpFormatImpl;
    FormatterBase( FormatterBaseImpl *pFormatImpl );
};

class NumericFormatterImpl;
class TOOLKIT_DLLPUBLIC NumericFormatter : public FormatterBase
{
protected:
    explicit NumericFormatter( FormatterBaseImpl *pImpl );
    NumericFormatterImpl &getFormatImpl() const;
public:
    void SetMin( sal_Int64 nNewMin );
    void SetMax( sal_Int64 nNewMax );
    void SetFirst( sal_Int64 nNewFirst );
    void SetLast( sal_Int64 nNewLast );
    void SetSpinSize( sal_Int64 nNewSize );

    void SetValue( sal_Int64 nNewValue );
    sal_Int64 GetValue() const;
};

class NumericFieldImpl;
class TOOLKIT_DLLPUBLIC NumericField : public SpinField, public NumericFormatter
{
    DECL_GET_IMPL( NumericField );
public:
    NumericField( Context *context, char const* id, sal_uInt32 nId=0 );
    NumericField( Window *parent, WinBits nStyle );
};

class MetricFormatterImpl;
// Different inheritance to save code
class TOOLKIT_DLLPUBLIC MetricFormatter : public FormatterBase
{
  protected:
    explicit MetricFormatter( FormatterBaseImpl *pImpl );
    MetricFormatterImpl &getFormatImpl() const;
public:
    void SetMin( sal_Int64 nNewMin, FieldUnit nUnit=FUNIT_NONE );
    void SetMax( sal_Int64 nNewMax, FieldUnit nUnit=FUNIT_NONE );
    void SetFirst( sal_Int64 nNewFirst, FieldUnit nUnit=FUNIT_NONE );
    void SetLast( sal_Int64 nNewLast, FieldUnit nUnit=FUNIT_NONE );
    void SetValue( sal_Int64 nNewValue, FieldUnit nUnit=FUNIT_NONE );
    sal_Int64 GetValue( FieldUnit nUnit=FUNIT_NONE ) const;

    void SetSpinSize( sal_Int64 nNewSize );
};

class MetricFieldImpl;
class TOOLKIT_DLLPUBLIC MetricField : public SpinField, public MetricFormatter
{
    DECL_GET_IMPL( MetricField );
public:
    MetricField( Context *context, char const* id, sal_uInt32 nId=0 );
    MetricField( Window *parent, WinBits nStyle );
};

class ComboBoxImpl;
class TOOLKIT_DLLPUBLIC ComboBox : public Edit
{
    DECL_GET_IMPL( ComboBox );
    DECL_GET_WINDOW (ComboBox );
    DECL_CONSTRUCTORS( ComboBox, Edit, 0 );

public:
    ~ComboBox ();
    sal_uInt16 InsertEntry( String const& rStr, sal_uInt16 nPos=COMBOBOX_APPEND );
    void RemoveEntry( String const& rStr );
    void RemoveEntry( sal_uInt16 nPos );
    void Clear();

    sal_uInt16 GetEntryPos( String const& rStr ) const;
    String GetEntry( sal_uInt16 nPos ) const;
    sal_uInt16 GetEntryCount() const;

    void SetClickHdl( Link const& rLink );
    void SetSelectHdl( Link const& rLink );
    void EnableAutocomplete (bool enable, bool matchCase=false );
};

class ListBoxImpl;
class TOOLKIT_DLLPUBLIC ListBox : public Control
{
    DECL_GET_IMPL( ListBox );
    DECL_CONSTRUCTORS( ListBox, Control, WB_BORDER );
    DECL_GET_WINDOW (ListBox);

public:
    ~ListBox ();
    sal_uInt16 InsertEntry( String const& rStr, sal_uInt16 nPos=LISTBOX_APPEND );

    void RemoveEntry( String const& rStr );
    void RemoveEntry( sal_uInt16 nPos );
    void Clear();

    sal_uInt16 GetEntryPos( String const& rStr ) const;
    String GetEntry( sal_uInt16 nPos ) const;
    sal_uInt16 GetEntryCount() const;

    void SelectEntry( String const& rStr, bool bSelect=true );
    void SelectEntryPos( sal_uInt16 nPos, bool bSelect=true );

    sal_uInt16 GetSelectEntryCount() const;
    String GetSelectEntry( sal_uInt16 nSelIndex=0 ) const;
    sal_uInt16 GetSelectEntryPos( sal_uInt16 nSelIndex=0 ) const;

    void SetSelectHdl (Link const& link);
    Link& GetSelectHdl ();

    void SetClickHdl (Link const& link);
    Link& GetClickHdl ();

    void SetDoubleClickHdl (Link const& link);
    Link& GetDoubleClickHdl ();

    void SetEntryData (sal_uInt16 pos, void* data);
    void* GetEntryData (sal_uInt16 pos) const;

	virtual void SetNoSelection ();
};

class MultiListBoxImpl;
class TOOLKIT_DLLPUBLIC MultiListBox : public ListBox
{
    DECL_GET_IMPL( MultiListBox );
    DECL_CONSTRUCTORS( MultiListBox, ListBox, 0 );
    DECL_GET_WINDOW( MultiListBox );
};

class DialogImpl;
class TOOLKIT_DLLPUBLIC Dialog : public Context, public Window
{
    DECL_GET_WINDOW (Dialog);

public:
    DECL_GET_IMPL (Dialog);
    Dialog( Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0 );
    Dialog( ::Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0 );
    ~Dialog ();
    virtual short Execute();
    void EndDialog( long nResult=0 );
    void SetText( rtl::OUString const& rStr );
    void SetTitle (rtl::OUString const& rStr );
    bool Close ();
    long Notify (NotifyEvent & event);

    // Sxf*Dialog
    bool bConstruct;
	void Initialize (SfxChildWinInfo*);
};

#define DECL_MESSAGE_BOX_CTORS(Name)\
    public:\
    Name##Box (::Window *parent, char const* message,\
               char const* yes=0, char const* no=0, const rtl::OString& help_id=rtl::OString(),\
               char const* xml_file="message-box.xml", char const* id="message-box");\
    Name##Box (::Window *parent, rtl::OUString const& message,\
               rtl::OUString yes=String (),\
               rtl::OUString no=String (),\
               const rtl::OString& help_id=rtl::OString(),\
               char const* xml_file="message-box.xml", char const* id="message-box");\
    Name##Box (::Window *parent, WinBits, char const* message,\
               char const* yes=0, char const* no=0, const rtl::OString& help_id=rtl::OString(),\
               char const* xml_file="message-box.xml", char const* id="message-box");\
    Name##Box (::Window *parent, WinBits, rtl::OUString const& message,\
               rtl::OUString yes=String (),\
               rtl::OUString no=String (),\
               const rtl::OString& help_id=rtl::OString(),\
               char const* xml_file="message-box.xml", char const* id="message-box")\

class TOOLKIT_DLLPUBLIC MessageBox : public Dialog
{
    DECL_MESSAGE_BOX_CTORS(Message);

protected:
    FixedImage imageError;
    FixedImage imageInfo;
    FixedImage imageQuery;
    FixedImage imageWarning;
    FixedText messageText;
    CancelButton cancelButton;
    HelpButton helpButton;
    IgnoreButton ignoreButton;
    NoButton noButton;
    RetryButton retryButton;
    YesButton yesButton;

    void bits_init (WinBits bits, rtl::OUString const& message,
                    rtl::OUString yes, rtl::OUString, const rtl::OString& help_id);
    void init (rtl::OUString const& message,
               rtl::OUString const& yes, rtl::OUString const& no, const rtl::OString& help_id);
    void init (char const* message, char const* yes, char const* no, const rtl::OString& help_id);
};

#define CLASS_MESSAGE_BOX(Name)\
    class TOOLKIT_DLLPUBLIC Name##Box : public MessageBox\
    {\
        DECL_MESSAGE_BOX_CTORS (Name);\
    }

//CLASS_MESSAGE_BOX (Mess);
typedef MessageBox MessBox;
CLASS_MESSAGE_BOX (Error);
CLASS_MESSAGE_BOX (Info);
CLASS_MESSAGE_BOX (Query);
CLASS_MESSAGE_BOX (Warning);

#undef CLASS_MESSAGE_BOX

#undef TAB_APPEND

class TabControlImpl;
class TOOLKIT_DLLPUBLIC TabControl : public Control
{
//#ifndef TAB_APPEND
#define TAB_APPEND 0xFFFF
//#endif /* !TAB_APPEND */

    DECL_GET_IMPL (TabControl);
    DECL_CONSTRUCTORS (TabControl, Control, 0);
    DECL_GET_WINDOW (TabControl);
    DECL_GET_LAYOUT_VCLXWINDOW (TabControl);

public:
    ~TabControl ();
    void InsertPage (sal_uInt16 id, rtl::OUString const& title, sal_uInt16 pos=TAB_APPEND);
    void RemovePage (sal_uInt16 id);
    sal_uInt16 GetPageCount () const;
    sal_uInt16 GetPageId (sal_uInt16 pos) const;
    sal_uInt16 GetPagePos (sal_uInt16 id) const;
    void SetCurPageId (sal_uInt16 id);
    sal_uInt16 GetCurPageId () const;
    void SetTabPage (sal_uInt16 id, ::TabPage* page);
    ::TabPage* GetTabPage (sal_uInt16 id) const;
    void SetActivatePageHdl (Link const& link);
    Link& GetActivatePageHdl () const;
    void SetDeactivatePageHdl (Link const& link);
    Link& GetDeactivatePageHdl () const;
    void SetTabPageSizePixel (Size const& size);
    Size GetTabPageSizePixel () const;
};

class TabPageImpl;
class TOOLKIT_DLLPUBLIC TabPage : public Context, public Window
{
    DECL_GET_IMPL( TabPage );
public:
    static ::Window* global_parent;
    static TabControl* global_tabcontrol;

    TabPage( Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0 );
    TabPage( ::Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0 );
    ~TabPage();
    DECL_GET_WINDOW( TabPage );
    virtual void ActivatePage();
    virtual void DeactivatePage();
};

class ProgressBarImpl;
class TOOLKIT_DLLPUBLIC ProgressBar : public Control
{
    DECL_GET_IMPL( ProgressBar );
    DECL_CONSTRUCTORS( ProgressBar, Control, WB_BORDER );
public:
    void SetForegroundColor( css::util::Color color );
    void SetBackgroundColor( css::util::Color color );
    void SetValue( sal_Int32 i );
    void SetRange( sal_Int32 min, sal_Int32 max );
    sal_Int32 GetValue();
};

// -----------------------------------------------------------------
//                 layout container / helper wrappers
// -----------------------------------------------------------------

class TOOLKIT_DLLPUBLIC Container
{
protected:
    css::uno::Reference< css::awt::XLayoutContainer > mxContainer;
    Container( rtl::OUString const& rName, sal_Int32 nBorder );
public:
    Container( Context const* context, char const* id );

    void Add( Window *pWindow );
    void Add( Container *pContainer );

    void Remove( Window *pWindow );
    void Remove( Container *pContainer );
    void Clear();
    // we can't really do a GetChildren() as they don't have a common class,
    // besides we would need to keep track of children, uh

    void ShowAll( bool bVisible );
    void Show();
    void Hide();

    css::uno::Reference< css::awt::XLayoutContainer > getImpl()
    { return mxContainer; }
};

class TOOLKIT_DLLPUBLIC Table : public Container
{
protected:
    Table( sal_Int32 nBorder, sal_Int32 nColumns );
public:
    Table( Context const* context, char const* id );
    void Add( Window *pWindow, bool bXExpand, bool bYExpand,
              sal_Int32 nXSpan=1, sal_Int32 nYSpan=1 );
    void Add( Container *pContainer, bool bXExpand, bool bYExpand,
              sal_Int32 nXSpan=1, sal_Int32 nYSpan=1 );

private:
    void setProps( css::uno::Reference< css::awt::XLayoutConstrains > xChild,
                   bool bXExpand, bool bYExpand, sal_Int32 nXSpan, sal_Int32 nYSpan );
};

class TOOLKIT_DLLPUBLIC Box : public Container
{
protected:
    Box( rtl::OUString const& rName, sal_Int32 nBorder, bool bHomogeneous );
public:
    Box( Context const* context, char const* id );
    void Add( Window *pWindow, bool bExpand, bool bFill, sal_Int32 nPadding);
    void Add( Container *pContainer, bool bExpand, bool bFill, sal_Int32 nPadding);

private:
    void setProps( css::uno::Reference< css::awt::XLayoutConstrains > xChild,
                   bool bXExpand, bool bYExpand, sal_Int32 nPadding );
};

class TOOLKIT_DLLPUBLIC HBox : public Box
{
public:
    HBox( Context const* context, char const* id );
    HBox( sal_Int32 nBorder, bool bHomogeneous );
};
class TOOLKIT_DLLPUBLIC VBox : public Box
{
public:
    VBox( Context const* context, char const* id );
    VBox( sal_Int32 nBorder, bool bHomogeneous );
};

class PluginImpl;
class TOOLKIT_DLLPUBLIC Plugin : public Control
{
    DECL_GET_IMPL( Plugin );
    //DECL_CONSTRUCTORS( Plugin, Control, 0 );
public:
    ::Control *mpPlugin;
    Plugin( Context *context, char const* id, ::Control *plugin );
};

class LocalizedStringImpl;
class TOOLKIT_DLLPUBLIC LocalizedString : public Window
{
    DECL_GET_IMPL( LocalizedString );

public:
    LocalizedString( Context *context, char const* id );

    rtl::OUString operator= (rtl::OUString const&);
    rtl::OUString operator+= (sal_Unicode );
    rtl::OUString operator+= (rtl::OUString const&);

    operator rtl::OUString ();
    operator rtl::OUString const& ();
    operator String();
    String getString ();
    rtl::OUString getOUString ();
    String GetToken (sal_uInt16 i, sal_Char c);
};

class InPlugImpl;
class TOOLKIT_DLLPUBLIC InPlug : public Context, public Window
{
    DECL_GET_IMPL (InPlug);

public:
    InPlug ( Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0);
    InPlug ( ::Window *parent, char const* xml_file, char const* id, sal_uInt32 nId=0);

    void ParentSet (Window *window);
};

} // end namespace layout

#if ENABLE_LAYOUT
#define LAYOUT_NS layout::
#define LAYOUT_DIALOG_PARENT\
    VCLXWindow::GetImplementation( uno::Reference <awt::XWindow> ( GetPeer(), uno::UNO_QUERY ) )->GetWindow()
#define LAYOUT_THIS_WINDOW( this ) this->GetWindow ()
#else /* !ENABLE_LAYOUT */
#define LAYOUT_NS
#define LAYOUT_DIALOG_PARENT this
#define LAYOUT_THIS_WINDOW( this ) this
#endif /* !ENABLE_LAYOUT */

#endif /* _LAYOUT_HXX */
