/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * 
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SV_BRDWIN_HXX
#define _SV_BRDWIN_HXX

#include <vcl/sv.h>
#include <vcl/window.hxx>

class ImplBorderWindowView;

// --------------------------
// - ImplBorderWindow-Types -
// --------------------------

#define BORDERWINDOW_STYLE_OVERLAP			((sal_uInt16)0x0001)
#define BORDERWINDOW_STYLE_BORDER			((sal_uInt16)0x0002)
#define BORDERWINDOW_STYLE_FLOAT			((sal_uInt16)0x0004)
#define BORDERWINDOW_STYLE_FRAME			((sal_uInt16)0x0008)
#define BORDERWINDOW_STYLE_APP				((sal_uInt16)0x0010)

#define BORDERWINDOW_HITTEST_TITLE			((sal_uInt16)0x0001)
#define BORDERWINDOW_HITTEST_LEFT			((sal_uInt16)0x0002)
#define BORDERWINDOW_HITTEST_MENU			((sal_uInt16)0x0004)
#define BORDERWINDOW_HITTEST_TOP			((sal_uInt16)0x0008)
#define BORDERWINDOW_HITTEST_RIGHT			((sal_uInt16)0x0010)
#define BORDERWINDOW_HITTEST_BOTTOM 		((sal_uInt16)0x0020)
#define BORDERWINDOW_HITTEST_TOPLEFT		((sal_uInt16)0x0040)
#define BORDERWINDOW_HITTEST_TOPRIGHT		((sal_uInt16)0x0080)
#define BORDERWINDOW_HITTEST_BOTTOMLEFT 	((sal_uInt16)0x0100)
#define BORDERWINDOW_HITTEST_BOTTOMRIGHT	((sal_uInt16)0x0200)
#define BORDERWINDOW_HITTEST_CLOSE			((sal_uInt16)0x0400)
#define BORDERWINDOW_HITTEST_ROLL			((sal_uInt16)0x0800)
#define BORDERWINDOW_HITTEST_DOCK			((sal_uInt16)0x1000)
#define BORDERWINDOW_HITTEST_HIDE			((sal_uInt16)0x2000)
#define BORDERWINDOW_HITTEST_HELP			((sal_uInt16)0x4000)
#define BORDERWINDOW_HITTEST_PIN			((sal_uInt16)0x8000)

#define BORDERWINDOW_DRAW_TITLE 			((sal_uInt16)0x0001)
#define BORDERWINDOW_DRAW_BORDER			((sal_uInt16)0x0002)
#define BORDERWINDOW_DRAW_FRAME 			((sal_uInt16)0x0004)
#define BORDERWINDOW_DRAW_CLOSE 			((sal_uInt16)0x0008)
#define BORDERWINDOW_DRAW_ROLL				((sal_uInt16)0x0010)
#define BORDERWINDOW_DRAW_DOCK				((sal_uInt16)0x0020)
#define BORDERWINDOW_DRAW_HIDE				((sal_uInt16)0x0040)
#define BORDERWINDOW_DRAW_HELP				((sal_uInt16)0x0080)
#define BORDERWINDOW_DRAW_PIN				((sal_uInt16)0x0100)
#define BORDERWINDOW_DRAW_MENU				((sal_uInt16)0x0200)
#define BORDERWINDOW_DRAW_ALL				(BORDERWINDOW_DRAW_TITLE |		\
                                             BORDERWINDOW_DRAW_BORDER | 	\
                                             BORDERWINDOW_DRAW_FRAME |		\
                                             BORDERWINDOW_DRAW_CLOSE |		\
                                             BORDERWINDOW_DRAW_ROLL |		\
                                             BORDERWINDOW_DRAW_DOCK |		\
                                             BORDERWINDOW_DRAW_HIDE |		\
                                             BORDERWINDOW_DRAW_HELP |		\
                                             BORDERWINDOW_DRAW_PIN  |		\
                                             BORDERWINDOW_DRAW_MENU)

#define BORDERWINDOW_TITLE_NORMAL			((sal_uInt16)0x0001)
#define BORDERWINDOW_TITLE_SMALL			((sal_uInt16)0x0002)
#define BORDERWINDOW_TITLE_TEAROFF			((sal_uInt16)0x0004)
#define BORDERWINDOW_TITLE_POPUP			((sal_uInt16)0x0008)
#define BORDERWINDOW_TITLE_NONE 			((sal_uInt16)0x0010)

// --------------------
// - ImplBorderWindow -
// --------------------

