/*******************************************************************************
 * Copyright (c) 2006, 2007 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
 *     Brad Reynolds - bug 116920
 *******************************************************************************/

package org.eclipse.jface.examples.databinding.snippets;

import java.text.NumberFormat;
import java.text.ParseException;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.WritableList;
import org.eclipse.core.databinding.observable.value.ComputedValue;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.internal.databinding.provisional.swt.TableUpdater;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ControlEditor;
import org.eclipse.swt.custom.TableCursor;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;

/**
 * @since 1.1
 * 
 */
public class Snippet006Spreadsheet {

	private static final int COUNTER_UPDATE_DELAY = 1000;

	private static final int NUM_COLUMNS = 6;

	private static final int NUM_ROWS = 16;

	/**
	 * 0 for no output, 1 for some, 2 for more
	 */
	private static int DEBUG_LEVEL = 0;

	/**
	 * If true, there will be a automatic counter at B1.
	 */
	private static boolean FUNKY_COUNTER = false;

	/**
	 * // * If true, all formulas (except for row 1 and column A) will be the
	 * sum of the values of their left and top neighbouring cells.
	 */
	private static boolean FUNKY_FORMULAS = true;

	static WritableValue[][] cellFormulas = new WritableValue[NUM_ROWS][NUM_COLUMNS];

	static ComputedValue[][] cellValues = new ComputedValue[NUM_ROWS][NUM_COLUMNS];

	static class ComputedCellValue extends ComputedValue {
		private final IObservableValue cellFormula;

		private boolean calculating;

		ComputedCellValue(IObservableValue cellFormula) {
			this.cellFormula = cellFormula;
		}

		protected Object calculate() {
			if (calculating) {
				return "#cycle";
			}
			try {
				calculating = true;
				return evaluate(cellFormula.getValue());
			} finally {
				calculating = false;
			}
		}

		private Object evaluate(Object value) {
			if (DEBUG_LEVEL >= 2) {
				System.out.println("evaluating " + this + " ...");
			}
			if (value == null) {
				return "";
			}
			try {
				String s = (String) value;
				if (!s.startsWith("=")) {
					return s;
				}
				String addition = s.substring(1);
				int indexOfPlus = addition.indexOf('+');
				String operand1 = addition.substring(0, indexOfPlus);
				double value1 = eval(operand1);
				String operand2 = addition.substring(indexOfPlus + 1);
				double value2 = eval(operand2);
				return NumberFormat.getNumberInstance().format(value1 + value2);
			} catch (Exception ex) {
				return ex.getMessage();
			}
		}

		/**
		 * @param s
		 * @return
		 * @throws ParseException
		 */
		private double eval(String s) throws ParseException {
			if (s.length() == 0) {
				return 0;
			}
			char character = s.charAt(0);
			if (Character.isLetter(character)) {
				character = Character.toLowerCase(character);
				// reference to other cell
				int columnIndex = character - 'a';
				int rowIndex = 0;
				rowIndex = NumberFormat.getNumberInstance().parse(
						s.substring(1)).intValue() - 1;
				String value = (String) cellValues[rowIndex][columnIndex]
						.getValue();
				return value.length() == 0 ? 0 : NumberFormat
						.getNumberInstance().parse(value).doubleValue();
			}
			return NumberFormat.getNumberInstance().parse(s).doubleValue();
		}
	}

	protected static int counter;

