//------------------------------------------------------------------------------
// emScreen.h
//
// Copyright (C) 2005-2011,2016-2017,2022 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program 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 General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------

#ifndef emScreen_h
#define emScreen_h

#ifndef emModel_h
#include <emCore/emModel.h>
#endif

class emWindow;
class emWindowPort;


//==============================================================================
//================================== emScreen ==================================
//==============================================================================

class emScreen : public emModel {

public:

        // This model class acts as an interface to the screen or desktop. It is
        // an abstract base class for an interface implementation. Such an
        // implementation should also define a public method like this:
        //
        //   static void Install(emContext & context);
        //
        // That method should find or create an instance of the interface
        // implementation within the given context, and it should call the
        // protected method Install for registering it as the interface to be
        // returned by LookupInherited. The main program or the emGUIFramework
        // implementation should call the public Install method on the root
        // context at program start.

        static emRef<emScreen> LookupInherited(emContext & context);
                // Get a reference to the screen interface.
                // Arguments:
                //   context - The context where the screen interface has been
                //             installed, or any descendant context. Typically,
                //             it should have been installed in the root
                //             context, so you can give any context here.
                // Returns:
                //   The reference to the interface, or a NULL reference if not
                //   found.

        virtual void GetDesktopRect(
                double * pX, double * pY, double * pW, double * pH
        ) const = 0;
                // Get the pixel coordinates of this (virtual) desktop.
                // Arguments:
                //   pX - Pointer for returning the X-position of the rectangle.
                //   pY - Pointer for returning the Y-position of the rectangle.
                //   pW - Pointer for returning the width of the rectangle.
                //   pH - Pointer for returning the height of the rectangle.

        virtual int GetMonitorCount() const = 0;
                // Get the number of display monitors showing this (virtual)
                // desktop.

        virtual void GetMonitorRect(
                int index, double * pX, double * pY, double * pW, double * pH
        ) const = 0;
                // Get the pixel coordinates of a display monitor on this
                // (virtual) desktop.
                // Arguments:
                //   index - Index of the monitor (0...GetMonitorCount()).
                //   pX    - Pointer for returning the X-position of the rectangle.
                //   pY    - Pointer for returning the Y-position of the rectangle.
                //   pW    - Pointer for returning the width of the rectangle.
                //   pH    - Pointer for returning the height of the rectangle.

        int GetMonitorIndexOfRect(double x, double y, double w, double h) const;
                // Get the index of the monitor which contains the given
                // rectangle or the biggest part of it. If the rectangle is
                // beyond all monitors, the index of the primary monitor is
                // returned (which is 0).

        virtual double GetDPI() const = 0;
                // Get pixels per inch of the primary monitor (horizontally).

        const emSignal & GetGeometrySignal() const;
                // This signal is signaled on any change in the results of
                // GetDesktopRect, GetMonitorCount, GetMonitorRect and GetDPI.

        virtual bool CanMoveMousePointer() const = 0;
                // Whether MoveMousePointer(..) has an effect.

        virtual void MoveMousePointer(double dx, double dy) = 0;
                // Move the mouse pointer programmatically.
                // Arguments:
                //   dx - Amount of pixels to move the pointer in X direction.
                //   dy - Amount of pixels to move the pointer in Y direction.

        virtual void Beep() = 0;
                // Give an acoustic warning to the user, if possible.

        const emArray<emWindow*> & GetWindows() const;
                // Get an array of pointers to all windows on the screen, which
                // have been created within the context of this screen
                // interface. Other windows are not included.

        const emSignal & GetWindowsSignal() const;
                // This signal is signaled when the array returned by GetWindows
                // has changed.

        void LeaveFullscreenModes(emWindow * exceptForWindow=NULL);
                // Make sure that no window is in fullscreen mode, except for a
                // given one, optionally. This concerns only windows that have
                // been created within the context of this screen interface.

protected:

        friend class emWindow;

        emScreen(emContext & context, const emString & name);
                // See emModel.

        virtual ~emScreen();

        void Install();
                // Register this interface so that it can be found by
                // LookupInherited.

        void SignalGeometrySignal();
                // Signal a change in the results of GetDesktopRect,
                // GetMonitorCount, GetMonitorRect or GetDPI.

        virtual emWindowPort * CreateWindowPort(emWindow & window) = 0;
                // Create a window port implementation for a new window on the
                // screen. (This is called by the constructor of emWindow)

private:
        emArray<emWindow*> Windows;
        emSignal GeometrySignal;
        emSignal WindowsSignal;
};

inline const emSignal & emScreen::GetGeometrySignal() const
{
        return GeometrySignal;
}

inline const emArray<emWindow*> & emScreen::GetWindows() const
{
        return Windows;
}

inline const emSignal & emScreen::GetWindowsSignal() const
{
        return WindowsSignal;
}

inline void emScreen::SignalGeometrySignal()
{
        Signal(GeometrySignal);
}


#endif