/*******************************************************************************
 * Copyright (c) 2003, 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:
 *    Kentarou FUKUDA - initial API and implementation
 *******************************************************************************/
package org.eclipse.actf.visualization.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.actf.model.ui.IModelService;
import org.eclipse.actf.model.ui.IModelServiceScrollManager;
import org.eclipse.actf.model.ui.ModelServiceSizeInfo;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;

/**
 * Utility class to show visualization result into {@link Canvas}
 */
public class VisualizationCanvas extends Canvas {

	private final Display display;

	private Image image = null;

	private ImageData imageData = null; // the currently-displayed image

	private int curX;

	private int curY;

	private ScrollBar horizontalBar;

	private ScrollBar verticalBar;

	private List<IPositionSize> highlightTargetList = new ArrayList<IPositionSize>();

	private IModelService current = null;

	private IModelService target = null;

	private String targetUrl = null;

	private boolean sync = true;

	/**
	 * Create {@link VisualizationCanvas}
	 * 
	 * @param parent
	 *            parent {@link Composite}
	 */
	public VisualizationCanvas(Composite parent) {
		this(parent, SWT.NONE);
	}

	/**
	 * Create {@link VisualizationCanvas}
	 * 
	 * @param parent
	 *            parent {@link Composite}
	 * @param style
	 *            widget style
	 */
	public VisualizationCanvas(Composite parent, int style) {
		super(parent, SWT.V_SCROLL | SWT.H_SCROLL | style);
		display = parent.getDisplay();
		init();

		// TODO
		parent.getShell().addListener(100, new Listener() {
			public void handleEvent(Event e) {
				setVScrollBar(e.detail);
			}
		});

	}

