/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.text.source;


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

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.HelpListener;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.SWTEventListener;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Menu;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension3;


/**
 * Standard implementation of <code>IVerticalRuler</code>. This ruler does not have a 
 * a visual representation of its own.  The presentation comes from the configurable list 
 * of decorators. Decorators must implement the <code>IVerticalRulerColumn</code>
 * interface.<p>
 * Clients may instantiate and configure this class.
 *
 * @see IVerticalRulerColumn
 * @see ITextViewer
 * @since 2.0
 */
public class CompositeRuler implements IVerticalRuler, IVerticalRulerExtension {
	
	
	/**
	 * Layout of the composite vertical ruler. Arranges the list of decorators.
	 */
	class RulerLayout extends Layout {
		
		/**
		 * Creates the new ruler layout.
		 */
		protected RulerLayout() {
		}
		
		/*
		 * @see Layout#computeSize(Composite, int, int, boolean)
		 */
		protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
			Control[] children= composite.getChildren();
			Point size= new Point(0, 0);
			for (int i= 0; i < children.length; i++) {
				Point s= children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, flushCache);
				size.x += s.x;
				size.y= Math.max(size.y, s.y);
			}
			size.x += (Math.max(0, children.length -1) * fGap);
			return size;
		}
		
		/*
		 * @see Layout#layout(Composite, boolean)
		 */
		protected void layout(Composite composite, boolean flushCache) {
			Rectangle clArea= composite.getClientArea();
			int rulerHeight= clArea.height;
			
			int x= 0;			
			Iterator e= fDecorators.iterator();
			while (e.hasNext()) {
				IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
				int columnWidth= column.getWidth();
				column.getControl().setBounds(x, 0, columnWidth, rulerHeight);
				x += (columnWidth + fGap);
			}
		}
	};
	
	/**
	 * A canvas that adds listeners to all its children. Used by the implementation of the
	 * vertical ruler to propagate listener additions and removals to the ruler's columns.
	 */
	static class CompositeRulerCanvas extends Canvas {
		
		/**
		 * Keeps the information for which event type a listener object has been added.
		 */
		static class ListenerInfo {
			Class fClass;
			SWTEventListener fListener;
		};
		
		/** The list of listeners added to this canvas. */
		private List fCachedListeners= new ArrayList();
		/** Internal mouse listener for opening the context menu. */
		private MouseListener fMouseListener;
		
		/**
		 * Creates a new composite ruler canvas.
		 * 
		 * @param parent the parent composite
		 * @param style the SWT styles
		 */
		public CompositeRulerCanvas(Composite parent, int style) {
			super(parent, style);
			fMouseListener= new MouseAdapter() {
				public void mouseUp(MouseEvent e) {
					if (3 == e.button) {
						Menu menu= getMenu();
						if (menu != null) {
							Control c= (Control) e.widget;
							Point p= new Point(e.x, e.y);
							Point p2= c.toDisplay(p);
							menu.setLocation(p2.x, p2.y);
							menu.setVisible(true);
						}
					}
				}
			};
			super.addDisposeListener(new DisposeListener() {
				public void widgetDisposed(DisposeEvent e) {
					if (fCachedListeners != null) {
						fCachedListeners.clear();
						fCachedListeners= null;
					}
				}
			});
		}
		
		/**
		 * Adds the given listener object as listner of the given type (<code>clazz</code>) to
		 * the given control.
		 * 
		 * @param clazz the listener type
		 * @param control the control to add the listener to
		 * @param listener the listener to be added
		 */
		private void addListener(Class clazz, Control control, SWTEventListener listener) {
			if (ControlListener.class.equals(clazz)) {
				control. addControlListener((ControlListener) listener);
				return;
			}
			if (FocusListener.class.equals(clazz)) {
				control. addFocusListener((FocusListener) listener);
				return;
			}
			if (HelpListener.class.equals(clazz)) {
				control. addHelpListener((HelpListener) listener);
				return;
			}
			if (KeyListener.class.equals(clazz)) {
				control. addKeyListener((KeyListener) listener);
				return;
			}
			if (MouseListener.class.equals(clazz)) {
				control. addMouseListener((MouseListener) listener);
				return;
			}
			if (MouseMoveListener.class.equals(clazz)) {
				control. addMouseMoveListener((MouseMoveListener) listener);
				return;
			}
			if (MouseTrackListener.class.equals(clazz)) {
				control. addMouseTrackListener((MouseTrackListener) listener);
				return;
			}
			if (PaintListener.class.equals(clazz)) {
				control. addPaintListener((PaintListener) listener);
				return;
			}
			if (TraverseListener.class.equals(clazz)) {
				control. addTraverseListener((TraverseListener) listener);
				return;
			}
			if (DisposeListener.class.equals(clazz)) {
				control. addDisposeListener((DisposeListener) listener);
				return;
			}
		}
		
		/**
		 * Removes the given listener object as listner of the given type (<code>clazz</code>) from
		 * the given control.
		 * 
		 * @param clazz the listener type
		 * @param control the control to remove the listener from
		 * @param listener the listener to be removed
		 */
		private void removeListener(Class clazz, Control control, SWTEventListener listener) {
			if (ControlListener.class.equals(clazz)) {
				control. removeControlListener((ControlListener) listener);
				return;
			}
			if (FocusListener.class.equals(clazz)) {
				control. removeFocusListener((FocusListener) listener);
				return;
			}
			if (HelpListener.class.equals(clazz)) {
				control. removeHelpListener((HelpListener) listener);
				return;
			}
			if (KeyListener.class.equals(clazz)) {
				control. removeKeyListener((KeyListener) listener);
				return;
			}
			if (MouseListener.class.equals(clazz)) {
				control. removeMouseListener((MouseListener) listener);
				return;
			}
			if (MouseMoveListener.class.equals(clazz)) {
				control. removeMouseMoveListener((MouseMoveListener) listener);
				return;
			}
			if (MouseTrackListener.class.equals(clazz)) {
				control. removeMouseTrackListener((MouseTrackListener) listener);
				return;
			}
			if (PaintListener.class.equals(clazz)) {
				control. removePaintListener((PaintListener) listener);
				return;
			}
			if (TraverseListener.class.equals(clazz)) {
				control. removeTraverseListener((TraverseListener) listener);
				return;
			}
			if (DisposeListener.class.equals(clazz)) {
				control. removeDisposeListener((DisposeListener) listener);
				return;
			}		
		}
				
		/**
		 * Adds the given listener object to the internal book keeping under
		 * the given listener type (<code>clazz</code>).
		 * 
		 * @param clazz the listener type
		 * @param listener the listener object
		 */
		private void addListener(Class clazz, SWTEventListener listener) {
			Control[] children= getChildren();
			for (int i= 0; i < children.length; i++) {
				if (children[i] != null && !children[i].isDisposed())
					addListener(clazz, children[i], listener);
			}
			
			ListenerInfo info= new ListenerInfo();
			info.fClass= clazz;
			info.fListener= listener;
			fCachedListeners.add(info);
		}
		
		/**
		 * Removes the given listener object from the internal book keeping under
		 * the given listener type (<code>clazz</code>).
		 * 
		 * @param clazz the listener type
		 * @param listener the listener object
		 */
		private void removeListener(Class clazz, SWTEventListener listener) {
			int length= fCachedListeners.size();
			for (int i= 0; i < length; i++) {
				ListenerInfo info= (ListenerInfo) fCachedListeners.get(i);
				if (listener == info.fListener && clazz.equals(info.fClass)) {
					fCachedListeners.remove(i);
					break;
				}
			}
			
			Control[] children= getChildren();
			for (int i= 0; i < children.length; i++) {
				if (children[i] != null && !children[i].isDisposed())
					removeListener(clazz, children[i], listener);
			}
		}
		
		/**
		 * Tells this canvas that a child has been added.
		 * 
		 * @param child the child
		 */
		public void childAdded(Control child) {
			if (child != null && !child.isDisposed()) {
				int length= fCachedListeners.size();
				for (int i= 0; i < length; i++) {
					ListenerInfo info= (ListenerInfo) fCachedListeners.get(i);
					addListener(info.fClass, child, info.fListener);
				}
				child.addMouseListener(fMouseListener);
			}
		}
		
		/**
		 * Tells this canvas that a child has been removed.
		 * 
		 * @param child the child
		 */
		public void childRemoved(Control child) {
			if (child != null && !child.isDisposed()) {
				int length= fCachedListeners.size();
				for (int i= 0; i < length; i++) {
					ListenerInfo info= (ListenerInfo) fCachedListeners.get(i);
					removeListener(info.fClass, child, info.fListener);
				}
				child.removeMouseListener(fMouseListener);
			}
		}
		
		/*
		 * @see Control#removeControlListener(ControlListener)
		 */
		public void removeControlListener(ControlListener listener) {
			removeListener(ControlListener.class, listener);
			super.removeControlListener(listener);
		}
		
		/*
		 * @see Control#removeFocusListener(FocusListener)
		 */
		public void removeFocusListener(FocusListener listener) {
			removeListener(FocusListener.class, listener);
			super.removeFocusListener(listener);
		}
		
		/*
		 * @see Control#removeHelpListener(HelpListener)
		 */
		public void removeHelpListener(HelpListener listener) {
			removeListener(HelpListener.class, listener);
			super.removeHelpListener(listener);
		}
		
		/*
		 * @see Control#removeKeyListener(KeyListener)
		 */
		public void removeKeyListener(KeyListener listener) {
			removeListener(KeyListener.class, listener);
			super.removeKeyListener(listener);
		}
		
		/*
		 * @see Control#removeMouseListener(MouseListener)
		 */
		public void removeMouseListener(MouseListener listener) {
			removeListener(MouseListener.class, listener);
			super.removeMouseListener(listener);
		}
		
		/*
		 * @see Control#removeMouseMoveListener(MouseMoveListener)
		 */
		public void removeMouseMoveListener(MouseMoveListener listener) {
			removeListener(MouseMoveListener.class, listener);
			super.removeMouseMoveListener(listener);
		}
		
		/*
		 * @see Control#removeMouseTrackListener(MouseTrackListener)
		 */
		public void removeMouseTrackListener(MouseTrackListener listener) {
			removeListener(MouseTrackListener.class, listener);
			super.removeMouseTrackListener(listener);
		}
		
		/*
		 * @see Control#removePaintListener(PaintListener)
		 */
		public void removePaintListener(PaintListener listener) {
			removeListener(PaintListener.class, listener);
			super.removePaintListener(listener);
		}
		
		/*
		 * @see Control#removeTraverseListener(TraverseListener)
		 */
		public void removeTraverseListener(TraverseListener listener) {
			removeListener(TraverseListener.class, listener);
			super.removeTraverseListener(listener);
		}
		
		/*
		 * @see Widget#removeDisposeListener(DisposeListener)
		 */
		public void removeDisposeListener(DisposeListener listener) {
			removeListener(DisposeListener.class, listener);
			super.removeDisposeListener(listener);
		}
		
		/*
		 * @seeControl#addControlListener(ControlListener)
		 */
		public void addControlListener(ControlListener listener) {
			super.addControlListener(listener);
			addListener(ControlListener.class, listener);
		}
		
		/*
		 * @see Control#addFocusListener(FocusListener)
		 */
		public void addFocusListener(FocusListener listener) {
			super.addFocusListener(listener);
			addListener(FocusListener.class, listener);
		}
		
		/* 
		 * @see Control#addHelpListener(HelpListener)
		 */
		public void addHelpListener(HelpListener listener) {
			super.addHelpListener(listener);
			addListener(HelpListener.class, listener);
		}

		/*
		 * @see Control#addKeyListener(KeyListener)
		 */
		public void addKeyListener(KeyListener listener) {
			super.addKeyListener(listener);
			addListener(KeyListener.class, listener);
		}
		
		/*
		 * @see Control#addMouseListener(MouseListener)
		 */
		public void addMouseListener(MouseListener listener) {
			super.addMouseListener(listener);
			addListener(MouseListener.class, listener);
		}

		/*
		 * @see Control#addMouseMoveListener(MouseMoveListener)
		 */
		public void addMouseMoveListener(MouseMoveListener listener) {
			super.addMouseMoveListener(listener);
			addListener(MouseMoveListener.class, listener);
		}

		/* 
		 * @see Control#addMouseTrackListener(MouseTrackListener)
		 */
		public void addMouseTrackListener(MouseTrackListener listener) {
			super.addMouseTrackListener(listener);
			addListener(MouseTrackListener.class, listener);
		}
		
		/* 
		 * @seeControl#addPaintListener(PaintListener)
		 */
		public void addPaintListener(PaintListener listener) {
			super.addPaintListener(listener);
			addListener(PaintListener.class, listener);
		}
		
		/* 
		 * @see Control#addTraverseListener(TraverseListener)
		 */
		public void addTraverseListener(TraverseListener listener) {
			super.addTraverseListener(listener);
			addListener(TraverseListener.class, listener);
		}
		
		/*
		 * @see Widget#addDisposeListener(DisposeListener)
		 */
		public void addDisposeListener(DisposeListener listener) {
			super.addDisposeListener(listener);
			addListener(DisposeListener.class, listener);
		}
	};
	
	/** The ruler's viewer */
	private ITextViewer fTextViewer;
	/** The ruler's canvas to which to add the ruler columns */
	private CompositeRulerCanvas fComposite;
	/** The ruler's annotation model */
	private IAnnotationModel fModel;
	/** The list of decorators */
	private List fDecorators= new ArrayList(2);
	/** The cached location of the last mouse button activity */
	private Point fLocation= new Point(-1, -1);
	/** The cached line of the list mouse button activity */
	private int fLastMouseButtonActivityLine= -1;
	/** The gap between the individual columns of this composite ruler */
	private int fGap;
	
	
	/**
	 * Constructs a new composite vertical ruler.
	 */
	public CompositeRuler() {
		this(0);
	}
	
	/**
	 * Constructs a new composite ruler with the given gap between its columns.
	 * 
	 * @param gap
	 */
	public CompositeRuler(int gap) {
		fGap= gap;
	}
	
	/**
	 * Inserts the given decorator at the specfied slot to this composite ruler.
	 * Decorators are counted from left to right.
	 * 
	 * @param index the index
	 * @param rulerColumn the decorator to be inserted
	 */
	public void addDecorator(int index, IVerticalRulerColumn rulerColumn) {
		fDecorators.add(index, rulerColumn);
		if (fComposite != null && !fComposite.isDisposed()) {
			rulerColumn.createControl(this, fComposite);
			fComposite.childAdded(rulerColumn.getControl());
			layoutTextViewer();
		}
	}
	
	/**
	 * Removes the decorator in the specified slot from this composite ruler.
	 * 
	 * @param index the index
	 */
	public void removeDecorator(int index) {
		IVerticalRulerColumn column= (IVerticalRulerColumn) fDecorators.get(index);
		fDecorators.remove(index);
		Control cc= column.getControl();
		if (cc != null && !cc.isDisposed()) {
			fComposite.childRemoved(cc);
			cc.dispose();
		}
		layoutTextViewer();
	}
	
	/**
	 * Relayouts the text viewer. This also causes this ruler to get
	 * relayouted.
	 */
	private void layoutTextViewer() {
		
		Control parent= fTextViewer.getTextWidget();
		
		if (fTextViewer instanceof ITextViewerExtension) {
			ITextViewerExtension extension= (ITextViewerExtension) fTextViewer;
			parent= extension.getControl();
		}
		
		if (parent instanceof Composite && !parent.isDisposed())
			((Composite) parent).layout(true);
	}
	
	/*
	 * @see IVerticalRuler#getControl()
	 */
	public Control getControl() {
		return fComposite;
	}
	
	/*
	 * @see IVerticalRuler#createControl(Composite, ITextViewer)
	 */
	public Control createControl(Composite parent, ITextViewer textViewer) {
		
		fTextViewer= textViewer;
		
		fComposite= new CompositeRulerCanvas(parent, SWT.NONE);
		fComposite.setLayout(new RulerLayout());
		
		Iterator e= fDecorators.iterator();
		while (e.hasNext()) {
			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
			column.createControl(this, fComposite);
			fComposite.childAdded(column.getControl());
		}
		
		parent.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent e) {
				fTextViewer= null;
				fComposite= null;
				fModel= null;
				fDecorators.clear();
			}
		});
		
		return fComposite;
	}
		
	/*
	 * @see IVerticalRuler#setModel(IAnnotationModel)
	 */
	public void setModel(IAnnotationModel model) {
		
		fModel= model;
		
		Iterator e= fDecorators.iterator();
		while (e.hasNext()) {
			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
			column.setModel(model);
		}	
	}
	
	/*
	 * @see IVerticalRuler#getModel()
	 */
	public IAnnotationModel getModel() {
		return fModel;
	}
	
	/*
	 * @see IVerticalRuler#update()
	 */
	public void update() {
		if (fComposite != null && !fComposite.isDisposed()) {
			Display d= fComposite.getDisplay();
			if (d != null) {
				d.asyncExec(new Runnable() {
					public void run() {
						Iterator e= fDecorators.iterator();
						while (e.hasNext()) {
							IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
							column.redraw();
						}	
					}
				});
			}	
		}
	}
	
	/*
	 * @see IVerticalRulerExtension#setFont(Font)
	 */
	public void setFont(Font font) {
		Iterator e= fDecorators.iterator();
		while (e.hasNext()) {
			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
			column.setFont(font);
		}	
	}
	
	/*
	 * @see IVerticalRulerInfo#getWidth()
	 */
	public int getWidth() {
		int width= 0;
		Iterator e= fDecorators.iterator();
		while (e.hasNext()) {
			IVerticalRulerColumn column= (IVerticalRulerColumn) e.next();
			width += (column.getWidth() + fGap);
		}
		return Math.max(0, width - fGap);
	}
	
	/*
	 * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
	 */
	public int getLineOfLastMouseButtonActivity() {
		if (fLastMouseButtonActivityLine == -1)
			fLastMouseButtonActivityLine= toDocumentLineNumber(fLocation.y);
		return fLastMouseButtonActivityLine;
	}
	
	/*
	 * @see IVerticalRulerInfo#toDocumentLineNumber(int)
	 */
	public int toDocumentLineNumber(int y_coordinate) {
		
		if (fTextViewer == null || y_coordinate == -1)
			return -1;
			
		StyledText text= fTextViewer.getTextWidget();
		int line= ((y_coordinate + text.getTopPixel()) / text.getLineHeight());
		return widgetLine2ModelLine(fTextViewer, line);
	}
		
	/**
	 * Returns the line in the given viewer's document that correspond to the given
	 * line of the viewer's widget.
	 * 
	 * @param viewer the viewer
	 * @param widgetLine the widget line
	 * @return the corresponding line the viewer's document
	 * @since 2.1
	 */
	protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {

		if (viewer instanceof ITextViewerExtension3) {
			ITextViewerExtension3 extension= (ITextViewerExtension3) viewer;
			return extension.widgetlLine2ModelLine(widgetLine);
		}

		try {
			IRegion r= viewer.getVisibleRegion();
			IDocument d= viewer.getDocument();
			return widgetLine += d.getLineOfOffset(r.getOffset());
		} catch (BadLocationException x) {
		}
		return widgetLine;
	}
	
	/**
	 * Returns this ruler's text viewer.
	 * 
	 * @return this ruler's text viewer
	 */
	public ITextViewer getTextViewer() {
		return fTextViewer;
	}
	
	/*
	 * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int)
	 */
	public void setLocationOfLastMouseButtonActivity(int x, int y) {
		fLocation.x= x;
		fLocation.y= y;
		fLastMouseButtonActivityLine= -1;
	}
}
