/*
 * 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.gnome;

import java.util.Vector;

import org.gnu.glib.Type;
import org.gnu.gnome.event.ClientEvent;
import org.gnu.gnome.event.ClientListener;
import org.gnu.gtk.GtkObject;
/**
 * The GnomeClient object makes it possible for your application to
 * save session information when the user logs out. If, when logging
 * out, the user chooses to save the current settings, a save_yourself
 * signal is sent to each application. Then an application can save
 * information in such a way that it is supported on the command line
 * whenever the program automatically restarts a user login.
 */
public class Client extends GtkObject {
	/**
	 * Listeners for handling Client events
	 */
	private Vector clientListeners = null;

	/**
	 * Create a new session management client and try to connect to
	 * a session manager.
	 */
	public Client() {
		super(gnome_client_new());
		initializeEventHandlers();
	}
	
	/**
	 * Initialize a client from a handle to a native resource.
	 */
	protected Client(int handle) {
		super(handle);
		initializeEventHandlers();
	}

	/**
	 * Get the config prefix for a client.  The config prefix provides
	 * a suitable place to store any details about the state of the
	 * client which can not be described using the app's command line
	 * arguments (as set in the restart command).
	 */
	public String getConfigPrefix() {
		return new String(gnome_client_get_config_prefix(getHandle()));
	}
	
	/**
	 * Get the config prefix for clients which have NOT been restarted or
	 * cloned.  This config prefix may be used to write the user's preferred
	 * config for these "new" clients.
	 * <p>
	 * You may also use this prefix as a place to store and retrieve config
	 * details that you wish to apply to ALL instances of the app.  However,
	 * this practice limits user's freedom to configure each instance in
	 * a different way so it should be used with caution.
	 */
	public String getGlobalConfigPrefix() {
		return new String(gnome_client_get_global_config_prefix(getHandle()));
	}
	
	/**
	 * Set the value used for the global config prefix.  The config prefixes
	 * returned by getGlobalConfigPrefix() are formed by extending this prefix
	 * with a unique identifier.
	 * <p>
	 * The global config prefix defaults to a name based on the name of the
	 * executable.  This function allows you to set it to a different value.
	 * It should be called BEFORE retrieving the config prefix for the
	 * first time.
	 */
	public void setGlobalConfigPrefix(String prefix) {
		gnome_client_set_global_config_prefix(getHandle(), prefix);
	}
	
	/**
	 * Returns some flags, that give additional information about this 
	 * client.
	 */
	public ClientFlags getFlags() {
		return ClientFlags.intern(gnome_client_get_flags(getHandle()));
	}
	
	/**
	 * The session manager usually only restarts clients which are running
	 * when the session was last saved.  You can set the restart style
	 * to make the manager restart the client:
	 * - at the start of every session (RESTART_AWAY)
	 * - whenever the client dies (RESTART_IMMEDIATELY)
	 * - never (RESTART_NEVER)
	 */
	public void setRestartStyle(RestartStyle style) {
		gnome_client_set_restart_style(getHandle(), style.getValue());
	}
	
	/**
	 * The gnome-session manager includes an extension to the protocol
	 * which allows the order in which clients are started up to be
	 * organized into a number of run levels.  This method may be
	 * used to inform the gnome-session manager of where this client
	 * should appear in this run level ordering.  The priority runs
	 * from 0 (started first) to 99 (started last) and defaults to
	 * 50.
	 */
	public void setPriority(int priority) {
		gnome_client_set_priority(getHandle(), priority);
	}
	
	/**
	 * Sets the directory where all commands are executed.
	 */
	public void setCurrentDirectory(String dir) {
		gnome_client_set_current_directory(getHandle(), dir);
	}
	
	/**
	 * Provide the command that should be used to restart this
	 * application.
	 */
	public void setRestartCommand(String [] args) {
		gnome_client_set_restart_command(getHandle(), args.length, args);
	}
	
	/**
	 * Request the session manager to save the session in some way.
	 */
	public void requestSave(SaveStyle saveStyle, boolean shutdown, InteractStyle interactStyle, boolean fast, boolean global) {
		gnome_client_request_save(getHandle(), saveStyle.getValue(), shutdown, interactStyle.getValue(), fast, global);
	}
	
	/**
	 * Flush the underlying connection to the connection manager.  This
	 * is useful if you have some pending changes that you want to
	 * make sure get committed.
	 */
	public void flush() {
		gnome_client_flush(getHandle());
	}
	
	/**
	 * Try to connect to a session manager.  This should only be called
	 * after a disconnect().
	 */
	public void connect() {
		gnome_client_connect(getHandle());
	}
	
	/**
	 * Disconnect from the session manager.
	 */
	public void disconnect() {
		gnome_client_disconnect(getHandle());
	}

