/*******************************************************************************
 * Copyright (c) 2005, 2012 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.ui.util;

import org.eclipse.bpel.ui.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.Accessible;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.TypedListener;


/** 
 * A modification of the SWT TableCursor class to better handle empty tables and dynamic tables 
 */
public class TableCursor extends Canvas {

	Table table;
	int row = -1, column = 0; // having row negative will end up hiding the cursor
	Listener tableListener, resizeListener;
	boolean progVisible = false;
	boolean userVisible = true;
	boolean hasFocus = false;
	AccessibleAdapter accessAdapter = null;
	Listener selectionAccessListener = null;
	Listener focusAccessListener = null;
	AccessibleControlAdapter accessControlAdapter = null;
	boolean hasAccessibility = false;

	public TableCursor(Table parent, int style) {
		super(parent, style);
		table = parent;
		Listener listener = new Listener() {
			public void handleEvent(Event event) {
				switch (event.type) {
					case SWT.Dispose :
						dispose(event);
						break;
					case SWT.KeyDown :
						keyDown(event);
						break;
					case SWT.Paint :
						paint(event);
						break;
					case SWT.Traverse :
						traverse(event);
						break;
				}
			}
		};
		addListener(SWT.Dispose, listener);
		addListener(SWT.KeyDown, listener);
		addListener(SWT.Paint, listener);
		addListener(SWT.Traverse, listener);

		tableListener = new Listener() {
			public void handleEvent(Event event) {
				switch (event.type) {
					case SWT.MouseDown :
						tableMouseDown(event);
						break;
					case SWT.FocusIn :
						tableFocusIn(event);
						break;
				}
			}
		};
		table.addListener(SWT.FocusIn, tableListener);
		table.addListener(SWT.MouseDown, tableListener);

		resizeListener = new Listener() {
			public void handleEvent(Event event) {
				resize();
			}
		};
		
		ScrollBar hBar = table.getHorizontalBar();
		if (hBar != null)
			hBar.addListener(SWT.Selection, resizeListener);
		
		ScrollBar vBar = table.getVerticalBar();
		if (vBar != null) 
			vBar.addListener(SWT.Selection, resizeListener);
		
		this.addFocusListener(new FocusListener() {
			public void focusGained(FocusEvent e) {
				hasFocus = true;
				redraw();
			}

			public void focusLost(FocusEvent e) {
				hasFocus = false;
				redraw();
				
			}});

		refresh();
		
		initAccessible();
	}
	
	/** 
	 * this is called whenever the content of the table has changed, it 
	 * will reconcile the cursor and any listeners that we need
	 */ 
	
	public void refresh() {
		// the number of rows and columns could have changed, ideally we should track
		// which columns have listeners but for the now, we'll just remove and readd
		int columns = table.getColumnCount();
		for (int i = 0; i < columns; i++) {
			TableColumn column = table.getColumn(i);
			column.removeListener(SWT.Resize, resizeListener);
		}
		for (int i = 0; i < columns; i++) {
			TableColumn column = table.getColumn(i);
			column.addListener(SWT.Resize, resizeListener);
		}
		
		// reset the row and column to be a valid one
		//boolean repaint = false;
		if (row >= table.getItemCount()) {
			row = table.getItemCount()-1;
		}
		if (column >= columns) {
			column = columns - 1;
		}
		
		// check to see what the selection is, and reset the tablecursor to 
		// a valid row/column in that selection
		
		TableItem[] selection = table.getSelection();
		if (selection.length == 0) {
			row = -1;
		}
		else {
//			// there is a selection, so make sure our table cursor is in that selection
//			// range
//			int min = 999999;
//			int max = -1;
//			for (int i = 0; i < selection.length; i++) {
//				int temp = table.indexOf(selection[i]);
//				min = Math.min(temp, min);
//				max = Math.max(temp, max);
//			}
//			if (row > max || row < min)
//				row = min;
		}
		setSelection(row, column);
	}

	public void addSelectionListener(SelectionListener listener) {
		checkWidget();
		if (listener == null)
			SWT.error(SWT.ERROR_NULL_ARGUMENT);
		TypedListener typedListener = new TypedListener(listener);
		addListener(SWT.Selection, typedListener);
		addListener(SWT.DefaultSelection, typedListener);
	}

	void dispose(Event event) {
		Display display = getDisplay();
		display.asyncExec(new Runnable() {
			public void run() {
				if (table.isDisposed())
					return;
				table.removeListener(SWT.FocusIn, tableListener);
				table.removeListener(SWT.MouseDown, tableListener);
				int columns = table.getColumnCount();
				for (int i = 0; i < columns; i++) {
					TableColumn column = table.getColumn(i);
					column.removeListener(SWT.Resize, resizeListener);
				}
				ScrollBar hBar = table.getHorizontalBar();
				if (hBar != null) {
					hBar.removeListener(SWT.Selection, resizeListener);
				}
				ScrollBar vBar = table.getVerticalBar();
				if (vBar != null) {
					vBar.removeListener(SWT.Selection, resizeListener);
				}
			}
		});
	}

