/*******************************************************************************
 * Copyright (c) 2004, 2006 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();
			}
		}
	}
}
