/*
 * 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.gtk;

import java.util.Vector;

import org.gnu.glib.EventMap;
import org.gnu.glib.EventType;
import org.gnu.glib.GObject;
import org.gnu.glib.Handle;
import org.gnu.gtk.event.IconViewEvent;
import org.gnu.gtk.event.IconViewListener;

/**
 */
public class IconView extends Container {

    /**
     * Create a new IconView
     */
    public IconView() {
        super(gtk_icon_view_new());
    }
    
    /**
     * Create a new IconView specifying the model.
     * @param model
     */
    public IconView(TreeModel model) {
        super(gtk_icon_view_new_with_model(model.getHandle()));
    }
    
    /**
     * Sets the model for this IconView.  If the IconView already has a
     * model it will remove it before setting the new model.  If model
     * is null it will unset the old model.
     * @param model
     */
    public void setModel(TreeModel model) {
        gtk_icon_view_set_model(getHandle(), model.getHandle());
    }
    
    /**
     * Returns the model that the IconView is using.  It will return
     * null if a model is the IconView currently does not have a model. 
     */
    public TreeModel getModel() {
        Handle hndl = gtk_icon_view_get_model(getHandle());
        if (null == hndl)
            return null;
        return new TreeModel(hndl);
    }
    
    /**
     * Sets the column with text for this IconView to be the specified column.
     * The text column must be of type DataColumnString.
     * @param column
     */
    public void setTextColumn(int column) {
        gtk_icon_view_set_text_column(getHandle(), column);
    }
    
    /**
     * Returns the column with text fro this IconView.
     */
    public int getTextColumn() {
        return gtk_icon_view_get_text_column(getHandle());
    }
    
    /**
     * Sets the column with markup information for this IconView to be
     * the specified column.  The markup column must be of type DataColumnString.
     * If the markup column is set to something it overrides the text column
     * set by <code>setTextColumn</code> 
     * @param column
     */
    public void setMarkupColumn(int column) {
        gtk_icon_view_set_markup_column(getHandle(), column);
    }
    
    /**
     * Returns the column with markup text for this IconView.
     */
    public int getMarkupColumn() {
        return gtk_icon_view_get_markup_column(getHandle());
    }
    
    /**
     * Sets the column with Pixbufs for this IconView to be the
     * specified column.  This pixubf column must be of type
     * DataColumnPixbuf.
     * @param column
     */
    public void setPixbufColumn(int column) {
        gtk_icon_view_set_pixbuf_column(getHandle(), column);
    }
    
    /**
     * Returns the column with Pixbufs for this IconView.
     */
    public int getPixbufColumn() {
        return gtk_icon_view_get_pixbuf_column(getHandle());
    }
    
    /**
     * Sets the orientation of this IconView which determines whether
     * the labels are drawn beside instead of below the icons.
     * @param orientation
     */
    public void setOrientation(Orientation orientation) {
        gtk_icon_view_set_orientation(getHandle(), orientation.getValue());
    }
    
    /**
     * Returns the Orientation for this IconView.
     */
    public Orientation getOrientation() {
        return Orientation.intern(gtk_icon_view_get_orientation(getHandle()));
    }
    
    /**
     * Set the number of columns for this IconView.
     * @param columns
     */
    public void setColumns(int columns) {
        gtk_icon_view_set_columns(getHandle(), columns);
    }
    
    /**
     * Returns the number of columns for this IconView.
     */
    public int getColumns() {
        return gtk_icon_view_get_columns(getHandle());
    }

    /**
     * Sets the width of each item.
     * @param width
     */
    public void setItemWidth(int width) {
        gtk_icon_view_set_item_width(getHandle(), width);
    }
    
    /**
     * Returns the width of each item.
     */
    public int getItemWidth() {
        return gtk_icon_view_get_item_width(getHandle());
    }
    
    /**
     * @param spacing
     */
    public void setSpacing(int spacing) {
        gtk_icon_view_set_spacing(getHandle(), spacing);
    }
    
    /**
     */
    public int getSpacing() {
        return gtk_icon_view_get_spacing(getHandle());
    }
    
    /**
     * 
     * @param rowSpacing
     */
    public void setRowSpacing(int rowSpacing) {
        gtk_icon_view_set_row_spacing(getHandle(), rowSpacing);
    }
    
    /**
     */
    public int getRowSpacing() {
        return gtk_icon_view_get_row_spacing(getHandle());
    }
    
    /**
     * 
     * @param columnSpacing
     */
    public void setColumnSpacing(int columnSpacing) {
        gtk_icon_view_set_column_spacing(getHandle(), columnSpacing);
    }
    
    /**
     * 
     */
    public int getColumnSpacing() {
        return gtk_icon_view_get_column_spacing(getHandle());
    }
    
