/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

package org.gnu.gdk;

import org.gnu.glib.GObject;
import org.gnu.glib.Handle;

/**
 * Controls the keyboard/mouse pointer grabs and a 	set of Screens.
 */
public class Display extends GObject {

	/**
	 * Creates the default Display.
	 */
	public Display() {
		super(gdk_display_get_default());
	}
	
	public Display(Handle hndl) {
		super(hndl);
	}
	
	/**
	 * Opens a Display.
	 * @param name
	 */
	public static Display open(String name) {
	    Handle hndl = gdk_display_open(name);
		return new Display(hndl);
	}
	
	/**
	 * Gets the name of the Display.
	 */
	public String getName() {
		return gdk_display_get_name(getHandle());
	}
	
	/**
	 * Gets the number of Screens managed by the Display.
	 */
	public int getNumScreens() {
		return gdk_display_get_n_screens(getHandle());
	}
	
	/**
	 * Gets the a Screen object for one of the screens of the display.
	 * @param screenNumber
	 */
	public Screen getScreen(int screenNumber) {
	    Handle hndl = gdk_display_get_screen(getHandle(), screenNumber);
		GObject obj = getGObjectFromHandle(hndl);
		if (null != obj)
			return (Screen)obj;
		return new Screen(hndl);
	}
	
	/**
	 * Gets the default Screen for display.
	 */
	public Screen getDefaultScreen() {
	    Handle hndl = gdk_display_get_default_screen(getHandle());
		GObject obj = getGObjectFromHandle(hndl);
		if (null != obj)
			return (Screen)obj;
		return new Screen(hndl);
	}
	
	/**
	 * Releases any pointer grab.
	 */
	public void ungrabPointer() {
		gdk_display_pointer_ungrab(getHandle(), 0);
	}

	/**
	 * Releases any keyboard grab.
	 */
	public void ungrabKeyboard() {
		gdk_display_keyboard_ungrab(getHandle(), 0);
	}

	/**
	 * Tests if the pointer is grabbed.
	 */
	public boolean pointerIsGrabbed() {
		return gdk_display_pointer_is_grabbed(getHandle());
	}
	
	/**
	 * Emits a short beep on display.
	 */
	public void beep() {
		gdk_display_beep(getHandle());
	}

	/**
	 * Flushes any requests queued for the windowing system and
	 * waits until all requests are handled.  This is often used
	 * for making sure that the display is synchronized with the
	 * current state of the program.
	 */
	public void sync() {
		gdk_display_sync(getHandle());
	}
	
	/**
	 * Flushes any requests queued for the windowing system; this
	 * happens automatically when the main loop block waiting for
	 * events, but if your application is drawing without returning
	 * control to the main loop, you may need to call this method
	 * explicitely.  A common case where this method needs to be
	 * called is when an application is executing drawing commands
	 * from a thread other than the thread where the main loop is
	 * running.
	 */
	public void flush() {
		gdk_display_flush(getHandle());
	}
	
	/**
	 * Closes the connection to the windowing system for this display
	 * and cleans up associated resources.
	 */
	public void close() {
		gdk_display_close(getHandle());
	}
	
	/**
	 * Returns an array of available input devices attached to this
	 * display.
	 */
	public Device[] listDevice() {
	    Handle[] hndls = gdk_display_list_devices(getHandle());
		if (null == hndls)
			return null;
		Device[] devices = new Device[hndls.length];
		for (int i = 0; i < hndls.length; i++) {
			GObject obj = getGObjectFromHandle(hndls[i]);
			if (null != obj)
				devices[i] = (Device)obj;
			else
				devices[i] = new Device(hndls[i]);
		}
		return devices;
	}

	/**
	 * Gets the next event to be processed by the display,
	 * fetching events from the windowing system if necessary.
	 */
	public Event getEvent() {
		return new Event(gdk_display_get_event(getHandle()));
	}
	
	/**
	 * Gets a copy of the first event in the display's event
	 * queue without removing the event from the queue.
	 */
	public Event peekEvent() {
		return new Event(gdk_display_peek_event(getHandle()));
	}
	
	/**
	 * Appends a copy of a given event onto the front of the
	 * event queue for the display.
	 * @param anEvent
	 */
	public void putEvent(Event anEvent) {
		gdk_display_put_event(getHandle(), anEvent.getHandle());
	}
	
	/**
	 * Returns the point where the pointer is currently pointing.
	 */
	public Point getPointerLocation() {
		Handle screen = GObject.getNullHandle();
		int[] x = new int[1];
		int[] y = new int[1];
		int[] modType = new int[1];
		gdk_display_get_pointer(getHandle(), screen, x, y, modType);
		return new Point(x[0], y[0]);
	}
	
	/**
	 * Returns the screen that the pointer is on.
	 */
	public Screen getPointerScreen() {
		Handle screen = GObject.getNullHandle();
		int[] x = new int[1];
		int[] y = new int[1];
		int[] modType = new int[1];
		gdk_display_get_pointer(getHandle(), screen, x, y, modType);
		return new Screen(screen);
	}
	
	public Device getCorePointer() {
	    Handle hndl = gdk_display_get_core_pointer(getHandle());
		GObject obj = getGObjectFromHandle(hndl);
		if (null != obj)
			return (Device)obj;
		return new Device(hndl);
	}
	