	private void init() {
		setBackground(new Color(display, 255, 255, 255));

		curX = 0;
		curY = 0;

		// Set up the image canvas scroll bars.
		horizontalBar = getHorizontalBar();
		horizontalBar.setVisible(true);
		horizontalBar.setMinimum(0);
		horizontalBar.setEnabled(false);
		horizontalBar.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scrollHorizontally((ScrollBar) event.widget);
			}
		});
		verticalBar = getVerticalBar();
		verticalBar.setVisible(true);
		verticalBar.setMinimum(0);
		verticalBar.setEnabled(false);
		verticalBar.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent event) {
				scrollVertically((ScrollBar) event.widget);
			}
		});

		addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				if (null == imageData) {
					return;
				}
				if (null != image) {
					paintImage(event);
				}

				resizeScrollBars();

			}
		});
	}

	private void paintImage(PaintEvent event) {
		if (null == image || null == imageData) {
			return;
		}

		Image paintImage = image;
		int w = Math.round(imageData.width); // xscale
		int h = Math.round(imageData.height); // yscale
		event.gc.drawImage(paintImage, 0, 0, imageData.width, imageData.height,
				curX + imageData.x, curY + imageData.y, w, h);

		List<IPositionSize> tmpV = highlightTargetList;
		if (tmpV != null) {
			// event.gc.setXORMode(false);
			event.gc.setLineWidth(2);
			for (IPositionSize ips : tmpV) {

				event.gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
				event.gc.drawRectangle(curX + ips.getX(), curY + ips.getY(),
						ips.getWidth(), ips.getHeight());

				event.gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
				event.gc.drawRectangle(curX + ips.getX() - 2, curY + ips.getY()
						- 2, ips.getWidth() + 4, ips.getHeight() + 4);

			}
		}
	}

	protected void resetScrollBars() {
		if (image == null) {
			horizontalBar.setEnabled(false);
			verticalBar.setEnabled(false);
			return;
		}

		curX = 0;
		curY = 0;
		resizeScrollBars();
		horizontalBar.setSelection(0);
		verticalBar.setSelection(0);
	}

	private void resizeScrollBars() {
		if (imageData == null)
			return;

		// Set the max and thumb for the image canvas scroll bars.

		Rectangle canvasBounds = getClientArea();
		int width = Math.round(imageData.width); // xscale
		if (width > canvasBounds.width) {
			// The image is wider than the canvas.
			horizontalBar.setEnabled(true);
			horizontalBar.setMaximum(width);
			horizontalBar.setThumb(canvasBounds.width);
			horizontalBar.setPageIncrement(canvasBounds.width);
		} else {
			// The canvas is wider than the image.
			horizontalBar.setEnabled(false);
			if (curX != 0) {
				// Make sure the image is completely visible.
				curX = 0;
				redraw();
			}
		}
		int height = Math.round(imageData.height); // yscale
		if (height > canvasBounds.height) {
			// The image is taller than the canvas.
			verticalBar.setEnabled(true);
			verticalBar.setMaximum(height);
			verticalBar.setThumb(canvasBounds.height);
			verticalBar.setPageIncrement(canvasBounds.height);
		} else {
			// The canvas is taller than the image.
			verticalBar.setEnabled(false);
			if (curY != 0) {
				// Make sure the image is completely visible.
				curY = 0;
				redraw();
			}
		}
	}

	private void setVScrollBar(int iPos) {
		if (sync) {
			if (image == null) {
				return;
			}
			// Rectangle canvasBounds = _imageCanvas.getClientArea();
			int width = Math.round(imageData.width); // xscale
			int height = Math.round(imageData.height); // yscale

			scroll(curX, -iPos, curX, curY, width, height, false);
			curY = -iPos;
			verticalBar.setSelection(iPos);
		}
	}

	private void scrollHorizontally(ScrollBar scrollBar) {
		if (image == null)
			return;
		Rectangle canvasBounds = getClientArea();
		int width = Math.round(imageData.width); // xscale
		int height = Math.round(imageData.height); // yscale
		if (width > canvasBounds.width) {
			// Only scroll if the image is bigger than the canvas.
			int x = -scrollBar.getSelection();
			if (x + width < canvasBounds.width) {
				// Don't scroll past the end of the image.
				x = canvasBounds.width - width;
			}
			scroll(x, curY, curX, curY, width, height, false);
			curX = x;

		}
	}

	private void scrollVertically(ScrollBar scrollBar) {
		if (null != image) {
			Rectangle canvasBounds = getClientArea();
			int width = Math.round(imageData.width); // xscale
			int height = Math.round(imageData.height); // yscale
			if (height > canvasBounds.height) {
				// Only scroll if the image is bigger than the canvas.
				int y = -scrollBar.getSelection();
				if (y + height < canvasBounds.height) {
					// Don't scroll past the end of the image.
					y = canvasBounds.height - height;
				}
				scroll(curX, y, curX, curY, width, height, false);

				if (sync) {
					if (current != null && current == target
							&& targetUrl.equals(target.getURL())) {
						IModelServiceScrollManager scrollManager = target
								.getScrollManager();
						switch (scrollManager.getScrollType()) {
						case IModelServiceScrollManager.ABSOLUTE_COORDINATE:
							int targetHeight = scrollManager.getSize(true)
									.getWholeSizeY();
							double ratio = (double) targetHeight
									/ (double) (height - horizontalBar
											.getSize().y);
							scrollManager.absoluteCoordinateScroll(
									(int) ((curY - y) * ratio), false);
							break;
						case IModelServiceScrollManager.INCREMENTAL:
							// TODO
							break;
						case IModelServiceScrollManager.PAGE:
							ModelServiceSizeInfo sizeInfo = scrollManager
									.getSize(false);
							int page = Math.abs(y / sizeInfo.getViewSizeY()) + 1;
							if (page < 1) {
								page = 1;
							} else if (page > scrollManager.getLastPageNumber()) {
								page = scrollManager.getCurrentPageNumber();
							}
							if (page != scrollManager.getCurrentPageNumber()) {
								scrollManager.jumpToPage(page, false);
							}

							break;
						case IModelServiceScrollManager.NONE:
						default:
						}
					}
				}
				curY = y;
			}
		}
	}

	/**
	 * Set current active model service
	 * 
	 * @param currentModelService
	 *            target {@link IModelService}
	 */
	public void setCurrentModelService(IModelService currentModelService) {
		this.current = currentModelService;
	}

	/**
	 * Show {@link ImageData} to Canvas and set specified {@link IModelService}
	 * as a view sync target
	 * 
	 * @param imageData
	 *            image data to show
	 * @param targetModelService
	 *            target {@link IModelService} for view sync
	 */
	public void showImage(ImageData imageData, IModelService targetModelService) {
		// Dispose of the old image
		if (null != image && !image.isDisposed()) {
			image.dispose();
		}
		this.imageData = imageData;
		target = targetModelService;
		if (null == current) { // first time
			current = target;
		}

		if (null != target) {
			targetUrl = target.getURL();
		} else {
			targetUrl = null;
		}

		if (null != this.imageData) {
			try {
				// Cache the new image
				image = new Image(display, this.imageData);
			} catch (SWTException se) {
				se.printStackTrace();
			}
		}
		redraw();
		resetScrollBars();
	}

	/**
	 * Clear canvas image
	 */
	public void clear() {
		if (image != null && !image.isDisposed()) {
			image.dispose();
			image = null;
		}
		if (imageData != null) {
			imageData = null;
		}
		highlightTargetList = new ArrayList<IPositionSize>();
		resetScrollBars();
		redraw();
	}

	/**
	 * Highlight specified areas
	 * 
	 * @param highlightList
	 *            target area information in {@link IPositionSize} format
	 */
	public void highlight(List<IPositionSize> highlightList) {
		if (highlightList != null) {
			// int topX = 0;
			int topY = -1;

			for (IPositionSize ips : highlightList) {
				if (topY < 0 || topY > ips.getY()) {
					topY = ips.getY();
					// TODO topX = ips.getX();
				}
			}

			if (topY >= 0) {
				Rectangle canvasBounds = getClientArea();
				int height = Math.round(imageData.height); // yscale
				if (height > canvasBounds.height) {
					if (height - topY < canvasBounds.height) {
						// Don't scroll past the end of the image.
						topY = height - canvasBounds.height;
					}
					// if (sync && canSync) {
					// // TODO use VizResult ModelService mapping
					// //
					// BrowserEventListenerManager.getInstance().fireScrollY(this._iy
					// // + topY);
					// }
					setVScrollBar(topY);
				}
			}
			highlightTargetList = highlightList;
		}
		redraw();
	}

	/**
	 * Enable/disable view sync with target {@link IModelService}
	 * 
	 * @param sync
	 *            if true, enable view sync
	 */
	public void setSync(boolean sync) {
		this.sync = sync;
	}

}