class ImplBorderWindow : public Window
{
    friend class Window;
    friend class ImplBorderWindowView;
    friend class ImplSmallBorderWindowView;
    friend class ImplStdBorderWindowView;

private:
    ImplBorderWindowView*	mpBorderView;
    Window* 				mpMenuBarWindow;
    long					mnMinWidth;
    long					mnMinHeight;
    long					mnMaxWidth;
    long					mnMaxHeight;
    long					mnRollHeight;
    long					mnOrgMenuHeight;
    sal_uInt16					mnTitleType;
    sal_uInt16					mnBorderStyle;
    sal_Bool					mbFloatWindow;
    sal_Bool					mbSmallOutBorder;
    sal_Bool					mbFrameBorder;
    sal_Bool					mbPined;
    sal_Bool					mbRollUp;
    sal_Bool					mbMenuHide;
    sal_Bool					mbDockBtn;
    sal_Bool					mbHideBtn;
    sal_Bool					mbHelpBtn;
    sal_Bool                    mbMenuBtn;
    sal_Bool					mbDisplayActive;

    using Window::ImplInit;
    void					ImplInit( Window* pParent,
                                      WinBits nStyle, sal_uInt16 nTypeStyle,
                                      SystemParentData* pParentData );
    void					ImplInit( Window* pParent,
                                      WinBits nStyle, sal_uInt16 nTypeStyle, 
                                      const ::com::sun::star::uno::Any& );

                            // Copy assignment is forbidden and not implemented.
                            ImplBorderWindow (const ImplBorderWindow &);
                            ImplBorderWindow& operator= (const ImplBorderWindow &);

public:
                            ImplBorderWindow( Window* pParent,
                                              SystemParentData* pParentData,
                                              WinBits nStyle = 0,
                                              sal_uInt16 nTypeStyle = 0 );
                            ImplBorderWindow( Window* pParent, WinBits nStyle = 0,
                                              sal_uInt16 nTypeStyle = 0 );
                            ImplBorderWindow( Window* pParent,
                                              WinBits nStyle, sal_uInt16 nTypeStyle, 
                                              const ::com::sun::star::uno::Any& );
                            ~ImplBorderWindow();

    virtual void			MouseMove( const MouseEvent& rMEvt );
    virtual void			MouseButtonDown( const MouseEvent& rMEvt );
    virtual void			Tracking( const TrackingEvent& rTEvt );
    virtual void			Paint( const Rectangle& rRect );
    virtual void			Activate();
    virtual void			Deactivate();
    virtual void			Resize();
    virtual void			RequestHelp( const HelpEvent& rHEvt );
    virtual void			StateChanged( StateChangedType nType );
    virtual void			DataChanged( const DataChangedEvent& rDCEvt );

    void					InitView();
    void					UpdateView( sal_Bool bNewView, const Size& rNewOutSize );
    void					InvalidateBorder();

    using Window::Draw;
    void					Draw( const Rectangle& rRect, OutputDevice* pDev, const Point& rPos );

    void					SetDisplayActive( sal_Bool bActive );
    sal_Bool					IsDisplayActive() const { return mbDisplayActive; }
    void					SetTitleType( sal_uInt16 nTitleType, const Size& rSize );
    void					SetBorderStyle( sal_uInt16 nStyle );
    sal_uInt16					GetBorderStyle() const { return mnBorderStyle; }
    void					SetPin( sal_Bool bPin );
    void					SetRollUp( sal_Bool bRollUp, const Size& rSize );
    void					SetCloser();
    void					SetDockButton( sal_Bool bDockButton );
    void					SetHideButton( sal_Bool bHideButton );
    void					SetHelpButton( sal_Bool bHelpButton );
    void					SetMenuButton( sal_Bool bMenuButton );

    void					UpdateMenuHeight();
    void					SetMenuBarWindow( Window* pWindow );
    void					SetMenuBarMode( sal_Bool bHide );

    void					SetMinOutputSize( long nWidth, long nHeight )
                                { mnMinWidth = nWidth; mnMinHeight = nHeight; }
    void					SetMaxOutputSize( long nWidth, long nHeight )
                                { mnMaxWidth = nWidth; mnMaxHeight = nHeight; }

    void					GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                       sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const;
    long					CalcTitleWidth() const;

    Rectangle               GetMenuRect() const;
};

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

// -----------------------
// - ImplBorderFrameData -
// -----------------------

struct ImplBorderFrameData
{
    ImplBorderWindow*		mpBorderWindow;
    OutputDevice*			mpOutDev;
    Rectangle				maTitleRect;
    Rectangle				maPinRect;
    Rectangle				maCloseRect;
    Rectangle				maRollRect;
    Rectangle				maDockRect;
    Rectangle				maMenuRect;
    Rectangle				maHideRect;
    Rectangle				maHelpRect;
    Point					maMouseOff;
    long					mnWidth;
    long					mnHeight;
    long					mnTrackX;
    long					mnTrackY;
    long					mnTrackWidth;
    long					mnTrackHeight;
    sal_Int32				mnLeftBorder;
    sal_Int32				mnTopBorder;
    sal_Int32				mnRightBorder;
    sal_Int32				mnBottomBorder;
    long					mnNoTitleTop;
    long					mnBorderSize;
    long					mnTitleHeight;
    long					mnTitleOff;
    sal_uInt16					mnHitTest;
    sal_uInt16					mnPinState;
    sal_uInt16					mnCloseState;
    sal_uInt16					mnRollState;
    sal_uInt16					mnDockState;
    sal_uInt16					mnMenuState;
    sal_uInt16					mnHideState;
    sal_uInt16					mnHelpState;
    sal_uInt16					mnTitleType;
    sal_Bool					mbFloatWindow;
    sal_Bool					mbDragFull;
    sal_Bool                    mbTitleClipped;
};

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

