#include "_Global.h"

#include "Main.h"

/**
 * 敵
 */
class Enemy extends Object {
	var m;

	// コンストラクタ
	function Enemy(m, p1, p2, p3, p4, p5, p6) {
		this.m = m;
		create(p1, p2, p3, p4, p5, p6);
	}

	var _x, _y;					// 位置
	var _elapse = 0;			// 経過時間
//	function x() { return _x; }
//	function y() { return _y; }
//	function elapse() { return _elapse; }

	var _col = -1;			// ウェーブの色

	var _type;					// 種類
	var _attack;				// 攻撃の種類
	var _w;						// 大きさ
	var _tx, _ty;				// ターゲット位置
	var _sx, _sy;				// 槍の先端
	var _interval;				// ウェーブを発する間隔
	var _shed;					// ウェーブを発する時間
	var _damage = 0, m_damage;	// ダメージ
	var _direction;
	var _pattern;
	var _show;
	function create(x, y, type, interval, shed, damage) {
		if ( type < 4 ) {
			_type = ENEMY_0;
			_attack = type;
			_w = 32;
		} else {
			switch ( _DIV(type - 4, 4) ) {
			case 0: _type = ENEMY_1; _attack = SHOT_DIRECTION; _w = 26; break;
			case 1: _type = ENEMY_2; _attack = SHOT_TARGET   ; _w = 34; break;
			case 2: _type = ENEMY_3; _attack = SHOT_TARGET   ; _w = 26; break;
			case 3: _type = ENEMY_4; _attack = SHOT_CIRCLE   ; _w = 32; break;
			case 4: _type = ENEMY_5; _attack = SHOT_CIRCLE   ; _w = 34; break;
			case 5: _type = ENEMY_6; _attack = TOUCH         ; _w = 26; break;
			}
		}
		_x        = x;
		_y        = y;
		_interval = interval;
		_shed     = shed;
		m_damage  = damage;
		switch ( _type ) {
		case ENEMY_1:
		case ENEMY_2:
		case ENEMY_3:
			switch ( _MOD(type - 4, 4) ) {
			case 0: _direction = DIRECTION_D; _pattern = 0; break;
			case 1: _direction = DIRECTION_L; _pattern = 4; break;
			case 2: _direction = DIRECTION_R; _pattern = 4; break;
			case 3: _direction = DIRECTION_U; _pattern = 0; break;
			}
			break;
		case ENEMY_5:
			_pattern = 0;
			switch ( _MOD(type - 4, 4) ) {
			case 0: _direction = DIRECTION_LD; break;
			case 1: _direction = DIRECTION_LU; break;
			case 2: _direction = DIRECTION_RD; break;
			case 3: _direction = DIRECTION_RU; break;
			}
			break;
		case ENEMY_6:
			spear();
			_pattern = 0;
			break;
		}
		_show = false;
	}
//	function spear_x() { return _sx; }
//	function spear_y() { return _sy; }
//	function max_damage() { return m_damage; }
//	function damage(cnt) { _damage += cnt; if ( _damage >= m_damage ) _elapse = 0; }
//	function destroyed() { return (_damage < m_damage) ? false : true; }
	function move(w, target) {
		if ( target ) {
			var _cx = _x;
			var _cy = _y;
			var i;
			var e;
			var dx, dy, sx, sy;
			var _w = 0;
			var _h = 0;
			var d = w * w;
			sx = (_tx > _cx) ? 1 : -1;
			dx = (_tx > _cx) ? _tx - _cx : _cx - _tx;
			sy = (_ty > _cy) ? 1 : -1;
			dy = (_ty > _cy) ? _ty - _cy : _cy - _ty;
			_x = _cx;
			_y = _cy;
			if ( dx >= dy ) {
				e = -dx;
				for ( i = 0; i <= w; i++ ) {
					_x += sx;
					e += 2 * dy;
					if ( e >= 0 ) {
						_y += sy;
						e -= 2 * dx;
					}
					_w = _x - _cx;
					_h = _y - _cy;
					if ( (_w * _w + _h * _h) >= d ) {
						// 目標距離に達すると抜ける
						break;
					}
				}
			} else {
				e = -dy;
				for ( i = 0; i <= w; i++ ) {
					_y += sy;
					e += 2 * dx;
					if ( e >= 0 ) {
						_x += sx;
						e -= 2 * dy;
					}
					_w = _x - _cx;
					_h = _y - _cy;
					if ( (_w * _w + _h * _h) >= d ) {
						// 目標距離に達すると抜ける
						break;
					}
				}
			}
			_tx += _w;
			_ty += _h;
		} else {
			switch ( _direction ) {
			case DIRECTION_D : _y += w; _pattern--; if ( _pattern < 0 ) _pattern = 0; break;
			case DIRECTION_L : _x -= w; _pattern++; if ( _pattern > 4 ) _pattern = 4; break;
			case DIRECTION_R : _x += w; _pattern++; if ( _pattern > 4 ) _pattern = 4; break;
			case DIRECTION_U : _y -= w; _pattern--; if ( _pattern < 0 ) _pattern = 0; break;
			case DIRECTION_LD: _x -= w; _y += w; break;
			case DIRECTION_LU: _x -= w; _y -= w; break;
			case DIRECTION_RD: _x += w; _y += w; break;
			case DIRECTION_RU: _x += w; _y -= w; break;
			}
		}
	}
	function spear() {
		var _x0 = _x + 12;
		var _y0 = _y + 12;
		var _x1 = m.jiki_x + 12;
		var _y1 = m.jiki_y + 12;

		var i;
		var e;
		var dx, dy, sx, sy;
		var w, h;
		var d = 20 * 20;
		sx = (_x1 > _x0) ? 1 : -1;
		dx = (_x1 > _x0) ? _x1 - _x0 : _x0 - _x1;
		sy = (_y1 > _y0) ? 1 : -1;
		dy = (_y1 > _y0) ? _y1 - _y0 : _y0 - _y1;
		_sx = _x0;
		_sy = _y0;
		if ( dx >= dy ) {
			e = -dx;
			for ( i = 0; i <= 20; i++ ) {
				_sx += sx;
				e += 2 * dy;
				if ( e >= 0 ) {
					_sy += sy;
					e -= 2 * dx;
				}
				w = _sx - _x0;
				h = _sy - _y0;
				if ( (w * w + h * h) >= d ) {
					// 目標距離に達すると抜ける
					break;
				}
			}
		} else {
			e = -dy;
			for ( i = 0; i <= 20; i++ ) {
				_sy += sy;
				e += 2 * dx;
				if ( e >= 0 ) {
					_sx += sx;
					e -= 2 * dy;
				}
				w = _sx - _x0;
				h = _sy - _y0;
				if ( (w * w + h * h) >= d ) {
					// 目標距離に達すると抜ける
					break;
				}
			}
		}
	}
//	function pattern() { return _pattern; }
//	function set_show(flag) { _show = flag; }
//	function show() { return _show; }
//	function type() { return _type; }
//	function attack() { return _attack; }
//	function w() { return _w; }
	function update(stage_clear) {
		if ( _damage >= m_damage ) {
			// 時間だけは経過させる
			_elapse++;
		} else if ( !stage_clear ) {
			// 移動する
			if (
			(_type != ENEMY_0) && (_type != ENEMY_4) &&
			(_x >= m._win_x - 132) && (_x <= m._win_x + 324) &&
			(_y >= m._win_y - 132) && (_y <= m._win_y + 324)
			) {
				var old_x = _x;
				var old_y = _y;
				switch ( _type ) {
				case ENEMY_1: move(ENEMY_MOVE1, false); break;
				case ENEMY_2: move(ENEMY_MOVE2, false); break;
				case ENEMY_3:
					if ( _MOD(_elapse, 15) == 0 ) {
						if ( Math.abs(_x - m.jiki_x) > Math.abs(_y - m.jiki_y) ) {
							if ( _x > m.jiki_x ) _direction = DIRECTION_L; else _direction = DIRECTION_R;
						} else {
							if ( _y > m.jiki_y ) _direction = DIRECTION_U; else _direction = DIRECTION_D;
						}
					}
					move(ENEMY_MOVE3, false);
					break;
				case ENEMY_5:
					if ( _MOD(_elapse, 15) == 0 ) {
						switch ( _direction ) {
						case DIRECTION_LD:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LU; break;
							case  0: _direction = DIRECTION_RD; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_LU:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_RD; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_RD:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_LU; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_RU:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_LU; break;
							case  1: _direction = DIRECTION_RD; break;
							}
							break;
						}
						break;
					}
					move(ENEMY_MOVE3, false);
					break;
				case ENEMY_6:
					if ( _MOD(_elapse, 5) == 0 ) {
						_tx = m.jiki_x;
						_ty = m.jiki_y;
					}
					move(ENEMY_MOVE3, true);
					break;
				}
				if ( m.stage.hit(_x, _y) == BASE_KABE ) {
					// 元の位置に戻す
					_x = old_x;
					_y = old_y;

					// 方向転換
					switch ( _type ) {
					case ENEMY_1:
						switch ( _direction ) {
						case DIRECTION_D: _direction = DIRECTION_U; break;
						case DIRECTION_L: _direction = DIRECTION_R; break;
						case DIRECTION_R: _direction = DIRECTION_L; break;
						case DIRECTION_U: _direction = DIRECTION_D; break;
						}
						break;
					case ENEMY_2:
					case ENEMY_3:
						switch ( _direction ) {
						case DIRECTION_D:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_L; break;
							case  0: _direction = DIRECTION_R; break;
							case  1: _direction = DIRECTION_U; break;
							}
							break;
						case DIRECTION_L:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_D; break;
							case  0: _direction = DIRECTION_R; break;
							case  1: _direction = DIRECTION_U; break;
							}
							break;
						case DIRECTION_R:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_D; break;
							case  0: _direction = DIRECTION_L; break;
							case  1: _direction = DIRECTION_U; break;
							}
							break;
						case DIRECTION_U:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_D; break;
							case  0: _direction = DIRECTION_L; break;
							case  1: _direction = DIRECTION_R; break;
							}
							break;
						}
						break;
					case ENEMY_5:
						switch ( _direction ) {
						case DIRECTION_LD:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LU; break;
							case  0: _direction = DIRECTION_RD; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_LU:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_RD; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_RD:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_LU; break;
							case  1: _direction = DIRECTION_RU; break;
							}
							break;
						case DIRECTION_RU:
							switch ( m.rand.next(2) ) {
							case -1: _direction = DIRECTION_LD; break;
							case  0: _direction = DIRECTION_LU; break;
							case  1: _direction = DIRECTION_RD; break;
							}
							break;
						}
						break;
					case ENEMY_6:
						switch ( m.rand.next(3) ) {
						case -2: _tx = _x - 960; _ty = _y; break;
						case -1: _tx = _x + 960; _ty = _y; break;
						case  0: _tx = _x + (_x - m.jiki_x); _ty = _y + (_y - m.jiki_y); break;
						case  1: _tx = _x; _ty = _y - 960; break;
						case  2: _tx = _x; _ty = _y + 960; break;
						}
						break;
					}
				}
				if ( _type == ENEMY_6 ) {
					spear();
				}
			}

			// 攻撃する
			if (
			(_MOD(_elapse, _interval) == _shed) &&
			(_x >= m._win_x - 132) && (_x <= m._win_x + 324) &&
			(_y >= m._win_y - 132) && (_y <= m._win_y + 324)
			) {
				switch ( _attack ) {
				case RING_C:
				case RING_M:
				case RING_Y:
					m.ring.addElement(new Ring(m, _DIV(_x, 12) + 1, _DIV(_y, 12) + 1, _attack));
					break;
				case RING_RANDOM:
					{
						var tmp = m.rand.next(2) + 1;
						if ( tmp == _col ) {
							tmp++; if ( tmp > 2 ) tmp = 0;
						}
						_col = tmp;
						m.ring.addElement(new Ring(m, _DIV(_x, 12) + 1, _DIV(_y, 12) + 1, tmp));
					}
					break;
				case SHOT_DIRECTION:
					switch  ( _direction ) {
					case DIRECTION_D: m.shot.addElement(new Shot(m, _x + 8, _y + 8, _x + 8, 960)); break;
					case DIRECTION_L: m.shot.addElement(new Shot(m, _x + 8, _y + 8,   0, _y + 8)); break;
					case DIRECTION_R: m.shot.addElement(new Shot(m, _x + 8, _y + 8, 960, _y + 8)); break;
					case DIRECTION_U: m.shot.addElement(new Shot(m, _x + 8, _y + 8, _x + 8,   0)); break;
					}
					break;
				case SHOT_TARGET:
					m.shot.addElement(new Shot(m, _x + 8, _y + 8, m.jiki_x + 8, m.jiki_y + 8));
					break;
				case SHOT_CIRCLE:
					{
						var i;
						for ( i = 0; i < 12; i++ ) {
							m.shot.addElement(new Shot(m, _x + 8, _y + 8, _x + 8 + m.COS[i], _y + 8 + m.SIN[i]));
						}
					}
					break;
				}
			}

			_elapse++;
		}
	}
}
