/*******************************************************************************
 * 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 org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;

public class Table extends Composite {
	TableItem [] items;
	TableColumn [] columns;
	int itemCount, columnCount;
	TableItem currentItem;
	TableColumn sortColumn;
	Object jsItems, jsColumns, model;
	int lastIndexOf = -1;
	
public Table (Composite parent, int style) {
	super (parent, checkStyle (style));
//TODO initialization here???	
	itemCount = columnCount = 0;
	items = new TableItem [4];
	columns = new TableColumn [4];
}

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);
}

static int checkStyle (int style) {
	/*
	* To be compatible with Windows, force the H_SCROLL
	* and V_SCROLL style bits.  On Windows, it is not
	* possible to create a table without scroll bars.
	*/
	style |= SWT.H_SCROLL | SWT.V_SCROLL;
	return checkBits (style, SWT.SINGLE, SWT.MULTI, 0, 0, 0, 0);
}

protected void checkSubclass () {
}

public void clear (int index) {
}

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

public void clear (int[] indices) {
}

public void clearAll () {
}

public void createItem (TableColumn column, int index){
	if (!(0 <= index && index <= columnCount)) error (SWT.ERROR_INVALID_RANGE);
	
	if (columnCount == columns.length) {
		TableColumn [] newColumns = new TableColumn [columns.length + 4];
		System.arraycopy (columns, 0, newColumns, 0, columns.length);
		columns = newColumns;
	}
	column._createItem(this, style, index);
	
	System.arraycopy (columns, index, columns, index + 1, columnCount++ - index);
	columns [index] = column;
	
}

public void createItem (TableItem item, int index){
	if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE);
	if (itemCount == items.length) {
		int length = drawCount == 0 ? items.length + 4 : Math.max (4, items.length * 3 / 2);
		TableItem [] newItems = new TableItem [length];	
		System.arraycopy (items, 0, newItems, 0, items.length);
		items = newItems;
	}
	item._createItem(this, style, index);
	
	System.arraycopy (items, index, items, index + 1, itemCount++ - index);
	items [index] = item;
}

//FIXME fix scrollbars / separeted widgets or not???
// temp return null to not screwed up the layout
ScrollBar createScrollBar (int type) {
	return null;
}

public void deselect (int[] indices) {
}

public void deselect (int index) {
}

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

public void deselectAll () {
}

public TableColumn getColumn (int index) {
	return null;
}

public int getColumnCount () {
	checkWidget ();
	return columnCount;
}

public int[] getColumnOrder () {
	return null;
}

public TableColumn[] getColumns () {
	checkWidget ();
	TableColumn [] result = new TableColumn [columnCount];
	System.arraycopy (columns, 0, result, 0, columnCount);
	return result;
}

public int getGridLineWidth () {
	return 0;
}

public int getHeaderHeight () {
	return 0;
}

public boolean getHeaderVisible () {
	return false;
}

public TableItem getItem (int index) {
	checkWidget();
	if (!(0 <= index && index < itemCount)) error (SWT.ERROR_INVALID_RANGE);
	return items[index];
}

public TableItem getItem (Point point) {
	return null;
}

public int getItemCount () {
	checkWidget ();
	return itemCount;
}

public int getItemHeight () {
	return 0;
}

public TableItem[] getItems () {
	checkWidget ();
	int count = getItemCount();
	TableItem [] result = new TableItem [count];
//	if ((style & SWT.VIRTUAL) != 0) {
//		for (int i=0; i<count; i++) {
//			result [i] = _getItem (i);
//		}
//	} else {
		System.arraycopy (items, 0, result, 0, count);
//	}
	return result;
}

public boolean getLinesVisible () {
	return false;
}

public TableItem[] getSelection () {
	return null;
}

public int getSelectionCount () {
	return 0;
}

public int getSelectionIndex () {
	return 0;
}

public int[] getSelectionIndices () {
	return null;
}

public TableColumn getSortColumn () {
	return null;
}

public int getSortDirection () {
	return 0;
}

public int getTopIndex () {
	return 0;
}

void hookEvents() {
	super.hookEvents();
	_hookEvents();
}

public int indexOf (TableColumn column) {
	checkWidget ();
	if (column == null) error (SWT.ERROR_NULL_ARGUMENT);
	for (int i=0; i<columnCount; i++) {
		if (columns [i] == column) return i;
	}
	return -1;
}

public int indexOf (TableItem item) {
	checkWidget ();
	if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
	if (1 <= lastIndexOf && lastIndexOf < itemCount - 1) {
		if (items [lastIndexOf] == item) return lastIndexOf;
		if (items [lastIndexOf + 1] == item) return ++lastIndexOf;
		if (items [lastIndexOf - 1] == item) return --lastIndexOf;
	}
	if (lastIndexOf < itemCount / 2) {
		for (int i=0; i<itemCount; i++) {
			if (items [i] == item) return lastIndexOf = i;
		}
	} else {
		for (int i=itemCount - 1; i>=0; --i) {
			if (items [i] == item) return lastIndexOf = i;
		}
	}
	return -1;
}

public boolean isSelected (int index) {
	return false;
}

public void remove (int[] indices) {
	checkWidget();
	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];
	if (!(0 <= start && start <= end && end < itemCount)) {
		error (SWT.ERROR_INVALID_RANGE);
	}
}

public void remove (int index) {
	checkWidget();
	if (!(0 <= index && index < itemCount)) error (SWT.ERROR_ITEM_NOT_REMOVED);
}