// ------------------------
// - ImplBorderWindowView -
// ------------------------

class ImplBorderWindowView
{
public:
    virtual 				~ImplBorderWindowView();

    virtual sal_Bool			MouseMove( const MouseEvent& rMEvt );
    virtual sal_Bool			MouseButtonDown( const MouseEvent& rMEvt );
    virtual sal_Bool			Tracking( const TrackingEvent& rTEvt );
    virtual String  		RequestHelp( const Point& rPos, Rectangle& rHelpRect );

    virtual void			Init( OutputDevice* pDev, long nWidth, long nHeight ) = 0;
    virtual void			GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                       sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const = 0;
    virtual long			CalcTitleWidth() const = 0;
    virtual void			DrawWindow( sal_uInt16 nDrawFlags, OutputDevice* pOutDev = NULL, const Point* pOffset = NULL ) = 0;
    virtual Rectangle       GetMenuRect() const;

    void					ImplInitTitle( ImplBorderFrameData* pData );
    sal_uInt16					ImplHitTest( ImplBorderFrameData* pData, const Point& rPos );
    sal_Bool					ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt );
    sal_Bool					ImplMouseButtonDown( ImplBorderFrameData* pData, const MouseEvent& rMEvt );
    sal_Bool					ImplTracking( ImplBorderFrameData* pData, const TrackingEvent& rTEvt );
    String					ImplRequestHelp( ImplBorderFrameData* pData, const Point& rPos, Rectangle& rHelpRect );
    long					ImplCalcTitleWidth( const ImplBorderFrameData* pData ) const;
};

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

// --------------------------
// - ImplNoBorderWindowView -
// --------------------------

class ImplNoBorderWindowView : public ImplBorderWindowView
{
public:
                            ImplNoBorderWindowView( ImplBorderWindow* pBorderWindow );

    virtual void			Init( OutputDevice* pDev, long nWidth, long nHeight );
    virtual void			GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                       sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const;
    virtual long			CalcTitleWidth() const;
    virtual void			DrawWindow( sal_uInt16 nDrawFlags, OutputDevice* pOutDev, const Point* pOffset );
};


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

// -----------------------------
// - ImplSmallBorderWindowView -
// -----------------------------

class ImplSmallBorderWindowView : public ImplBorderWindowView
{
    ImplBorderWindow*		mpBorderWindow;
    OutputDevice*			mpOutDev;
    long					mnWidth;
    long					mnHeight;
    sal_Int32				mnLeftBorder;
    sal_Int32				mnTopBorder;
    sal_Int32				mnRightBorder;
    sal_Int32				mnBottomBorder;
    bool                    mbNWFBorder;

public:
                            ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow );

    virtual void			Init( OutputDevice* pOutDev, long nWidth, long nHeight );
    virtual void			GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                       sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const;
    virtual long			CalcTitleWidth() const;
    virtual void			DrawWindow( sal_uInt16 nDrawFlags, OutputDevice* pOutDev, const Point* pOffset );
};


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

// ---------------------------
// - ImplStdBorderWindowView -
// ---------------------------


class ImplStdBorderWindowView : public ImplBorderWindowView
{
    ImplBorderFrameData 	maFrameData;
    VirtualDevice*			mpATitleVirDev;
    VirtualDevice*			mpDTitleVirDev;

public:
                            ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow );
                            ~ImplStdBorderWindowView();

    virtual sal_Bool			MouseMove( const MouseEvent& rMEvt );
    virtual sal_Bool			MouseButtonDown( const MouseEvent& rMEvt );
    virtual sal_Bool			Tracking( const TrackingEvent& rTEvt );
    virtual String  		RequestHelp( const Point& rPos, Rectangle& rHelpRect );
    virtual Rectangle       GetMenuRect() const;

    virtual void			Init( OutputDevice* pDev, long nWidth, long nHeight );
    virtual void			GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
                                       sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const;
    virtual long			CalcTitleWidth() const;
    virtual void			DrawWindow( sal_uInt16 nDrawFlags, OutputDevice* pOutDev, const Point* pOffset );
};


#endif	// _SV_BRDWIN_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