	/**
	 * Retrieve the runtime type used by the GLib library.
	 */
	public static Type getType() {
		return new Type(gnome_client_get_type());
	}

	//////////////////////////////////////////////////
	// Event handling
	/////////////////////////////////////////////////
	/**
	 * Register an object to handle Client events.
	 * @see org.gnu.gnome.event.ClientListener
	 */
	public void addListener(ClientListener listener) {
		// Don't add the listener a second time if it is in the Vector.
		int i = findListener(clientListeners, listener);
		if (i == -1) {
			if (null == clientListeners) {
				clientListeners = new Vector();
			}
			clientListeners.addElement(listener);
		}
	}
	/**
	 * Removes a listener
	 * @see #addListener(ClientListener)
	 */
	public void removeListener(ClientListener listener) {
		int i = findListener(clientListeners, listener);
		if (i > -1) {
			clientListeners.remove(i);
		}
		if (0 == clientListeners.size()) {
			clientListeners = null;
		}
	}

	/**
	 * Give us a way to locate a specific listener in a Vector.
	* @param list The Vector of listeners to search.
	* @param listener The object that is to be located in the Vector.
	* @return Returns the index of the listener in the Vector, or -1 if
	*                 the listener is not contained in the Vector.
	 */
	protected static int findListener(Vector list, Object listener) {
		if (null == list || null == listener)
			return -1;
		return list.indexOf(listener);
	}

	protected void fireClientEvent(ClientEvent event) {
		if (null == clientListeners) {
			return;
		}
		int size = clientListeners.size();
		int i = 0;
		while (i < size) {
			ClientListener cl = (ClientListener)clientListeners.elementAt(i);
			cl.clientEvent(event);
			i++;
		}
	}

	private void handleConnect(boolean restarted) {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.CONNECT));
	}

	private void handleDie() {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.DIE));
	}

	private void handleDisconnect() {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.DISCONNECT));
	}

	private void handleSaveComplete() {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.SAVE_COMPLETE));
	}

	private void handleSaveYourself(int phase, int saveStyle, boolean shutdown, int interactStyle, boolean fase) {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.SAVE_YOURSELF));
	}

	private void handleShutdownCancelled() {
		fireClientEvent(new ClientEvent(this, ClientEvent.Type.SHUTDOWN_CANCELLED));
	}

	protected void initializeEventHandlers() {
		addEventHandler("connect", "handleConnect", this);
		addEventHandler("die", "handleDie", this);
		addEventHandler("disconnect", "handleDisconnect", this);
		addEventHandler("save_complete", "handleSaveComplete", this);
		addEventHandler("save_yourself", "handleSaveYourself", this);
		addEventHandler("shutdown_cancelled", "handleShutdownCancelled", this);
	}
	/****************************************
	 * BEGINNING OF GENERATED CODE
	 ****************************************/
	native static final protected int gnome_client_get_type();
	native static final protected String gnome_client_get_config_prefix(int client);
	native static final protected String gnome_client_get_global_config_prefix(int client);
	native static final protected void gnome_client_set_global_config_prefix(int client, String prefix);
	native static final protected int gnome_client_get_flags(int client);
	native static final protected void gnome_client_set_restart_style(int client, int style);
	native static final protected void gnome_client_set_priority(int client, int priority);
	native static final protected void gnome_client_set_restart_command(int client, int argc, String[] args);
	native static final protected void gnome_client_set_discard_command(int client, int argc, String[] args);
	native static final protected void gnome_client_set_resign_command(int client, int argc, String[] args);
	native static final protected void gnome_client_set_shutdown_command(int client, int argc, String[] args);
	native static final protected void gnome_client_set_current_directory(int client, String dir);
	native static final protected void gnome_client_set_environment(int client, String name, String value);
	native static final protected void gnome_client_set_clone_command(int client, int argc, String[] args);
	native static final protected void gnome_client_set_process_id(int client, int id);
	native static final protected void gnome_client_set_program(int client, String program);
	native static final protected void gnome_client_set_user_id(int client, String id);
	native static final protected void gnome_client_save_any_dialog(int client, int dialog);
	native static final protected void gnome_client_save_error_dialog(int client, int dialog);
	native static final protected void gnome_client_request_phase_2(int client);
	native static final protected void gnome_client_request_save(int client, int save_style, boolean shutdown, int interact_style, boolean fast, boolean global);
	native static final protected void gnome_client_flush(int client);
	native static final protected int gnome_client_new();
	native static final protected void gnome_client_connect(int client);
	native static final protected void gnome_client_disconnect(int client);
	native static final protected void gnome_client_set_id(int client, String id);
	native static final protected String gnome_client_get_id(int client);
	native static final protected String gnome_client_get_previous_id(int client);
	native static final protected String gnome_client_get_desktop_id(int client);
	/****************************************
	 * END OF GENERATED CODE
	 ****************************************/
}