	/**
	 * Obtains the window underneath the mouse pointer.
	 */
	public Window getWindowAtPointer() {
	    Handle hndl = gdk_display_get_window_at_pointer(getHandle(), 0, 0);
		GObject obj = getGObjectFromHandle(hndl);
		if (null != obj)
			return (Window)obj;
		return new Window(hndl);
	}

	/**
	 * Returns true if the cursor can use an 8bit alpha channel
	 * on display.
	 */
	public boolean supportsCursorAlpha() {
		return gdk_display_supports_cursor_alpha(getHandle());
	}
	
	/**
	 * Returns true if multicolored cursors are supported on the
	 * display.
	 */
	public boolean supportsCursorColor() {
		return gdk_display_supports_cursor_color(getHandle());
	}

	/**
	 * Returns the default size to use for cursors on display.
	 */
	public int getDefaultCursorSize() {
		return gdk_display_get_default_cursor_size(getHandle());
	}

	/**
	 * Return the maximum width for a cursor on display.
	 */
	public int getMaxCursorWidth() {
		int[] width = new int[1];
		int[] height = new int[1];
		gdk_display_get_maximum_cursor_size(getHandle(), width, height);
		return width[0];
	}
	
	/**
	 * Return the maximum height for a cursor on display.
	 */
	public int getMaxCursorHeight() {
		int[] width = new int[1];
		int[] height = new int[1];
		gdk_display_get_maximum_cursor_size(getHandle(), width, height);
		return height[0];
	}
	
	/**
	 * Returns the default group leader window for all toplevel
	 * windows on display.
	 */
	public Window getDefaultGroup() {
		return new Window(gdk_display_get_default_group(getHandle()));
	}
	
	/**
	 * Returns whether EventOwnerChange events will be sent when
	 * the owner of a selection changes.
	 */
	public boolean supportsSelectionNotification() {
		return gdk_display_supports_selection_notification(getHandle());
	}
	
	/**
	 * Requests EventOwnerChange events for ownership changes of the
	 * selection named by the given atom.
	 * @param atom
	 */
	public boolean requestSelectionNotification(Atom atom) {
		return gdk_display_request_selection_notification(getHandle(), atom.getHandle());
	}
	 
	/**
	 * Returns whether the display supports clipboard persistence; i.e.
	 * if it is possible to store the clipboard data after an application
	 * has quit.
	 */
	public boolean supportsClipboardPersistence() {
		return gdk_display_supports_clipboard_persistence(getHandle());
	}
	
	/**
	 * Issues a request to the clipboard manager to store the clipboard
	 * data.
	 * @param clipboardWindow
	 * @param targets
	 */
	public void storeClipboard(Window clipboardWindow, Atom[] targets) {
		Handle[] tar = new Handle[targets.length];
		for (int i = 0; i < targets.length; i++) 
			tar[i] = targets[i].getHandle();
		gdk_display_store_clipboard(getHandle(), clipboardWindow.getHandle(), 0, tar);
	}
	

	native static final protected int gdk_display_get_type();
	native static final protected Handle gdk_display_open(String displayName);
	native static final protected String gdk_display_get_name(Handle display);
	native static final protected int gdk_display_get_n_screens(Handle display);
	native static final protected Handle gdk_display_get_screen(Handle display, int screenNum);
	native static final protected Handle gdk_display_get_default_screen(Handle display);
	native static final protected void gdk_display_pointer_ungrab(Handle display, int time);
	native static final protected void gdk_display_keyboard_ungrab(Handle display, int time);
	native static final protected boolean gdk_display_pointer_is_grabbed(Handle display);
	native static final protected void gdk_display_beep(Handle display);
	native static final protected void gdk_display_sync(Handle display);
	native static final protected void gdk_display_flush(Handle display);
	native static final protected void gdk_display_close(Handle display);
	native static final protected Handle[] gdk_display_list_devices(Handle display);
	native static final protected Handle gdk_display_get_event(Handle display);
	native static final protected Handle gdk_display_peek_event(Handle display);
	native static final protected void gdk_display_put_event(Handle display, Handle event);
	native static final protected Handle gdk_display_get_default();
	native static final protected Handle gdk_display_get_core_pointer(Handle display);
	native static final protected void gdk_display_get_pointer(Handle display, Handle screen, int[] x, int[] y, int[] modType);
	native static final protected Handle gdk_display_get_window_at_pointer(Handle display, int x, int y);
	native static final protected boolean gdk_display_supports_cursor_alpha(Handle display);
	native static final protected boolean gdk_display_supports_cursor_color(Handle display);
	native static final protected int gdk_display_get_default_cursor_size(Handle display);
	native static final protected void gdk_display_get_maximum_cursor_size(Handle display, int[] width, int[] height);
	native static final protected boolean gdk_display_supports_selection_notification(Handle display); 
	native static final protected boolean gdk_display_request_selection_notification(Handle display, Handle selection);
	native static final protected boolean gdk_display_supports_clipboard_persistence(Handle display);
	native static final protected void gdk_display_store_clipboard(Handle display, Handle clipboardWindow, int time, Handle[] targets);
	native static final protected Handle gdk_display_get_default_group(Handle display);
}
