/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   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 .
 */

#ifndef INCLUDED_VCL_INC_SVDATA_HXX
#define INCLUDED_VCL_INC_SVDATA_HXX

#include "sal/types.h"

#include <osl/thread.hxx>
#include <rtl/ref.hxx>
#include <rtl/ustring.hxx>
#include "tools/link.hxx"
#include "tools/fldunit.hxx"
#include "tools/color.hxx"
#include "tools/debug.hxx"
#include "tools/solar.h"
#include "vcl/bitmapex.hxx"
#include "vcl/dllapi.h"
#include "vcl/keycod.hxx"
#include "vcl/svapp.hxx"
#include "vcl/vclevent.hxx"

#include "unotools/options.hxx"

#include "xconnection.hxx"

#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/uno/Reference.hxx"

#include <boost/unordered_map.hpp>

#include <config_version.h>

struct ImplTimerData;
struct ImplConfigData;
class ImplDirectFontSubstitution;
struct ImplHotKey;
struct ImplEventHook;
class Point;
class ResMgr;
class ImplAccelManager;
class PhysicalFontCollection;
class ImplFontCache;
class HelpTextWindow;
class ImplTBDragMgr;
class ImplIdleMgr;
class FloatingWindow;
class AllSettings;
class NotifyEvent;
class Timer;
class AutoTimer;
class Help;
class ImageList;
class Image;
class PopupMenu;
class Application;
class OutputDevice;
namespace vcl { class Window; }
class SystemWindow;
class WorkWindow;
class Dialog;
class VirtualDevice;
class Printer;
class SalFrame;
class SalInstance;
class SalSystem;
class ImplPrnQueueList;
class UnoWrapperBase;
class GraphicConverter;
class ImplWheelWindow;
class SalTimer;
class SalI18NImeStatus;
class DockingManager;
class VclEventListeners2;
class SalData;

namespace vcl { class DisplayConnection; class SettingsConfigItem; class DeleteOnDeinitBase; }

class LocaleConfigurationListener : public utl::ConfigurationListener
{
public:
    virtual void ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 ) SAL_OVERRIDE;
};

struct ImplSVAppData
{
    enum ImeStatusWindowMode
    {
        ImeStatusWindowMode_UNKNOWN,
        ImeStatusWindowMode_HIDE,
        ImeStatusWindowMode_SHOW
    };

    AllSettings*            mpSettings;         // Application settings
    LocaleConfigurationListener* mpCfgListener;
    VclEventListeners*      mpEventListeners;   // listeners for vcl events (eg, extended toolkit)
    VclEventListeners*      mpKeyListeners;     // listeners for key events only (eg, extended toolkit)
    ImplAccelManager*       mpAccelMgr;         // Accelerator Manager
    OUString*               mpAppName;          // Application name
    OUString*               mpAppFileName;      // Abs. Application FileName
    OUString*               mpDisplayName;      // Application Display Name
    OUString*               mpFontPath;         // Additional Fontpath
    Help*                   mpHelp;             // Application help
    PopupMenu*              mpActivePopupMenu;  // Actives Popup-Menu (in Execute)
    ImplIdleMgr*            mpIdleMgr;          // Idle-Manager
    ImplWheelWindow*        mpWheelWindow;      // WheelWindow
    ImplHotKey*             mpFirstHotKey;      // HotKey-Verwaltung
    ImplEventHook*          mpFirstEventHook;   // Event-Hooks
    VclEventListeners2*     mpPostYieldListeners;           // post yield listeners
    sal_uLong               mnLastInputTime;                // GetLastInputTime()
    sal_uInt16              mnDispatchLevel;                // DispatchLevel
    sal_uInt16              mnModalMode;                    // ModalMode Count
    sal_uInt16              mnModalDialog;                  // ModalDialog Count
    sal_uInt16              mnAccessCount;                  // AccessHdl Count
    sal_uInt16              mnSysWinMode;                   // Mode, when SystemWindows should be created
    sal_uInt16              mnLayout;                       // --- RTL-Flags --- currently not used, only for testing
    short                   mnDialogScaleX;                 // Scale X-Positions and sizes in Dialogs
    bool                mbInAppMain;                    // is Application::Main() on stack
    bool                mbInAppExecute;                 // is Application::Execute() on stack
    bool                mbAppQuit;                      // is Application::Quit() called
    bool                mbSettingsInit;                 // true: Settings are initialized
    bool                mbNoYield;                      // Application::Yield will not wait for events if the queue is empty
                                                            // essentially that makes it the same as Application::Reschedule
    Application::DialogCancelMode meDialogCancel;           // true: All Dialog::Execute() calls will be terminated immediately with return false
    long                    mnDefaultLayoutBorder;          // default value in pixel for layout distances used
                                                            // in window arrangers

