// This code has been adapted and copied from code that has been written by Immanuel Scholz and others for JOSM.
// License: GPL. Copyright 2007 by Tim Haussmann

import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

/**
 * This class controls the user input by listening to mouse and key events.
 * Currently implemented is: - zooming in and out with scrollwheel - zooming in
 * and centering by double clicking - selecting an area by clicking and dragging
 * the mouse
 * 
 * @author Tim Haussmann
 */
public class OsmMapControl extends MouseAdapter implements MouseMotionListener, MouseListener {

	// start and end point of selection rectangle
	private Point iStartSelectionPoint;
	private Point iEndSelectionPoint;

	// the SlippyMapChooserComponent
	private final SlippyMapChooser iSlippyMapChooser;

	private SizeButton iSizeButton = null;
	private SourceButton iSourceButton = null;

	/**
	 * Create a new OsmMapControl
	 */
	public OsmMapControl(SlippyMapChooser navComp, JPanel contentPane, SizeButton sizeButton, SourceButton sourceButton) {
		this.iSlippyMapChooser = navComp;
		iSlippyMapChooser.addMouseListener(this);
		iSlippyMapChooser.addMouseMotionListener(this);

		String[] n = { ",", ".", "up", "right", "down", "left" };
		int[] k =
				{ KeyEvent.VK_COMMA, KeyEvent.VK_PERIOD, KeyEvent.VK_UP, KeyEvent.VK_RIGHT,
						KeyEvent.VK_DOWN, KeyEvent.VK_LEFT };

		if (contentPane != null) {
			for (int i = 0; i < n.length; ++i) {
				contentPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
						KeyStroke.getKeyStroke(k[i], KeyEvent.CTRL_DOWN_MASK),
						"MapMover.Zoomer." + n[i]);
			}
		}
		iSizeButton = sizeButton;
		iSourceButton = sourceButton;
	}

	/**
	 * Start drawing the selection rectangle if it was the 1st button (left
	 * button)
	 */
	@Override
	public void mousePressed(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			if (!iSizeButton.hit(e.getPoint())) {
				iStartSelectionPoint = e.getPoint();
				iEndSelectionPoint = e.getPoint();
			}
		}
		
	}

	public void mouseDragged(MouseEvent e) {		
		if((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) == MouseEvent.BUTTON1_DOWN_MASK){
			if (iStartSelectionPoint != null) {				
				iEndSelectionPoint = e.getPoint();
				iSlippyMapChooser.setSelection(iStartSelectionPoint, iEndSelectionPoint);
			}
		}
	}

	/**
	 * When dragging the map change the cursor back to it's pre-move cursor. If
	 * a double-click occurs center and zoom the map on the clicked location.
	 */
	@Override
	public void mouseReleased(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			
			int sourceButton = iSourceButton.hit(e.getPoint());
			
			if (iSizeButton.hit(e.getPoint())) {
				iSizeButton.toggle();
				iSlippyMapChooser.resizeSlippyMap();
			}
			else if(sourceButton == SourceButton.HIDE_OR_SHOW) {
				iSourceButton.toggle();
				iSlippyMapChooser.repaint();
				
			}else if(sourceButton == SourceButton.MAPNIK || sourceButton == SourceButton.OSMARENDER) {
				iSlippyMapChooser.toggleMapSource(sourceButton);
			}
			else {
				if (e.getClickCount() == 1) {
					iSlippyMapChooser.setSelection(iStartSelectionPoint, e.getPoint());

					// reset the selections start and end
					iEndSelectionPoint = null;
					iStartSelectionPoint = null;
				}
			}
			
		}
	}

	public void mouseMoved(MouseEvent e) {
	}

}