public void remove (int start, int end) {
	checkWidget();
	if (start > end) return;
	if (!(0 <= start && start <= end && end < itemCount)) {
		error (SWT.ERROR_INVALID_RANGE);
	}
}

public void removeAll () {
	checkWidget();
	int index = itemCount - 1;
	while (index >= 0) {
		TableItem item = items [index];
		if (item != null && !item.isDisposed ()) item.release (false);
		--index;
	}
	items = new TableItem [4];
	itemCount = 0;
	_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 setColumnOrder (int[] order) {
}

public void setFont (Font font) {
}

public void setHeaderVisible (boolean show) {
	_setHeaderVisible (show);
}

public void setItemCount (int count) {
}

public void setLinesVisible (boolean show) {
}

public void setRedraw (boolean redraw) {
}

public void setSelection (int[] indices) {
}

public void setSelection (TableItem item) {
}

public void setSelection (TableItem[] items) {
}

public void setSelection (int index) {
}

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

public void setSortColumn (TableColumn column) {
}

public void setSortDirection (int direction) {
}

public void setTopIndex (int index) {
}

public void showColumn (TableColumn column) {
}

public void showItem (TableItem item) {
}

public void showSelection () {
}

/*---------------- NATIVE INTERFACE ----------------*/

protected native void _createHandle (Widget parent, int style, int index) /*-{
	if(!$wnd.dojo._hasResource["org.eclipse.swt.Table"]){
		$wnd.dojo._hasResource["org.eclipse.swt.Table"] = true;
		$wnd.dojo.provide("org.eclipse.swt.Table");
		
		$wnd.dojo.require("dojox.grid.Grid");
        $wnd.dojo.require("dojox.grid._data.model");
		
		$wnd.dojo.declare(
			"org.eclipse.swt.Table", $wnd.dojox.Grid,{
				border: "",
				autoHeight: false,
				headerVisible: false,
				isSortable : false,
				adaptHeight: function(){
					$wnd.swt.setCssStyle(this.viewsHeaderNode, {display: this.headerVisible ? "block" : "none"});
					this.inherited("adaptHeight",arguments);
				},
				canSort: function(){
					return this.isSortable && this.inherited("canSort",arguments);
				},
				postCreate: function(){
					this.inherited("postCreate",arguments);
					this.setStructure([{cells: [[]]}]);
					$wnd.swt.setCssStyle(this.domNode, {border: this.border});
				},
				setHeaderVisible: function(show){
					this.headerVisible = show;
					this.adaptHeight();
				},
				setWidgetBounds: function(dim){
					this._sizeBox = $wnd.swt.setBounds(this.domNode, dim);
					this.update();
				}
			}
		);
	}
	
	var jsParent = parent.@org.eclipse.swt.widgets.Widget::jsObject;
	var params = {};
	if((style & (@org.eclipse.swt.SWT::BORDER)) != 0){
		params.border = "1px solid black";
	}
	if((style & (@org.eclipse.swt.SWT::BORDER)) != 0){
		params.border = "1px solid black";
	}
	var self = new $wnd.org.eclipse.swt.Table(params);
	this.@org.eclipse.swt.widgets.Table::jsItems = [];
	this.@org.eclipse.swt.widgets.Table::jsColumns = [];
	var columnView = {cells: [this.@org.eclipse.swt.widgets.Table::jsColumns]};
	self.setStructure([columnView]);
	
	try {
		this.@org.eclipse.swt.widgets.Widget::jsObject = self;
		jsParent.addChild(self);
	} catch (e) {
//TODO Have to throw real exception for Java side also	
		$wnd.console.log(e);
	}
	this.@org.eclipse.swt.widgets.Table::updateModel()();
	
}-*/;

native void _setHeaderVisible (boolean show) /*-{
	this.@org.eclipse.swt.widgets.Widget::jsObject.setHeaderVisible(show);	
}-*/;

native void updateStructure()/*-{
	var columnView = {cells: [this.@org.eclipse.swt.widgets.Table::jsColumns]};
	this.@org.eclipse.swt.widgets.Widget::jsObject.setStructure([columnView]);
}-*/;

native void updateModel()/*-{
	var model = new $wnd.dojox.grid.data.Table(null, this.@org.eclipse.swt.widgets.Table::jsItems);
	this.@org.eclipse.swt.widgets.Widget::jsObject.setModel(model);	
	this.@org.eclipse.swt.widgets.Table::model = model;
}-*/;

native void _removeAll()/*-{
	this.@org.eclipse.swt.widgets.Table::jsItems = [];
	var model = new $wnd.dojox.grid.data.Table(null, this.@org.eclipse.swt.widgets.Table::jsItems);
	this.@org.eclipse.swt.widgets.Widget::jsObject.setModel(model);
	this.@org.eclipse.swt.widgets.Table::model = model;
}-*/;

native void _hookEvents()/*-{
//	var self = this;
//	$wnd.dojo.connect(
//		self.@org.eclipse.swt.widgets.Widget::jsObject,
//		"onSelect",
//		function(arg){
//			if (arg) {
//				var event = self.@org.eclipse.swt.widgets.Widget::getEvent()();
//				event.@org.eclipse.swt.widgets.Event::type = 13;
//				event.@org.eclipse.swt.widgets.Event::x = arg.pageX;
//				event.@org.eclipse.swt.widgets.Event::y = arg.pageY;
//				self.@org.eclipse.swt.widgets.Widget::sendEvent(ILorg/eclipse/swt/widgets/Event;)(style, event);
//			}
//		}
//	);
}-*/;

}