    /** Controls whether showing any IME status window is toggled on or off.

        Only meaningful if showing IME status windows can be toggled on and off
        externally (see Application::CanToggleImeStatusWindow).
     */
    ImeStatusWindowMode meShowImeStatusWindow;

    DECL_STATIC_LINK( ImplSVAppData, ImplQuitMsg, void* );
};

struct ImplSVGDIData
{
    OutputDevice*           mpFirstWinGraphics; // First OutputDevice with a Frame Graphics
    OutputDevice*           mpLastWinGraphics;  // Last OutputDevice with a Frame Graphics
    OutputDevice*           mpFirstVirGraphics; // First OutputDevice with a VirtualDevice Graphics
    OutputDevice*           mpLastVirGraphics;  // Last OutputDevice with a VirtualDevice Graphics
    OutputDevice*           mpFirstPrnGraphics; // First OutputDevice with a InfoPrinter Graphics
    OutputDevice*           mpLastPrnGraphics;  // Last OutputDevice with a InfoPrinter Graphics
    VirtualDevice*          mpFirstVirDev;      // First VirtualDevice
    VirtualDevice*          mpLastVirDev;       // Last VirtualDevice
    Printer*                mpFirstPrinter;     // First Printer
    Printer*                mpLastPrinter;      // Last Printer
    ImplPrnQueueList*       mpPrinterQueueList; // List of all printer queue
    PhysicalFontCollection* mpScreenFontList;   // Screen-Font-List
    ImplFontCache*          mpScreenFontCache;  // Screen-Font-Cache
    ImplDirectFontSubstitution* mpDirectFontSubst;// Font-Substitutons defined in Tools->Options->Fonts
    GraphicConverter*       mpGrfConverter;     // Converter for graphics
    long                    mnRealAppFontX;     // AppFont X-Numenator for 40/tel Width
    long                    mnAppFontX;         // AppFont X-Numenator for 40/tel Width + DialogScaleX
    long                    mnAppFontY;         // AppFont Y-Numenator for 80/tel Height
    bool                    mbFontSubChanged;   // true: FontSubstitution was changed between Begin/End
    bool                    mbNativeFontConfig; // true: do not override UI font
};

struct ImplSVWinData
{
    vcl::Window*                 mpFirstFrame;       // First FrameWindow
    vcl::Window*                 mpDefDialogParent;  // Default Dialog Parent
    WorkWindow*             mpAppWin;           // Application-Window
    vcl::Window*                 mpFocusWin;         // window, that has the focus
    vcl::Window*                 mpActiveApplicationFrame; // the last active application frame, can be used as DefModalDialogParent if no focuswin set
    vcl::Window*                 mpCaptureWin;       // window, that has the mouse capture
    vcl::Window*                 mpLastDeacWin;      // Window, that need a deactivate (FloatingWindow-Handling)
    FloatingWindow*         mpFirstFloat;       // First FloatingWindow in PopupMode
    Dialog*                 mpLastExecuteDlg;   // First Dialog that is in Execute
    vcl::Window*                 mpExtTextInputWin;  // Window, which is in ExtTextInput
    vcl::Window*                 mpTrackWin;         // window, that is in tracking mode
    AutoTimer*              mpTrackTimer;       // tracking timer
    ImageList*              mpMsgBoxImgList;    // ImageList for MessageBox
    vcl::Window*                 mpAutoScrollWin;    // window, that is in AutoScrollMode mode
    sal_uInt16              mnTrackFlags;       // tracking flags
    sal_uInt16              mnAutoScrollFlags;  // auto scroll flags
    bool                mbNoDeactivate;     // true: do not execute Deactivate
    bool                mbNoSaveFocus;      // true: menus must not save/restore focus
    bool                mbNoSaveBackground; // true: save background is unnecessary or even less performant
};

typedef std::vector< std::pair< OUString, FieldUnit > > FieldUnitStringList;

