/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-6 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified under the terms of the
   GNU General Public License, as published by the Free Software Foundation;
   either version 2 of the License, or (at your option) any later version.

   JUCE 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 for more details.

   You should have received a copy of the GNU General Public License
   along with JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

#ifndef __JUCE_DESKTOP_JUCEHEADER__
#define __JUCE_DESKTOP_JUCEHEADER__

#include "juce_Component.h"
#include "../../application/juce_DeletedAtShutdown.h"
#include "../../events/juce_Timer.h"


//==============================================================================
/**
    Describes and controls aspects of the computer's desktop.

*/
class JUCE_API  Desktop  : private DeletedAtShutdown,
                           private Timer
{
public:
    //==============================================================================
    /** There's only one dektop object, and this method will return it.
    */
    static Desktop& getInstance();

    //==============================================================================
    /** Returns a list of the positions of all the monitors available.

        The first rectangle in the list will be the main monitor area, and will
        NOT include areas like the taskbar on Windows, or the menu bar on Mac.
    */
    const RectangleList getAllMonitorDisplayAreas() const;

    /** Returns the position and size of the main monitor. */
    const Rectangle getMainMonitorArea() const;

    /** Returns the position and size of the monitor which contains this co-ordinate.

        If none of the monitors contains the point, this will just return the
        main monitor.
    */
    const Rectangle getMonitorAreaContaining (int x, int y) const;


    //==============================================================================
    /** Returns the mouse position.

        The co-ordinates are relative to the top-left of the main monitor.
    */
    static void getMousePosition (int& x, int& y);

    /** Makes the mouse pointer jump to a given location.

        The co-ordinates are relative to the top-left of the main monitor.
    */
    static void setMousePosition (int x, int y);

    /** Returns the last position at which a mouse button was pressed.
    */
    static void getLastMouseDownPosition (int& x, int& y);

    /** Returns the number of times the mouse button has been clicked since the
        app started.

        Each mouse-down event increments this number by 1.
    */
    static int getMouseButtonClickCounter();

    //==============================================================================
    /** Registers a MouseListener that will receive all mouse events that occur on
        any component.

        @see removeGlobalMouseListener
    */
    void addGlobalMouseListener (MouseListener* listener);

    /** Unregisters a MouseListener that was added with the addGlobalMouseListener()
        method.

        @see addGlobalMouseListener
    */
    void removeGlobalMouseListener (MouseListener* listener);

    //==============================================================================
    /** Returns the number of components that are currently active as top-level
        desktop windows.

        @see getComponent, Component::addToDesktop
    */
    int getNumComponents() const;

    /** Returns one of the top-level desktop window components.

        The index is from 0 to getNumComponents() - 1. This could return 0 if the
        index is out-of-range.

        @see getNumComponents, Component::addToDesktop
    */
    Component* getComponent (const int index) const;

    /** Finds the component at a given screen location.

        This will drill down into top-level windows to find the child component at
        the given position.

        Returns 0 if the co-ordinates are inside a non-Juce window.
    */
    Component* findComponentAt (const int screenX,
                                const int screenY) const;


    //==============================================================================
    juce_UseDebuggingNewOperator

    /** Tells this object to refresh its idea of what the screen resolution is.

        (Called internally by the native code).
    */
    void refreshMonitorSizes();

    /** True if the OS supports semitransparent windows */
    static bool canUseSemiTransparentWindows();


private:
    //==============================================================================
    friend class Component;
    friend class ComponentPeer;
    VoidArray mouseListeners;
    VoidArray desktopComponents;

    friend class DeletedAtShutdown;
    Desktop();
    ~Desktop();

    Array <Rectangle> monitorCoords;
    int lastMouseX, lastMouseY;

    void timerCallback();
    void sendMouseMove();
    void resetTimer();
    int getNumDisplayMonitors() const;
    const Rectangle getDisplayMonitorCoordinates (const int index) const;

    void addDesktopComponent (Component* const c);
    void removeDesktopComponent (Component* const c);
    void componentBroughtToFront (Component* const c);

    Desktop (const Desktop&);
    const Desktop& operator= (const Desktop&);
};


#endif   // __JUCE_DESKTOP_JUCEHEADER__