    /**
     * 
     * @param margin
     */
    public void setMargin(int margin) {
        gtk_icon_view_set_margin(getHandle(), margin);
    }
    
    /**
     * 
     */
    public int getMargin() {
        return gtk_icon_view_get_margin(getHandle());
    }
    
    /**
     * Find the path at the point (x,y) relative to widget coordinates.
     * @param x
     * @param y
     */
    public TreePath getPathAtPosition(int x, int y) {
        Handle hndl = gtk_icon_view_get_path_at_pos(getHandle(), x, y);
        if (null == hndl)
            return null;
        return new TreePath(hndl);
    }
    
    /**
     * Sets the selection mode for this IconView.
     * @param mode
     */
    public void setSelectionMode(SelectionMode mode) {
        gtk_icon_view_set_selection_mode(getHandle(), mode.getValue());
    }
    
    /**
     * Returns the selection mode for this IconView.
     */
    public SelectionMode getSelectionMode() {
        return SelectionMode.intern(gtk_icon_view_get_selection_mode(getHandle()));
    }
    
    /**
     * Selects the row at the specified path.
     * @param path
     */
    public void selectPath(TreePath path) {
        gtk_icon_view_select_path(getHandle(), path.getHandle());
    }
    
    /**
     * Unselects the row at the specified path.
     * @param path
     */
    public void unselectPath(TreePath path) {
    
        gtk_icon_view_unselect_path(getHandle(), path.getHandle());
    }
    
    /**
     * returns true if the path is currently selected.
     * @param path
     */
    public boolean pathIsSelected(TreePath path) {
        return gtk_icon_view_path_is_selected(getHandle(), path.getHandle());
    }
    
    /**
     * Returns an array of all selected paths.
     */
    public TreePath[] getSelectedItems() {
        Handle[] hndls = gtk_icon_view_get_selected_items(getHandle());
        if (null == hndls)
            return null;
        TreePath[] paths = new TreePath[hndls.length];
        for (int i = 0; i < hndls.length; i++)
            paths[i] = new TreePath(hndls[i]);
        return paths;
    }
    
    /**
     * Selects all of the icons.  The IconView must have its' selection
     * mode set to SelectionMode.MILTIPLE.
     */
    public void selectAll() {
        gtk_icon_view_select_all(getHandle());
    }
    
    /**
     * Unselects all of the icons.
     */
    public void unselectAll() {
        gtk_icon_view_unselect_all(getHandle());
    }
    
    /**
     * Activate the item specified by path.
     * @param path
     */
    public void itemActivated(TreePath path) {
        gtk_icon_view_item_activated(getHandle(), path.getHandle());
    }
    
	/* **************************************
	 * EVENT LISTENERS
	 ****************************************/

	/**
	 * Listeners for handling IconView events
	 */
	private Vector ivListeners = null;

	/**
	 * Register an object to handle IconView events.
	 * @see IconViewListener
	 */
	public void addListener(IconViewListener listener) {
		// Don't add the listener a second time if it is in the Vector.
		int i = findListener(ivListeners, listener);
		if (i == -1) {
			if (null == ivListeners) {
				evtMap.initialize(this, IconViewEvent.Type.SET_SCROLL_ADJUSTMENTS);
				evtMap.initialize(this, IconViewEvent.Type.ITEM_ACTIVATED);
				evtMap.initialize(this, IconViewEvent.Type.SELECTION_CHANGED);
				ivListeners = new Vector();
			}
			ivListeners.addElement(listener);
		}
	}
	
	/**
	 * Removes a listener.
	 * @see #addListener(IconViewListener)
	 */
	public void removeListener(IconViewListener listener) {
		int i = findListener(ivListeners, listener);
		if (i > -1) {
		    ivListeners.remove(i);
		}
		if (0 == ivListeners.size()) {
			evtMap.uninitialize(this, IconViewEvent.Type.SET_SCROLL_ADJUSTMENTS);
			evtMap.uninitialize(this, IconViewEvent.Type.ITEM_ACTIVATED);
			evtMap.uninitialize(this, IconViewEvent.Type.SELECTION_CHANGED);
			ivListeners = null;
		}
	}

	protected void fireIconViewEvent(IconViewEvent event) {
		if (null == ivListeners) {
			return;
		}
		int size = ivListeners.size();
		int i = 0;
		while (i < size) {
		    IconViewListener ivl = (IconViewListener)ivListeners.elementAt(i);
		    ivl.iconViewEvent(event);
			i++;
		}
	}

