class JGUtil {
	static getCenterPoint(p:CommonOffset):CommonOffset {
		var a = <CommonArea>p;
		if (a.width && a.height) {
			return {
				x: p.x + a.width / 2,
				y: p.y + a.height / 2
			}
		}
		return p;
	}

	static getMargin(p:CommonOffset):CommonOffset {
		var a = <CommonArea>p;
		if (a.width && a.height) {
			return {
				x: a.width / 2,
				y: a.height / 2
			}
		}
		return {x:0, y:0};
	}

	static intersect(p1:CommonOffset, p2:CommonOffset):bool {
		var a1 = <CommonArea>p1;
		var a2 = <CommonArea>p2;
		if (a1.width && a1.height) {
			if (a2.width && a2.height) {
				//area:area
				return a1.x <= (a2.x+a2.width) &&
				       a2.x <= (a1.x+a1.width) &&
				       a1.y <= (a2.y+a2.height) &&
				       a2.y <= (a1.y+a1.height);
			} else {
				//area:point
				return a2.x >= a1.x && a2.x <= (a1.x + a1.width)
				    && a2.y >= a1.y && a2.y <= (a1.y + a1.height);
			}
		} else if (a2.width && a2.height) {
			//point:area
				return a1.x >= a2.x && a1.x <= (a2.x + a2.width)
				    && a1.y >= a2.y && a1.y <= (a2.y + a2.height);
		}

		//point:point
		return p1.x == p2.x && p1.y == p2.y;
	}

	static getDistance(p1:CommonOffset, p2:CommonOffset):CommonOffset {
		var _p1 = JGUtil.getCenterPoint(p1);
		var _p2 = JGUtil.getCenterPoint(p2);
		return {
			x: Math.abs(_p1.x - _p2.x),
			y: Math.abs(_p1.y - _p2.y)
		}
	}

	static getMovePoint(p1:CommonOffset, p2:CommonOffset, power?:number, maxMove?:number):CommonOffset {
		var _p1 = JGUtil.getCenterPoint(p1);
		var _p2 = JGUtil.getCenterPoint(p2);

		if (! power)
			power = 1;
		var ret = {
			x: (_p1.x - _p2.x) * power,
			y: (_p1.y - _p2.y) * power
		}
		var absx = Math.abs(ret.x);
		var absy = Math.abs(ret.y);
		var max = Math.max(absx, absy);
		var xper = absx / max;
		var yper = absy / max;
		if (maxMove) {
			if (absx > maxMove || absy > maxMove) {
				if (ret.x < 0)
					ret.x = -maxMove * xper;
				else
					ret.x = maxMove * xper;
				if (ret.y < 0)
					ret.y = -maxMove * yper;
				else
					ret.y = maxMove * yper;
			}
		}
		return ret;
	}

	static getDirectionAngle(p1: CommonOffset, p2:CommonOffset, minDistance?:number):Angle {
		var _p1 = JGUtil.getCenterPoint(p1);
		var _p2 = JGUtil.getCenterPoint(p2);
		var xp = Math.abs(_p1.x - _p2.x);
		var yp = Math.abs(_p1.y - _p2.y);

		if (minDistance && Math.max(xp, yp) < minDistance)
			return null;

		if (xp > yp) {
			if (_p1.x > _p2.x) {
				return Angle.left;
			} else {
				return Angle.right;
			}
		} else {
			if (_p1.y > _p2.y) {
				return Angle.up;
			} else {
				return Angle.down;
			}
		}
	}

	static getDirectionKeytype(p1: CommonOffset, p2:CommonOffset, minDistance?:number):Keytype {
		var _p1 = JGUtil.getCenterPoint(p1);
		var _p2 = JGUtil.getCenterPoint(p2);
		var xp = Math.abs(_p1.x - _p2.x);
		var yp = Math.abs(_p1.y - _p2.y);

		if (minDistance && Math.max(xp, yp) < minDistance)
			return null;

		if (xp > yp) {
			if (_p1.x > _p2.x) {
				return Keytype.left;
			} else {
				return Keytype.right;
			}
		} else {
			if (_p1.y > _p2.y) {
				return Keytype.up;
			} else {
				return Keytype.down;
			}
		}
	}

	static homingX(p1:CommonOffset, p2:CommonOffset, speed:number, t:number):bool {
		var m1 = JGUtil.getMargin(p1);
		var m2 = JGUtil.getMargin(p2);
		var x = p2.x + m2.x - m1.x;
		if (p1.x > x) {
			p1.x -= speed * t;
			if (p1.x < x) {
				p1.x = x;
				return true;
			}
			return false;
		} else if (p1.x < x) {
			p1.x += speed * t;
			if (p1.x > x) {
				p1.x = x;
				return true;
			}
			return false;
		}
		return true;
	}

	static homingY(p1:CommonOffset, p2:CommonOffset, speed:number, t:number):bool {
		var m1 = JGUtil.getMargin(p1);
		var m2 = JGUtil.getMargin(p2);
		var y = p2.y + m2.y - m1.y;
		if (p1.y > y) {
			p1.y -= speed * t;
			if (p1.y < y) {
				p1.y = y;
				return true;
			}
			return false;
		} else if (p1.y < y) {
			p1.y += speed * t;
			if (p1.y > y) {
				p1.y = y;
				return true;
			}
			return false;
		}
		return true;
	}

	static homing(p1:CommonOffset, p2:CommonOffset, speed:number, t:number):bool {
		var m1 = JGUtil.getMargin(p1);
		var m2 = JGUtil.getMargin(p2);
		var p = {
			x: p2.x + m2.x - m1.x,
			y: p2.y + m2.y - m1.y
		}
		var xng, yng;
		if (p1.x > p.x) {
			p1.x -= speed * t;
			if (p1.x < p.x)
				p1.x = p.x;
			else
				xng = true;
		} else if (p1.x < p.x) {
			p1.x += speed * t;
			if (p1.x > p.x)
				p1.x = p.x;
			else
				xng = true;
		}

		if (p1.y > p.y) {
			p1.y -= speed * t;
			if (p1.y < p.y)
				p1.y = p.y;
			else
				yng = true;
		} else if (p1.y < p.y) {
			p1.y += speed * t;
			if (p1.y > p.y)
				p1.y = p.y;
			else
				yng = true;
		}

		return xng || yng ? false : true;
	}

}