	public static void main(String[] args) {

		final Display display = new Display();
		Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
			public void run() {
				Shell shell = new Shell(display);
				shell.setText("Data Binding Snippet 006");

				final Table table = new Table(shell, SWT.BORDER | SWT.MULTI
						| SWT.FULL_SELECTION | SWT.VIRTUAL);
				table.setLinesVisible(true);
				table.setHeaderVisible(true);

				for (int i = 0; i < NUM_COLUMNS; i++) {
					TableColumn tableColumn = new TableColumn(table, SWT.NONE);
					tableColumn.setText(Character.toString((char) ('A' + i)));
					tableColumn.setWidth(60);
				}
				WritableList list = new WritableList();
				for (int i = 0; i < NUM_ROWS; i++) {
					list.add(new Object());
					for (int j = 0; j < NUM_COLUMNS; j++) {
						cellFormulas[i][j] = new WritableValue();
						cellValues[i][j] = new ComputedCellValue(
								cellFormulas[i][j]);
						if (!FUNKY_FORMULAS || i == 0 || j == 0) {
							cellFormulas[i][j].setValue("");
						} else {
							cellFormulas[i][j].setValue("="
									+ cellReference(i - 1, j) + "+"
									+ cellReference(i, j - 1));
						}
					}
				}

				new TableUpdater(table, list) {
					protected void updateItem(int rowIndex, TableItem item, Object element) {
						if (DEBUG_LEVEL >= 1) {
							System.out.println("updating row " + rowIndex);
						}
						for (int j = 0; j < NUM_COLUMNS; j++) {
							item.setText(j, (String) cellValues[rowIndex][j]
									.getValue());
						}
					}
				};

				if (FUNKY_COUNTER) {
					// counter in A1
					display.asyncExec(new Runnable() {
						public void run() {
							cellFormulas[0][1].setValue("" + counter++);
							display.timerExec(COUNTER_UPDATE_DELAY, this);
						}
					});
				}

				// create a TableCursor to navigate around the table
				final TableCursor cursor = new TableCursor(table, SWT.NONE);
				// create an editor to edit the cell when the user hits "ENTER"
				// while over a cell in the table
				final ControlEditor editor = new ControlEditor(cursor);
				editor.grabHorizontal = true;
				editor.grabVertical = true;

				cursor.addSelectionListener(new SelectionAdapter() {
					// when the TableEditor is over a cell, select the
					// corresponding row
					// in
					// the table
					public void widgetSelected(SelectionEvent e) {
						table.setSelection(new TableItem[] { cursor.getRow() });
					}

					// when the user hits "ENTER" in the TableCursor, pop up a
					// text
					// editor so that
					// they can change the text of the cell
					public void widgetDefaultSelected(SelectionEvent e) {
						final Text text = new Text(cursor, SWT.NONE);
						TableItem row = cursor.getRow();
						int rowIndex = table.indexOf(row);
						int columnIndex = cursor.getColumn();
						text
								.setText((String) cellFormulas[rowIndex][columnIndex]
										.getValue());
						text.addKeyListener(new KeyAdapter() {
							public void keyPressed(KeyEvent e) {
								// close the text editor and copy the data over
								// when the user hits "ENTER"
								if (e.character == SWT.CR) {
									TableItem row = cursor.getRow();
									int rowIndex = table.indexOf(row);
									int columnIndex = cursor.getColumn();
									cellFormulas[rowIndex][columnIndex]
											.setValue(text.getText());
									text.dispose();
								}
								// close the text editor when the user hits
								// "ESC"
								if (e.character == SWT.ESC) {
									text.dispose();
								}
							}
						});
						editor.setEditor(text);
						text.setFocus();
					}
				});
				// Hide the TableCursor when the user hits the "MOD1" or "MOD2"
				// key.
				// This alows the user to select multiple items in the table.
				cursor.addKeyListener(new KeyAdapter() {
					public void keyPressed(KeyEvent e) {
						if (e.keyCode == SWT.MOD1 || e.keyCode == SWT.MOD2
								|| (e.stateMask & SWT.MOD1) != 0
								|| (e.stateMask & SWT.MOD2) != 0) {
							cursor.setVisible(false);
						}
					}
				});
				// Show the TableCursor when the user releases the "MOD2" or
				// "MOD1" key.
				// This signals the end of the multiple selection task.
				table.addKeyListener(new KeyAdapter() {
					public void keyReleased(KeyEvent e) {
						if (e.keyCode == SWT.MOD1
								&& (e.stateMask & SWT.MOD2) != 0)
							return;
						if (e.keyCode == SWT.MOD2
								&& (e.stateMask & SWT.MOD1) != 0)
							return;
						if (e.keyCode != SWT.MOD1
								&& (e.stateMask & SWT.MOD1) != 0)
							return;
						if (e.keyCode != SWT.MOD2
								&& (e.stateMask & SWT.MOD2) != 0)
							return;

						TableItem[] selection = table.getSelection();
						TableItem row = (selection.length == 0) ? table
								.getItem(table.getTopIndex()) : selection[0];
						table.showItem(row);
						cursor.setSelection(row, 0);
						cursor.setVisible(true);
						cursor.setFocus();
					}
				});

				GridLayoutFactory.fillDefaults().generateLayout(shell);
				shell.setSize(400, 300);
				shell.open();

				// The SWT event loop
				while (!shell.isDisposed()) {
					if (!display.readAndDispatch()) {
						display.sleep();
					}
				}
			}
		});
		display.dispose();
	}

	private static String cellReference(int rowIndex, int columnIndex) {
		String cellReference = "" + ((char) ('A' + columnIndex))
				+ (rowIndex + 1);
		return cellReference;
	}

}
