/*****************************************************************************
 * Copyright (c) 2004 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.wst.xml.ui.internal.tabletree;

import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;


public class TreeExtension implements PaintListener {

	protected Tree fTree;
	protected EditManager editManager;
	protected String[] fColumnProperties;
	protected ICellModifier cellModifier;
	protected int columnPosition = 300;
	protected int columnHitWidth = 5;
	protected Color tableLineColor;
	protected int controlWidth;
	protected DelayedDrawTimer delayedDrawTimer;
	private boolean fisUnsupportedInput = false;

	public TreeExtension(Tree tree) {
		this.fTree = tree;
		InternalMouseListener listener = new InternalMouseListener();
		tree.addMouseMoveListener(listener);
		tree.addMouseListener(listener);
		tree.addPaintListener(this);
		editManager = new EditManager(tree);
		delayedDrawTimer = new DelayedDrawTimer(tree);

		tableLineColor = tree.getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW);
	}

	public void dispose() {
		tableLineColor.dispose();
	}

	public void setCellModifier(ICellModifier modifier) {
		cellModifier = modifier;
	}

	public void resetCachedData() {
		// todo: sure seems we should reset something?
	}

	public ICellModifier getCellModifier() {
		return cellModifier;
	}

	public List getItemList() {
		List list = new Vector();
		getItemListHelper(fTree.getItems(), list);
		return list;
	}

	protected void getItemListHelper(TreeItem[] items, List list) {
		for (int i = 0; i < items.length; i++) {
			TreeItem item = items[i];
			list.add(item);
			getItemListHelper(item.getItems(), list);
		}
	}

	protected TreeItem getTreeItemOnRow(int px, int py) {
		TreeItem result = null;
		List list = getItemList();
		for (Iterator i = list.iterator(); i.hasNext();) {
			TreeItem item = (TreeItem) i.next();
			Rectangle r = item.getBounds();
			if ((r != null) && (px >= r.x) && (py >= r.y) && (py <= r.y + r.height)) {
				result = item;
			}
		}
		return result;
	}

	protected class InternalMouseListener extends MouseAdapter implements MouseMoveListener {
		protected int columnDragged = -1;
		protected boolean isDown = false;
		protected int prevX = -1;
		protected Cursor cursor = null;

		public void mouseMove(MouseEvent e) {
			if ((e.x > columnPosition - columnHitWidth) && (e.x < columnPosition + columnHitWidth)) {
				if (cursor == null) {
					cursor = new Cursor(fTree.getDisplay(), SWT.CURSOR_SIZEWE);
					fTree.setCursor(cursor);
				}
			}
			else {
				if (cursor != null) {
					fTree.setCursor(null);
					cursor.dispose();
					cursor = null;
				}
			}

			if (columnDragged != -1) {
				// using the delay timer will make redraws less flickery
				if (e.x > 20) {
					columnPosition = e.x;
					delayedDrawTimer.reset(20);
				}
			}
		}

		public void mouseDown(MouseEvent e) {
			// here we handle the column resizing by detect if the user has
			// click on a column separator
			//
			columnDragged = -1;
			editManager.deactivateCellEditor();

			if ((e.x > columnPosition - columnHitWidth) && (e.x < columnPosition + columnHitWidth)) {
				columnDragged = 0;
			}

			// here we handle selecting tree items when any thing on the 'row'
			// is clicked
			//
			TreeItem item = fTree.getItem(new Point(e.x, e.y));
			if (item == null) {
				item = getTreeItemOnRow(e.x, e.y);
				if (item != null) {
					TreeItem[] items = new TreeItem[1];
					items[0] = item;
					fTree.setSelection(items);
				}
			}
		}

		public void mouseUp(MouseEvent e) {
			columnDragged = -1;
		}
	}

	public String[] getColumnProperties() {
		return fColumnProperties;
	}

	public void setColumnProperties(String[] columnProperties) {
		this.fColumnProperties = columnProperties;
	}

	public void paintControl(PaintEvent event) {
		GC gc = event.gc;
		Rectangle treeBounds = fTree.getBounds();

		controlWidth = treeBounds.width;
		Color bg = fTree.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
		Color bg2 = fTree.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION);

		gc.setBackground(bg2);

		// // This next part causes problems on LINUX, so let's not do it
		// there
		// if (B2BHacks.IS_UNIX == false) {
		// TreeItem[] selectedItems = tree.getSelection();
		// if (selectedItems.length > 0) {
		// for (int i = 0; i < selectedItems.length; i++) {
		// TreeItem item = selectedItems[i];
		// Rectangle bounds = item.getBounds();
		// if (bounds != null) {
		// gc.fillRectangle(bounds.x + bounds.width, bounds.y, controlWidth,
		// bounds.height);
		// }
		// }
		// }
		// }
		//
		if (!fisUnsupportedInput) {
			TreeItem[] items = fTree.getItems();
			if (items.length > 0) {
				gc.setForeground(tableLineColor);
				gc.setBackground(bg);

				gc.fillRectangle(columnPosition, treeBounds.x, treeBounds.width, treeBounds.height);

				Rectangle itemBounds = items[0].getBounds();
				int height = computeTreeItemHeight();

				if (itemBounds != null) {
					/*
					 * Bounds will be for the first item, which will either be
					 * visible at the top of the Tree, or scrolled off with
					 * negative values
					 */
					int startY = itemBounds.y;

					/* Only draw lines within the Tree boundaries */
					for (int i = startY; i < treeBounds.height; i += height) {
						if (i >= treeBounds.y) {
							gc.drawLine(0, i, treeBounds.width, i);
						}
					}
				}
				gc.drawLine(columnPosition, 0, columnPosition, treeBounds.height);
				paintItems(gc, items, treeBounds);

			}
			else {
				addEmptyTreeMessage(gc);
			}
		}
		else {
			addUnableToPopulateTreeMessage(gc);
		}
	}

	protected int computeTreeItemHeight() {
		int result = -1;

		/*
		 * On GTK tree.getItemHeight() seems to lie to us. It reports that the
		 * tree item occupies a few pixles less vertical space than it should
		 * (possibly because of the image height vs. the text height?). This
		 * foils our code that draws the 'row' lines since we assume that
		 * lines should be drawn at 'itemHeight' increments. Don't trust
		 * getItemHeight() to compute the increment... instead compute the
		 * value based on distance between two TreeItems, and then use the
		 * larger value.
		 * 
		 * This strategy only works on trees where the items are of even
		 * height, however bug
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=117201 indicates that
		 * this is no longer promised, at least on win32 and likely on other
		 * platforms soon.
		 */
		if (fTree.getItemCount() > 0) {
			TreeItem[] items = fTree.getItems();
			Rectangle itemBounds = items[0].getBounds();

			if (items[0].getExpanded()) {
				TreeItem[] children = items[0].getItems();
				if (children.length > 0) {
					result = children[0].getBounds().y - itemBounds.y;
				}
			}
			else if (items.length > 1) {
				result = items[1].getBounds().y - itemBounds.y;
			}
		}

		result = Math.max(fTree.getItemHeight(), result);
		return result;
	}

	protected void addEmptyTreeMessage(GC gc) {
		// nothing to add here
	}

	private void addUnableToPopulateTreeMessage(GC gc) {
		// here we print a message when the document cannot be displayed just
		// to give the
		// user a visual cue
		// so that they know how to proceed to edit the blank view
		gc.setForeground(fTree.getDisplay().getSystemColor(SWT.COLOR_BLACK));
		gc.setBackground(fTree.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
		gc.drawString(XMLEditorMessages.TreeExtension_0, 10, 10);
	}

	void setIsUnsupportedInput(boolean isUnsupported) {
		fisUnsupportedInput = isUnsupported;
	}

	public void paintItems(GC gc, TreeItem[] items, Rectangle treeBounds) {
		if (items != null) {
			for (int i = 0; i < items.length; i++) {
				TreeItem item = items[i];
				if (item != null) {
					Rectangle bounds = item.getBounds();
					if (bounds != null) {
						if (treeBounds.intersects(bounds)) {
							paintItem(gc, item, bounds);
						}
					}

					// defect 241039
					//
					if (item.getExpanded()) {
						paintItems(gc, item.getItems(), treeBounds);
					}
				}
			}
		}
	}

	protected void paintItem(GC gc, TreeItem item, Rectangle bounds) {
		// nothing to paint
	}

	public interface ICellEditorProvider {
		CellEditor getCellEditor(Object o, int col);
	}

	/**
	 * This class is used to improve drawing during a column resize.
	 */
	public class DelayedDrawTimer implements Runnable {
		protected Control control;

		public DelayedDrawTimer(Control control1) {
			this.control = control1;
		}

		public void reset(int milliseconds) {
			getDisplay().timerExec(milliseconds, this);
		}

		public void run() {
			control.redraw();
		}
	}

	Display getDisplay() {

		return PlatformUI.getWorkbench().getDisplay();
	}

	/**
	 * EditManager
	 */
	public class EditManager {
		protected Tree fTree1;
		protected Control cellEditorHolder;
		protected CellEditorState cellEditorState;

		public EditManager(Tree tree) {
			this.fTree1 = tree;
			this.cellEditorHolder = new Composite(tree, SWT.NONE);

			final Tree theTree = tree;

			MouseAdapter theMouseAdapter = new MouseAdapter() {
				public void mouseDown(MouseEvent e) {
					deactivateCellEditor();

					if (e.x > columnPosition + columnHitWidth) {
						TreeItem[] items = theTree.getSelection();
						// No edit if more than one row is selected.
						if (items.length == 1) {
							Rectangle bounds = items[0].getBounds();
							if ((bounds != null) && (e.y >= bounds.y) && (e.y <= bounds.y + bounds.height)) {
								int columnToEdit = 1;
								activateCellEditor(items[0], columnToEdit);
							}
						}
					}
				}
			};

			SelectionListener selectionListener = new SelectionListener() {
				public void widgetDefaultSelected(SelectionEvent e) {
					applyCellEditorValue();
				}

				public void widgetSelected(SelectionEvent e) {
					applyCellEditorValue();
				}
			};

			KeyListener keyListener = new KeyAdapter() {
				public void keyPressed(KeyEvent e) {
					if (e.character == SWT.CR) {
						deactivateCellEditor();
						TreeItem[] items = theTree.getSelection();
						if (items.length == 1) {
							activateCellEditor(items[0], 1);
						}
					}
				}
			};

			tree.addMouseListener(theMouseAdapter);
			tree.addKeyListener(keyListener);
			ScrollBar hBar = tree.getHorizontalBar();
			if (hBar != null) {
				hBar.addSelectionListener(selectionListener);
			}
			ScrollBar vBar = tree.getVerticalBar();
			if (vBar != null) {
				vBar.addSelectionListener(selectionListener);
			}
		}

		public boolean isCellEditorActive() {
			return cellEditorState != null;
		}

		public void applyCellEditorValue() {
			if ((cellEditorState != null) && (cellModifier != null)) {
				TreeItem treeItem = cellEditorState.fTreeItem;

				// The area below the cell editor needs to be explicity
				// repainted on Linux
				//
				// Rectangle r = B2BHacks.IS_UNIX ? treeItem.getBounds() :
				// null;

				Object value = cellEditorState.fCellEditor.getValue();
				String property = cellEditorState.fProperty;

				deactivateCellEditor();

				cellModifier.modify(treeItem, property, value);

				// if (r != null) {
				// tree.redraw(r.x, r.y, tree.getBounds().width, r.height,
				// false);
				// }
			}
		}

		public void deactivateCellEditor() {
			// Clean up any previous editor control
			if (cellEditorState != null) {
				cellEditorState.deactivate();
				cellEditorState = null;
			}
		}

		public void activateCellEditor(TreeItem treeItem, int column) {
			if (cellModifier instanceof ICellEditorProvider) {
				ICellEditorProvider cellEditorProvider = (ICellEditorProvider) cellModifier;
				Object data = treeItem.getData();
				if (fColumnProperties.length > column) {
					String property = fColumnProperties[column];
					if (cellModifier.canModify(data, property)) {
						CellEditor newCellEditor = cellEditorProvider.getCellEditor(data, column);
						if (newCellEditor != null) {
							// The control that will be the editor must be a
							// child of the columnPosition
							Control control = newCellEditor.getControl();
							if (control != null) {
								cellEditorState = new CellEditorState(newCellEditor, control, treeItem, column, property);
								cellEditorState.activate();
							}
						}
					}
				}
			}
		}

		/**
		 * this class holds the state that is need on a per cell editor
		 * invocation basis
		 */
		public class CellEditorState implements ICellEditorListener, FocusListener {
			public CellEditor fCellEditor;
			public Control fControl;
			public TreeItem fTreeItem;
			public int fColumnNumber;
			public String fProperty;

			public CellEditorState(CellEditor cellEditor, Control control, TreeItem treeItem, int columnNumber, String property) {
				this.fCellEditor = cellEditor;
				this.fControl = control;
				this.fTreeItem = treeItem;
				this.fColumnNumber = columnNumber;
				this.fProperty = property;
			}

			public void activate() {
				Object element = fTreeItem.getData();
				String value = cellModifier.getValue(element, fProperty).toString();
				if (fControl instanceof Text) {
					Text text = (Text) fControl;
					int requiredSize = value.length() + 100;
					if (text.getTextLimit() < requiredSize) {
						text.setTextLimit(requiredSize);
					}
				}
				Rectangle r = fTreeItem.getBounds();
				if (r != null) {
					fControl.setBounds(columnPosition + 5, r.y + 1, fTree1.getClientArea().width - (columnPosition + 5), r.height - 1);
					fControl.setVisible(true);
					fCellEditor.setValue(value);
					fCellEditor.addListener(this);
					fCellEditor.setFocus();
					fControl.addFocusListener(this);
				}
			}

			public void deactivate() {
				fCellEditor.removeListener(this);
				fControl.removeFocusListener(this);
				fCellEditor.deactivate();
				fTree1.forceFocus();
			}

			// ICellEditorListener methods
			//
			public void applyEditorValue() {
				applyCellEditorValue();
			}

			public void cancelEditor() {
				deactivateCellEditor();
			}

			public void editorValueChanged(boolean oldValidState, boolean newValidState) {
				// nothing, for now
			}

			// FocusListener methods
			//
			public void focusGained(FocusEvent e) {
				// do nothing
			}

			public void focusLost(FocusEvent e) {
				applyCellEditorValue();
			}
		}
	}
}