/*
 * Created on Apr 21, 2003
 *
 * To change this generated comment go to 
 * Window>Preferences>Java>Code Generation>Code Template
 */
package jdraw.std;

import java.awt.event.*;
import java.awt.*;
import jdraw.framework.*;

/**
 * @author Christoph
 */
public abstract class StdHandle implements Handle {
	protected static final int WIDTH  = 6;
	protected static final int HEIGHT = 6;
	protected static final String CENTEREDPROPORTIONAL = "Scale (centered and proportional) - ";
	protected static final String CENTERED = "Scale (centered) - ";
	protected static final String PROPORTIONAL = "Scale (preserve proportion) - ";
	protected static final String FREEHAND = "Scale (freehand) - ";

	protected Point anchor;
	protected Point center;
	protected double proportion;  // width/height
	
	protected final Figure owner;
	
	public StdHandle(Figure owner) {
		this.owner = owner;
	}
	
	public Figure getOwner(){
		return owner;
	}
	
	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#draw(java.awt.Graphics)
	 */
	public void draw(Graphics g) {
		java.awt.Rectangle h = getBounds();
		Color tmp = g.getColor();
		g.setColor(Color.WHITE);
		g.fillRect(h.x, h.y, h.width, h.height);
		g.setColor(Color.BLACK);
		g.drawRect(h.x, h.y, h.width, h.height);
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#getCursor()
	 */
	public Cursor getCursor() {
		return Cursor.getDefaultCursor();
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#contains(int, int)
	 */
	public boolean contains(int x, int y) {
		return getBounds().contains(x, y);
	}
	
	protected abstract Point getAnchor(java.awt.Rectangle r);

	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#startInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
	 */
	public void startInteraction(int x, int y, MouseEvent e, DrawView v) {
		java.awt.Rectangle r = getOwner().getBounds();
		center = new Point((int)r.getCenterX(), (int)r.getCenterY());
		proportion = (double)r.width/(double)r.height;
		anchor = getAnchor(r);
		showStatus(e, v);
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#dragInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
	 */
	public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
		showStatus(e, v);
	}

	/* (non-Javadoc)
	 * @see jdraw.framework.Handle#stopInteraction(int, int, java.awt.event.MouseEvent, jdraw.framework.DrawView)
	 */
	public void stopInteraction(int x, int y, MouseEvent e, DrawView v){
		v.getEditor().showStatus("");
	}

	private void showStatus(MouseEvent e, DrawView v) {
		String status;
		if (e.isAltDown() && e.isShiftDown()) status = CENTEREDPROPORTIONAL;
		if (e.isAltDown()) status = CENTERED;
		else if (e.isShiftDown()) status = PROPORTIONAL;
		else status = FREEHAND;
		v.getEditor().showStatus(status + "w = " + owner.getBounds().width + " h = " + owner.getBounds().height);
	}
	
	/**
	 * North Handle
	 */
	public static class North extends StdHandle {
		private int width; 	// at anchor point

		public North(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x+b.width/2-WIDTH/2, b.y-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			int nh;
			if (e.isAltDown() && e.isShiftDown()) { // centered & proportional
				nh = center.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), center.y+nh),
												new Point((int)(center.x+nw), y));
			} else if (e.isShiftDown()) { // centered
				nh = anchor.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(anchor.x-nw/2), anchor.y),
												new Point((int)(anchor.x+nw/2), y));
			} else if (e.isAltDown()) { // proportional
				nh = center.y - y;
				owner.setBounds(new Point(anchor.x-width/2, center.y+nh),
												new Point(anchor.x+width/2, y));
			} else {	// freehand
				owner.setBounds(new Point(anchor.x-width/2, anchor.y),
												new Point(anchor.x+width/2, y));
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			width = r.width;
			return new Point(r.x + r.width/2, r.y + r.height);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
		}

	}

	/**
	 * South Handle
	 */
	public static class South extends StdHandle {
		private int width; 	// at anchor point

		public South(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x+b.width/2-WIDTH/2, b.y+b.height-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			int nh;
			if (e.isAltDown() && e.isShiftDown()) {
				nh = y - center.y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), y),
												new Point((int)(center.x+nw), center.y-nh));
			} else if (e.isShiftDown()) { // proportional
				nh = y - anchor.y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(anchor.x-nw/2), y),
												new Point((int)(anchor.x+nw/2), anchor.y));
			} else if (e.isAltDown()) { // centered
				nh = y - center.y;
				owner.setBounds(new Point(anchor.x-width/2, y),
												new Point(anchor.x+width/2, center.y-nh));
			} else {
				owner.setBounds(new Point(anchor.x-width/2, anchor.y),
												new Point(anchor.x+width/2, y));
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			width = r.width;
			return new Point(r.x + r.width/2, r.y);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
		}

	}

	/**
	 * West Handle
	 */
	public static class West extends StdHandle {
		private int height; 	// at anchor point

		public West(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x-WIDTH/2, b.y+b.height/2-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			int nw;
			if (e.isAltDown() && e.isShiftDown()) {
				nw = center.x - x;
				double nh = (double)nw/proportion;
				owner.setBounds(new Point(x, (int)(center.y-nh)),
												new Point(center.x+nw, (int)(center.y+nh)));
			} else if (e.isShiftDown()) { // proportional
				nw = anchor.x - x;
				double nh = (double)nw/proportion;
				owner.setBounds(new Point(x, (int)(anchor.y-nh/2)),
												new Point(anchor.x, (int)(anchor.y+nh/2)));
			} else if (e.isAltDown()) { // centered
				nw = center.x - x;
				owner.setBounds(new Point(x, anchor.y-height/2),
												new Point(center.x+nw, anchor.y+height/2));
			} else {
				owner.setBounds(new Point(anchor.x, anchor.y-height/2),
												new Point(x, anchor.y+height/2));
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			height = r.height;
			return new Point(r.x + r.width, r.y+r.height/2);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
		}
	}

	/**
	 * East Handle
	 */
	public static class East extends StdHandle {
		private int height; 	// at anchor point

		public East(Figure owner) {
			super(owner);
		}

		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x+b.width-WIDTH/2, b.y+b.height/2-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			int nw;
			int nh;
			if (e.isAltDown() && e.isShiftDown()) {
				nw = x - center.x;
				nh = (int)(nw/proportion);
				owner.setBounds(new Point(x, center.y-nh),
												new Point(center.x-nw, (int)(center.y+nh)));
			} else if (e.isShiftDown()) { // proportional
				nw = x - anchor.x;
				nh = (int)(nw/proportion);
				owner.setBounds(new Point(x, anchor.y-nh/2),
												new Point(anchor.x, (int)(anchor.y+nh/2)));
			} else if (e.isAltDown()) { // centered
				nw = x - center.x;
				owner.setBounds(new Point(x, anchor.y-height/2),
												new Point(center.x-nw, anchor.y+height/2));
			} else {
				owner.setBounds(new Point(anchor.x, anchor.y-height/2),
												new Point(x, anchor.y+height/2));
			}
			super.dragInteraction(x,y,e,v);
		}
	
		protected Point getAnchor(java.awt.Rectangle r) {
			height = r.height;
			return new Point(r.x, r.y+r.height/2);
		}
	
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
		}
	}

	/**
	 * NorthEast Handle
	 */
	public static class NorthEast extends StdHandle {

		public NorthEast(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x+b.width-WIDTH/2, b.y-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			if (e.isAltDown() && e.isShiftDown()) {
				int nh = center.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), center.y+nh),
												new Point((int)(center.x+nw), y));
			} else if (e.isShiftDown()) { // proportional
				int nh = anchor.y - y;
				int nw = (int)(proportion*nh);
				owner.setBounds(anchor,
												new Point((int)(anchor.x+nw), y));
			} else if (e.isAltDown()) { // centered
				int nh = center.y - y;
				int nw = x - center.x;
				owner.setBounds(new Point(center.x+nw, center.y+nh),
												new Point(center.x-nw, center.y-nh));
			} else {
				owner.setBounds(anchor, e.getPoint());
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			return new Point(r.x, r.y + r.height);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
		}

	}

	/**
	 * NorthWest Handle
	 */
	public static class NorthWest extends StdHandle {

		public NorthWest(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x-WIDTH/2, b.y-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			if (e.isAltDown() && e.isShiftDown()) {
				int nh = center.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), center.y+nh),
												new Point((int)(center.x+nw), y));
			} else if (e.isShiftDown()) { // proportional
				int nh = anchor.y - y;
				int nw = (int)(proportion*nh);
				owner.setBounds(anchor,
												new Point(anchor.x-nw, y));
			} else if (e.isAltDown()) { // centered
				int nh = center.y - y;
				int nw = center.x - x;
				owner.setBounds(new Point(center.x+nw, center.y+nh),
												new Point(center.x-nw, center.y-nh));
			} else {
				owner.setBounds(anchor, e.getPoint());
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			return new Point(r.x + r.width, r.y + r.height);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
		}

	}

	/**
	 * SouthWest Handle
	 */
	public static class SouthWest extends StdHandle {

		public SouthWest(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x-WIDTH/2, b.y+b.height-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			if (e.isAltDown() && e.isShiftDown()) {
				int nh = center.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), center.y+nh),
												new Point((int)(center.x+nw), y));
			} else if (e.isShiftDown()) { // proportional
				int nh = anchor.y - y;
				int nw = (int)(proportion*nh);
				owner.setBounds(anchor,
												new Point(anchor.x+nw, y));
			} else if (e.isAltDown()) { // centered
				int nh = center.y - y;
				int nw = center.x - x;
				owner.setBounds(new Point(center.x+nw, center.y+nh),
												new Point(center.x-nw, center.y-nh));
			} else {
				owner.setBounds(anchor, e.getPoint());
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			return new Point(r.x + r.width, r.y);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
		}

	}

	/**
	 * SouthEast Handle
	 */
	public static class SouthEast extends StdHandle {

		public SouthEast(Figure owner) {
			super(owner);
		}
	
		public java.awt.Rectangle getBounds() {
			java.awt.Rectangle b = owner.getBounds();
			return new java.awt.Rectangle(b.x+b.width-WIDTH/2, b.y+b.height-HEIGHT/2, WIDTH, HEIGHT);
		}

		public void dragInteraction(int x, int y, MouseEvent e, DrawView v) {
			java.awt.Rectangle r = owner.getBounds();
			if (e.isAltDown() && e.isShiftDown()) {
				int nh = center.y - y;
				double nw = proportion*nh;
				owner.setBounds(new Point((int)(center.x-nw), center.y+nh),
												new Point((int)(center.x+nw), y));
			} else if (e.isShiftDown()) { // proportional
				int nh = anchor.y - y;
				int nw = (int)(proportion*nh);
				owner.setBounds(anchor,
												new Point(anchor.x-nw, y));
			} else if (e.isAltDown()) { // centered
				int nh = center.y - y;
				int nw = center.x - x;
				owner.setBounds(new Point(center.x+nw, center.y+nh),
												new Point(center.x-nw, center.y-nh));
			} else {
				owner.setBounds(anchor, e.getPoint());
			}
			super.dragInteraction(x,y,e,v);
		}
		
		protected Point getAnchor(java.awt.Rectangle r) {
			return new Point(r.x, r.y);
		}
		
		public Cursor getCursor() {
			return Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
		}

	}

}