struct ImplSVCtrlData
{
    ImageList*              mpCheckImgList;     // ImageList for CheckBoxes
    ImageList*              mpRadioImgList;     // ImageList for RadioButtons
    ImageList*              mpPinImgList;       // ImageList for PIN
    ImageList*              mpSplitHPinImgList; // ImageList for Horizontale SplitWindows
    ImageList*              mpSplitVPinImgList; // ImageList for Vertikale SplitWindows (PIN's)
    ImageList*              mpSplitHArwImgList; // ImageList for Horizontale SplitWindows (Arrows)
    ImageList*              mpSplitVArwImgList; // ImageList for Vertikale SplitWindows (Arrows)
    Image*                  mpDisclosurePlus;
    Image*                  mpDisclosureMinus;
    ImplTBDragMgr*          mpTBDragMgr;        // DragMgr for ToolBox
    sal_uInt16                  mnCheckStyle;       // CheckBox-Style for ImageList-Update
    sal_uInt16                  mnRadioStyle;       // Radio-Style for ImageList-Update
    sal_uLong                   mnLastCheckFColor;  // Letzte FaceColor fuer CheckImage
    sal_uLong                   mnLastCheckWColor;  // Letzte WindowColor fuer CheckImage
    sal_uLong                   mnLastCheckWTextColor;  // Letzte WindowTextColor fuer CheckImage
    sal_uLong                   mnLastCheckLColor;  // Letzte LightColor fuer CheckImage
    sal_uLong                   mnLastRadioFColor;  // Letzte FaceColor fuer RadioImage
    sal_uLong                   mnLastRadioWColor;  // Letzte WindowColor fuer RadioImage
    sal_uLong                   mnLastRadioLColor;  // Letzte LightColor fuer RadioImage
    FieldUnitStringList*    mpFieldUnitStrings; // list with field units
    FieldUnitStringList*    mpCleanUnitStrings; // same list but with some "fluff" like spaces removed
};

struct ImplSVHelpData
{
    bool                    mbContextHelp       : 1;    // is ContextHelp enabled
    bool                    mbExtHelp           : 1;    // is ExtendedHelp enabled
    bool                    mbExtHelpMode       : 1;    // is in ExtendedHelp Mode
    bool                    mbOldBalloonMode    : 1;    // BallonMode, before ExtHelpMode started
    bool                    mbBalloonHelp       : 1;    // is BalloonHelp enabled
    bool                    mbQuickHelp         : 1;    // is QuickHelp enabled
    bool                    mbSetKeyboardHelp   : 1;    // tiphelp was activated by keyboard
    bool                    mbKeyboardHelp      : 1;    // tiphelp was activated by keyboard
    bool                    mbAutoHelpId        : 1;    // generate HelpIds
    bool                    mbRequestingHelp    : 1;    // In Window::RequestHelp
    HelpTextWindow*         mpHelpWin;                  // HelpWindow
    sal_uLong                   mnLastHelpHideTime;         // ticks of last show
};

// "NWF" means "Native Widget Framework" and was the term used for the
// idea that StarView/OOo "widgets" should *look* (and feel) like the
// "native widgets" on each platform, even if not at all implemented
// using them. See http://people.redhat.com/dcbw/ooo-nwf.html .

struct ImplSVNWFData
{
    int                     mnStatusBarLowerRightOffset;    // amount in pixel to avoid in the lower righthand corner
    int                     mnMenuFormatBorderX;            // horizontal inner popup menu border
    int                     mnMenuFormatBorderY;            // vertical inner popup menu border
    ::Color                 maMenuBarHighlightTextColor;    // override higlight text color
                                                            // in menubar if not transparent
    bool                    mbMenuBarDockingAreaCommonBG:1; // e.g. WinXP default theme
    bool                    mbDockingAreaSeparateTB:1;      // individual toolbar backgrounds
                                                            // instead of one for docking area
    bool                    mbDockingAreaAvoidTBFrames:1;   ///< don't draw frames around the individual toolbars if mbDockingAreaSeparateTB is false
    bool                    mbToolboxDropDownSeparate:1;    // two adjacent buttons for
                                                            // toolbox dropdown buttons
    bool                    mbFlatMenu:1;                   // no popup 3D border
    bool                    mbOpenMenuOnF10:1;              // on gnome the first menu opens on F10
    bool                    mbNoFocusRects:1;               // on Aqua focus rects are not used
    bool                    mbCenteredTabs:1;               // on Aqua, tabs are centered
    bool                    mbNoActiveTabTextRaise:1;       // on Aqua the text for the selected tab
                                                            // should not "jump up" a pixel
    bool                    mbProgressNeedsErase:1;         // set true for platforms that should draw the
                                                            // window background before drawing the native
                                                            // progress bar
    bool                    mbCheckBoxNeedsErase:1;         // set true for platforms that should draw the
                                                            // window background before drawing the native
                                                            // checkbox
    bool                    mbCanDrawWidgetAnySize:1;       // set to true currently on gtk

    /// entire drop down listbox resembles a button, no textarea/button parts (as currently on Windows)
    bool                    mbDDListBoxNoTextArea:1;
};

struct BlendFrameCache
{
    Size m_aLastSize;
    sal_uInt8 m_nLastAlpha;
    Color m_aLastColorTopLeft;
    Color m_aLastColorTopRight;
    Color m_aLastColorBottomRight;
    Color m_aLastColorBottomLeft;
    BitmapEx m_aLastResult;

    BlendFrameCache()
        : m_aLastSize(0, 0)
        , m_nLastAlpha(0)
        , m_aLastColorTopLeft(COL_BLACK)
        , m_aLastColorTopRight(COL_BLACK)
        , m_aLastColorBottomRight(COL_BLACK)
        , m_aLastColorBottomLeft(COL_BLACK)
    {
    }
};

