/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.widgets;

import intrinsic.Array;
import intrinsic.Function;
import intrinsic.mx.collections.ArrayCollection;
import intrinsic.mx.controls.listClasses.*;
import intrinsic.mx.core.EdgeMetrics;
import intrinsic.mx.core.ScrollControlBase;
import intrinsic.mx.events.ListEvent;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Rectangle;

public class List extends Scrollable {
	ArrayCollection dataProvider;

public List (Composite parent, int style) {
	super (parent, checkStyle (style));
}

public void add (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	dataProvider.addItem (string);
}

public void add (String string, int index) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	dataProvider.addItemAt (string, index);
}

public void addSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	TypedListener typedListener = new TypedListener (listener);
	addListener (SWT.Selection,typedListener);
	addListener (SWT.DefaultSelection,typedListener);
}

void changeHandler(ListEvent event) {
	postEvent (SWT.Selection);
}

native Function changeHandlerFunction ()/*{
	return changeHandler__Lmx_events_ListEvent_2;
}*/;

void createHandle () {
	intrinsic.mx.controls.List widget = new intrinsic.mx.controls.List();
	if ((style & SWT.MULTI) != 0) widget.allowMultipleSelection = true;
	widget.dataProvider = dataProvider = new ArrayCollection();
	object = widget;
}

static int checkStyle (int style) {
	style |= SWT.H_SCROLL | SWT.V_SCROLL;
	return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
}

public Rectangle computeTrim (int x, int y, int width, int height) {
	checkWidget ();
	ScrollControlBase widget = (ScrollControlBase)object;
	EdgeMetrics view = widget.viewMetrics;
	x -= view.left;
	y -= view.top;
	width += (view.left + view.right);
	height += (view.top + view.bottom);
	return new Rectangle(x, y, width, height);
}

public void deselect (int[] indices) {
	checkWidget();
}

public void deselect (int index) {
}

public void deselect (int start, int end) {
}

public void deselectAll () {
	checkWidget();
	((ListBase)object).selectedIndices = new Array();
}

public int getFocusIndex () {
	return 0;
}

public String getItem (int index) {
	checkWidget ();
	int count = dataProvider.length;
	if (!(0 <= index && index < count)) error (SWT.ERROR_INVALID_RANGE);
	return (String)dataProvider.getItemAt (index);
}

public int getItemCount () {
	checkWidget ();
	return dataProvider.length;
}

public int getItemHeight () {
	return (int)((ListBase)object).rowHeight;
}

public String[] getItems () {
	checkWidget ();
	String[] result = new String[dataProvider.length];
	for (int i = 0; i < result.length; i++) {
		result[i] = (String)dataProvider.getItemAt (i);
	}
	return result;
}

public String[] getSelection () {
	checkWidget ();
	Array array = ((ListBase)object).selectedIndices;
	String[] result = new String[array.length];
	for (int i = 0; i < result.length; i++) {
		result[i] = (String)dataProvider.getItemAt(arrayGetInt(array, i));
	}
	return result;
}

public int getSelectionCount () {
	checkWidget ();
	return ((ListBase)object).selectedIndices.length;
}

public int getSelectionIndex () {
	checkWidget ();
	return ((ListBase)object).selectedIndex;
}

public int[] getSelectionIndices () {
	checkWidget ();
	Array array = ((ListBase)object).selectedIndices;
	int[] result = new int[array.length];
	for (int i = 0; i < result.length; i++) {
		result[i] = arrayGetInt(array, i);
	}
	return result;
}

public int getTopIndex () {
	return 0;
}

public int indexOf (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	return dataProvider.getItemIndex (string);
}

public int indexOf (String string, int start) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	return dataProvider.toArray().indexOf (string, start);
}

public boolean isSelected (int index) {
	checkWidget ();
	Array array = ((ListBase)object).selectedIndices;
	for (int i = 0; i < array.length; i++) {
		if (arrayGetInt(array, i) == index) {
			return true;
		}
	}
	return false;
}

void hookEvents (){
	super.hookEvents();
	object.addEventListener(ListEvent.CHANGE, changeHandlerFunction ());
}

void releaseWidget () {
	super.releaseWidget ();
	dataProvider = null;
}

public void remove (int[] indices) {
	if (indices == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (indices.length == 0) return;
	int [] newIndices = new int [indices.length];
	System.arraycopy (indices, 0, newIndices, 0, indices.length);
	sort (newIndices);
	int start = newIndices [newIndices.length - 1], end = newIndices [0];
	int count = getItemCount ();
	if (!(0 <= start && start <= end && end < count)) {
		error (SWT.ERROR_INVALID_RANGE);
	}
	dataProvider.disableAutoUpdate();
	int last = -1;
	for (int i=0; i<newIndices.length; i++) {
		int index = newIndices [i];
		if (index != last) {
			dataProvider.removeItemAt (index);
			last = index;
		}
	}
	dataProvider.enableAutoUpdate();
}

public void remove (int index) {
	checkWidget ();
	int count = dataProvider.length;
	if (!(0 <= index && index < count)) error (SWT.ERROR_INVALID_RANGE);
	dataProvider.removeItemAt (index);
}

public void remove (int start, int end) {
	int count = dataProvider.length;
	if (!(0 <= start && start <= end && end < count)) {
		error (SWT.ERROR_INVALID_RANGE);
	}
	dataProvider.disableAutoUpdate();
	for (int index=end; index>=start; index--) {
		dataProvider.removeItemAt (index);
	}
	dataProvider.enableAutoUpdate();
}

public void remove (String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	int index = dataProvider.getItemIndex (string);
	if (index == -1) error (SWT.ERROR_INVALID_ARGUMENT);
	dataProvider.removeItemAt(index);
}

public void removeAll () {
	checkWidget ();
	dataProvider.removeAll ();
}

public void removeSelectionListener (SelectionListener listener) {
	checkWidget ();
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (eventTable == null) return;
	eventTable.unhook (SWT.Selection, listener);
	eventTable.unhook (SWT.DefaultSelection,listener);	
}

public void select (int[] indices) {
}

public void select (int index) {
}

public void select (int start, int end) {
}

public void selectAll () {
}

public void setItem (int index, String string) {
	checkWidget ();
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
	int count = dataProvider.length;
	if (!(0 <= index && index < count)) error (SWT.ERROR_INVALID_RANGE);
	dataProvider.setItemAt(string, index);
}

public void setItems (String[] items) {
	checkWidget ();
	if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
	for (int i=0; i<items.length; i++) {
		if (items [i] == null) error (SWT.ERROR_INVALID_ARGUMENT);
	}
	dataProvider.disableAutoUpdate();
	dataProvider.removeAll ();
	for (int i = 0; i < items.length; i++) {
		dataProvider.addItem (items[i]);
	}
	dataProvider.enableAutoUpdate();
}

public void setSelection (int[] indices) {
}

public void setSelection (String[] items) {
}

public void setSelection (int index) {
}

public void setSelection (int start, int end) {
}

public void setTopIndex (int index) {
}

public void showSelection () {
}

}