	private void handleSetScrollAdjustment(Handle hAdj, Handle vAdj) {
	    IconViewEvent evt = new IconViewEvent(this, IconViewEvent.Type.SET_SCROLL_ADJUSTMENTS);
		Adjustment h;
		Adjustment v;
		GObject obj = getGObjectFromHandle(hAdj);
		if (null != obj)
			h = (Adjustment)obj;
		else
			h = new Adjustment(hAdj);
		obj = getGObjectFromHandle(vAdj);
		if (null != obj)
			v = (Adjustment)obj;
		else
			v = new Adjustment(vAdj);
		evt.setHorizontalAdjustment(h);
		evt.setVerticalAdjustment(v);
		fireIconViewEvent(evt);
	}

	private void handleItemActivated(Handle path) {
	    IconViewEvent evt = new IconViewEvent(this, IconViewEvent.Type.ITEM_ACTIVATED);
	    TreePath p = new TreePath(path);
	    evt.setPath(p);
		fireIconViewEvent(evt);
	}
	
	private void handleSelectionChanged() {
	    IconViewEvent evt = new IconViewEvent(this, IconViewEvent.Type.SELECTION_CHANGED);
	    fireIconViewEvent(evt);
	}

	public Class getEventListenerClass(String signal) {
		Class cls = evtMap.getEventListenerClass(signal);
		if (cls == null) cls = super.getEventListenerClass(signal);
		return cls;
	}

	public EventType getEventType(String signal) {
		EventType et = evtMap.getEventType(signal);
		if (et == null) et = super.getEventType(signal);
		return et;
	}

	private static EventMap evtMap = new EventMap();
	static {
		addEvents(evtMap);
	}

	/**
	 * Implementation method to build an EventMap for this widget class.
	 * Not useful (or supported) for application use.
	 */
	private static void addEvents(EventMap anEvtMap) {
		anEvtMap.addEvent("set_scroll_adjustments", "handleSetScrollAdjustment", IconViewEvent.Type.SET_SCROLL_ADJUSTMENTS, IconViewListener.class);
		anEvtMap.addEvent("item_activated", "handleItemActivated", IconViewEvent.Type.ITEM_ACTIVATED, IconViewListener.class);
		anEvtMap.addEvent("selection_changed", "handleSelectionChanged", IconViewEvent.Type.SELECTION_CHANGED, IconViewListener.class);
	}

	
    native static final protected int gtk_icon_view_get_type ();
    native static final protected Handle gtk_icon_view_new();
    native static final protected Handle gtk_icon_view_new_with_model(Handle model);
    native static final protected void gtk_icon_view_set_model(Handle view, Handle model);
    native static final protected Handle gtk_icon_view_get_model(Handle view);
    native static final protected void gtk_icon_view_set_text_column(Handle view, int column);
    native static final protected int gtk_icon_view_get_text_column(Handle view);
    native static final protected void gtk_icon_view_set_markup_column(Handle view, int column);
    native static final protected int gtk_icon_view_get_markup_column(Handle view);
    native static final protected void gtk_icon_view_set_pixbuf_column(Handle view, int column);
    native static final protected int gtk_icon_view_get_pixbuf_column(Handle view);
    native static final protected void gtk_icon_view_set_orientation(Handle view, int orientation);
    native static final protected int gtk_icon_view_get_orientation(Handle view);
    native static final protected void gtk_icon_view_set_columns(Handle view, int columns);
    native static final protected int gtk_icon_view_get_columns(Handle view);
    native static final protected void gtk_icon_view_set_item_width(Handle view, int width);
    native static final protected int gtk_icon_view_get_item_width(Handle view);
    native static final protected void gtk_icon_view_set_spacing(Handle view, int spacing);
    native static final protected int gtk_icon_view_get_spacing(Handle view);
    native static final protected void gtk_icon_view_set_row_spacing(Handle view, int spacing);
    native static final protected int gtk_icon_view_get_row_spacing(Handle view);
    native static final protected void gtk_icon_view_set_column_spacing(Handle view, int spacing);
    native static final protected int gtk_icon_view_get_column_spacing(Handle view);
    native static final protected void gtk_icon_view_set_margin(Handle view, int margin);
    native static final protected int gtk_icon_view_get_margin(Handle view);
    native static final protected Handle gtk_icon_view_get_path_at_pos(Handle view, int x, int y);
    native static final protected void gtk_icon_view_set_selection_mode(Handle view, int mode);
    native static final protected int gtk_icon_view_get_selection_mode(Handle view);
    native static final protected void gtk_icon_view_select_path(Handle view, Handle path);
    native static final protected void gtk_icon_view_unselect_path(Handle view, Handle path);
    native static final protected boolean gtk_icon_view_path_is_selected(Handle view, Handle path);
    native static final protected Handle[] gtk_icon_view_get_selected_items(Handle view);
    native static final protected void gtk_icon_view_select_all(Handle view);
    native static final protected void gtk_icon_view_unselect_all(Handle view);
    native static final protected void gtk_icon_view_item_activated(Handle view, Handle path);

}