struct ImplSVData
{
    SalData*                mpSalData;
    SalInstance*            mpDefInst;          // Default SalInstance
    Application*            mpApp;              // pApp
    WorkWindow*             mpDefaultWin;       // Default-Window
    bool                    mbDeInit;             // Is VCL deinitializing
    sal_uLong                   mnThreadCount;      // is VCL MultiThread enabled
    ImplConfigData*         mpFirstConfigData;  // Zeiger auf ersten Config-Block
    ImplTimerData*          mpFirstTimerData;   // list of all running timers
    SalTimer*               mpSalTimer;         // interface to sal event loop/timers
    SalI18NImeStatus*       mpImeStatus;        // interface to ime status window
    SalSystem*              mpSalSystem;        // SalSystem interface
    ResMgr*                 mpResMgr;           // SV-Resource-Manager
    sal_uLong                   mnTimerPeriod;      // current timer period
    sal_uLong                   mnTimerUpdate;      // TimerCallbackProcs on stack
    bool                    mbNotAllTimerCalled;// true: Es muessen noch Timer abgearbeitet werden
    bool                    mbNoCallTimer;      // true: No Timeout calls
    ImplSVAppData           maAppData;          // indepen data for class Application
    ImplSVGDIData           maGDIData;          // indepen data for Output classes
    ImplSVWinData           maWinData;          // indepen data for Windows classes
    ImplSVCtrlData          maCtrlData;         // indepen data for Control classes
    ImplSVHelpData          maHelpData;         // indepen data for Help classes
    ImplSVNWFData           maNWFData;
    UnoWrapperBase*         mpUnoWrapper;
    vcl::Window*                 mpIntroWindow;      // the splash screen
    DockingManager*         mpDockingManager;
    BlendFrameCache*        mpBlendFrameCache;
    bool                mbIsTestTool;

    oslThreadIdentifier                     mnMainThreadId;
    rtl::Reference< vcl::DisplayConnection >            mxDisplayConnection;

    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mxAccessBridge;
    ::vcl::SettingsConfigItem*          mpSettingsConfigItem;
    std::list< vcl::DeleteOnDeinitBase* >*   mpDeinitDeleteList;
    boost::unordered_map< int, OUString >*     mpPaperNames;

    Link maDeInitHook;
};

void        ImplInitSVData();
void        ImplDeInitSVData();
void        ImplDestroySVData();
vcl::Window*     ImplGetDefaultWindow();
VCL_PLUGIN_PUBLIC ResMgr*     ImplGetResMgr();
VCL_PLUGIN_PUBLIC ResId VclResId( sal_Int32 nId ); // throws std::bad_alloc if no res mgr
DockingManager*     ImplGetDockingManager();
BlendFrameCache*    ImplGetBlendFrameCache();
void        ImplWindowAutoMnemonic( vcl::Window* pWindow );

void        ImplUpdateSystemProcessWindow();

bool        ImplCallHotKey( const vcl::KeyCode& rKeyCode );
void        ImplFreeHotKeyData();
void        ImplFreeEventHookData();

bool        ImplCallPreNotify( NotifyEvent& rEvt );

extern VCL_PLUGIN_PUBLIC ImplSVData* pImplSVData;
inline ImplSVData* ImplGetSVData() { return pImplSVData; }
VCL_PLUGIN_PUBLIC void ImplHideSplash();

bool ImplInitAccessBridge();

FieldUnitStringList* ImplGetFieldUnits();
FieldUnitStringList* ImplGetCleanedFieldUnits();

// ImplDelData is used as a "dog tag" by a window when it
// does something that could indirectly destroy the window
// TODO: wild destruction of a window should not be possible

struct ImplDelData
{
    ImplDelData*    mpNext;
    const vcl::Window*   mpWindow;
    bool            mbDel;

                    ImplDelData( const vcl::Window* pWindow = NULL )
                    : mpNext( NULL ), mpWindow( NULL ), mbDel( false )
                    { if( pWindow ) AttachToWindow( pWindow ); }

    virtual         ~ImplDelData();

    bool            IsDead() const
    {
        DBG_ASSERT( mbDel == false, "object deleted while in use !" );
        return mbDel;
    }

private:
    void            AttachToWindow( const vcl::Window* );
};

struct ImplFocusDelData : public ImplDelData
{
    vcl::Window*         mpFocusWin;
};

struct ImplSVEvent
{
    void*               mpData;
    Link*               mpLink;
    vcl::Window*             mpWindow;
    ImplDelData         maDelData;
    bool                mbCall;
};

#endif // INCLUDED_VCL_INC_SVDATA_HXX

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