	void keyDown(Event event) {
		switch (event.character) {
			case SWT.CR :
				notifyListeners(SWT.DefaultSelection, new Event());
				return;
		}
		switch (event.keyCode) {
			case SWT.ARROW_UP :
				if (column < 0)
					column = 0;
				setRowColumn(row - 1, column, true);
				break;
			case SWT.ARROW_DOWN :
			if (column < 0)
				column = 0;
				setRowColumn(row + 1, column, true);
				break;
			case SWT.ARROW_LEFT :
			case SWT.ARROW_RIGHT :
				{
					if (column < 0)
						column = 0;
					int leadKey = (getStyle() & SWT.RIGHT_TO_LEFT) != 0 ? SWT.ARROW_RIGHT : SWT.ARROW_LEFT;
					if (event.keyCode == leadKey) {
						setRowColumn(row, column - 1, true);
					} else {
						setRowColumn(row, column + 1, true);
					}
					break;
				}
			case SWT.HOME :
				if (column < 0)
					column = 0;
				setRowColumn(0, column, true);
				break;
			case SWT.END :
				{
					if (column < 0)
						column = 0;
					int row = table.getItemCount() - 1;
					setRowColumn(row, column, true);
					break;
				}
		}
	}

	void paint(Event event) {
		GC gc = event.gc;
		Display display = getDisplay();
		gc.setBackground(display.getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
		gc.setForeground(display.getSystemColor(SWT.COLOR_LIST_SELECTION));
		gc.fillRectangle(event.x, event.y, event.width, event.height);
		TableItem item = null;
		if (row >= 0)
			item = table.getItem(row);
		int x = 0, y = 0;
		Point size = getSize();
		if (item != null) {
			Image image = item.getImage(column);
			if (image != null) {
				Rectangle imageSize = image.getBounds();
				int imageY = y + (int) (((float)size.y - (float)imageSize.height) / 2.0);
				gc.drawImage(image, x, imageY);
				x += imageSize.width;
			}
			x += (column == 0) ? 2 : 6;
			int textY = y + (int) (((float)size.y - (float)gc.getFontMetrics().getHeight()) / 2.0);
			gc.drawString(item.getText(column), x, textY);
		}
		
		if (isFocusControl()) {
			gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
			gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
			gc.drawFocus(0, 0, size.x, size.y);
		}

	}

	void tableFocusIn(Event event) {
		if (isDisposed())
			return;
		if (isVisible()) {
			setFocus();
			redraw();
		}
	}

	void tableMouseDown(Event event) {
		event.doit = true;
		if (isDisposed() || !isVisible())
			return;
		Point pt = new Point(event.x, event.y);
		Rectangle clientRect = table.getClientArea();
		int columns = table.getColumnCount();
		int start = table.getTopIndex();
		int end = table.getItemCount();
		for (int row = start; row < end; row++) {
			TableItem item = table.getItem(row);
			for (int column = 0; column < columns; column++) {
				Rectangle rect = item.getBounds(column);
				if (rect.y > clientRect.y + clientRect.height)
					return;
				if (rect.contains(pt)) {
					setRowColumn(row, column, true);
					//setFocus();
					return;
				}
			}
		}
	}

	void traverse(Event event) {
		switch (event.detail) {
			case SWT.TRAVERSE_ARROW_NEXT :
			case SWT.TRAVERSE_ARROW_PREVIOUS :
			case SWT.TRAVERSE_RETURN :
				event.doit = false;
				return;
		}
		event.doit = true;
	}

	void setRowColumn(int row, int column, boolean notify) {
		if (0 <= row && row < table.getItemCount()) {
			if (0 <= column && column < table.getColumnCount()) {
				this.row = row;
				this.column = column;
				TableItem item = table.getItem(row);
				table.showItem(item);
				setBounds(item.getBounds(column));
//				redraw();
				if (notify) {
					notifyListeners(SWT.Selection, new Event());
				}
			}
		}
		redraw();
		updateVisible();
	}

	@Override
	public void setVisible(boolean visible) {
		checkWidget();
		userVisible = visible;
		resize();
	}

	void resize() {
		if (row >= 0 && row < table.getItemCount()) {
			TableItem item = table.getItem(row);
			setBounds(item.getBounds(column));
		}
		updateVisible();
	}
	
	void updateVisible() {
		progVisible = false;
		if (0 <= row && row < table.getItemCount()) {
			if (0 <= column && column < table.getColumnCount()) {
				progVisible = true;
			}
		}
		super.setVisible(progVisible && userVisible);
	}

	public int getColumn() {
		checkWidget();
		return column;
	}

	public TableItem getRow() {
		checkWidget();
		if (table.getItemCount() == 0)
			return null;
		return table.getItem(row);
	}

	public void setSelection(int row, int column) {
		checkWidget();
		setRowColumn(row, column, false);
	}
	
	public void setSelection(TableItem row, int column) {
		checkWidget();
		setRowColumn(table.indexOf(row), column, false);
	}
	
	private void initAccessible() {
		final Accessible accessible = getAccessible();
		if (accessAdapter == null) {
			accessAdapter = new AccessibleAdapter() {
				@Override
				public void getName(AccessibleEvent e) {
					String name = null;
					TableItem item = null;
					TableColumn[] tableColumns = table.getColumns();
					TableColumn thisCol = null;

					if (row >= 0 && row < table.getItemCount() && column >= 0 && column < table.getColumnCount()) {
						item = table.getItem(row);
						if (column >= 0 && column < tableColumns.length) {
							thisCol = tableColumns[column];
						}
					}
					if (item != null) {
						if (thisCol != null)
							name = thisCol.getText();
						if (name != null && name.length() > 0)
							name = name + "=" + item.getText(column); //$NON-NLS-1$
						else
							name = item.getText(column);
					}
					e.result = name;
				}

				@Override
				public void getHelp(AccessibleEvent e) {
					String help = null;
					e.result = help;
				}
				@Override
				public void getKeyboardShortcut(AccessibleEvent e) {
				}
			};

			accessControlAdapter = new AccessibleControlAdapter() {
				@Override
				public void getChildAtPoint(AccessibleControlEvent e) {
					Point testPoint = toControl(new Point(e.x, e.y));
					int childID = ACC.CHILDID_NONE;
					if (childID == ACC.CHILDID_NONE) {
						Rectangle location = getBounds();
						location.height = location.height - getClientArea().height;
						if (location.contains(testPoint)) {
							childID = ACC.CHILDID_SELF;
						}
					}
					e.childID = childID;
				}

				@Override
				public void getLocation(AccessibleControlEvent e) {
					Rectangle location = null;
					int childID = e.childID;
					if (childID == ACC.CHILDID_SELF) {
						location = getBounds();
					}
					if (location != null) {
						Point pt = toDisplay(new Point(location.x, location.y));
						e.x = pt.x;
						e.y = pt.y;
						e.width = location.width;
						e.height = location.height;
					}
				}

				@Override
				public void getChildCount(AccessibleControlEvent e) {
					e.detail = 0;
				}

				@Override
				public void getDefaultAction(AccessibleControlEvent e) {
					String action = Messages.TableCursor_ScreenReader_Cell_Action1; 
					e.result = action;
				}

				@Override
				public void getFocus(AccessibleControlEvent e) {
					int childID = ACC.CHILDID_NONE;
					if (isFocusControl()) {
						childID = ACC.CHILDID_SELF;
					}
					e.childID = childID;
				}

				@Override
				public void getRole(AccessibleControlEvent e) {
					int role = 0;
					int childID = e.childID;
					if (childID == ACC.CHILDID_SELF)
						role = ACC.ROLE_LISTITEM;
					e.detail = role;
				}

				@Override
				public void getSelection(AccessibleControlEvent e) {
					e.childID = ACC.CHILDID_NONE;
				}

				@Override
				public void getState(AccessibleControlEvent e) {
					int state = 0;
					int childID = e.childID;
					if (childID == ACC.CHILDID_SELF) {
						state = ACC.STATE_SELECTABLE;
						if (isFocusControl()) {
							state |= ACC.STATE_FOCUSABLE;
							if (TableCursor.this.hasFocus) {
								state += ACC.STATE_FOCUSED | ACC.STATE_SELECTED;
							}
						}
					}
					e.detail = state;
				}

				@Override
				public void getChildren(AccessibleControlEvent e) {
					e.children = null;
				}
			};

			selectionAccessListener = new Listener() {
				public void handleEvent(Event event) {
					accessible.setFocus(ACC.CHILDID_SELF);
				}
			};

			focusAccessListener = new Listener() {
				public void handleEvent(Event event) {
					accessible.setFocus(ACC.CHILDID_SELF);
				}
			};
		}

		if (hasAccessibility) {
			accessible.removeAccessibleListener(accessAdapter);
			accessible.removeAccessibleControlListener(accessControlAdapter);
			removeListener(SWT.Selection, selectionAccessListener);
			removeListener(SWT.FocusIn, focusAccessListener);
			hasAccessibility = false;
		}
		if (hasAccessibility == false) {
			accessible.addAccessibleListener(accessAdapter);
			accessible.addAccessibleControlListener(accessControlAdapter);
			addListener(SWT.Selection, selectionAccessListener);
			addListener(SWT.FocusIn, focusAccessListener);
			hasAccessibility = true;
		}
	}	
}

