//------------------------------------------------------[TG]
// Battle Ship
//
// Screens: 'welcome', 'new_game', 'instructions', 'high_scores'
// Ships: Minesweeper - {2}, Frigate - {3}, Cruiser - {4}, Battleship - {5}
//
//------------------------------------------------------[TG]

// Misc Functions --------------------------------------[TG]
var Misc = {
	ApplyStyle : function(MyObject, Styles) {
		for (var i in Styles) {
			MyObject.style[i] = Styles[i];
		}
	},
	Random : function(Min, Max) {
		return Min + Math.floor(Math.random() * (Max - Min));
	}
};
//------------------------------------------------------[TG]

// Ships -----------------------------------------------[TG]
var Ships = {
	'Minesweeper' : {
		'Length' : 2
	},
	'Frigate' : {
		'Length' : 3
	},
	'Cruiser' : {
		'Length' : 4
	},
	'Battleship' : {
		'Length' : 5
	}
};
//------------------------------------------------------[TG]

// Game Class ------------------------------------------[TG]
var GME = function(MyName, MyFieldID, MyOverlayID) {
	return {
		// Game Vars -------------------------------------------[TG]
		State		: 'Idle',
		Owner		: null,
		Screen		: null,
		Images		: null,
		Name		: MyName,
		Field		: null,
		FieldID		: MyFieldID,
		Overlay		: null,
		OverlayID	: MyOverlayID,
		FieldWidth	: 320,
		FieldHeight	: 356,
		Players		: null,
		Stats		: null,
		//------------------------------------------------------[TG]

		// Game Functions --------------------------------------[TG]
		Init : function(MyOwner) {
			this.Field		= document.getElementById(this.FieldID);
			this.Overlay	= document.getElementById(this.OverlayID);
			this.Owner		= (MyOwner == 'Player') ? 'Player' : 'Computer';

			if (this.Field == null || this.Overlay == null) {
				this.StopGame('Error: No field or Overlay.');
				return false;
			}
			this.Field.innerHTML = this.Overlay.innerHTML = '';
			
			var Styles = {
				position	: 'absolute',
				height		: this.FieldHeight + 'px',
				width		: this.FieldWidth + 'px',
				overflow	: 'hidden',
				top			: 0,
				left		: 0
			};
			Misc.ApplyStyle(this.Field, Styles);

			// Pre-Load Images
			this.Images = {};
			
			this.LoadImage(320, 356, '/img/e1/t1/battleship/msc_title.jpg');
			this.LoadImage(300, 30, '/img/e1/t1/battleship/msc_loading.gif');
			this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_water.gif');
			this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_water.hit.gif');
			this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_water.hit.still.gif');
			this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_explosion.gif');
			this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_explosion.still.gif');

			for (var i in Ships) {
				for (var x = 0; x < Ships[i].Length; x++) {
					this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_' + i.toLowerCase() + '.x.' + x + '.sit.gif');
					this.LoadImage(40, 40, '/img/e1/t1/battleship/npc_' + i.toLowerCase() + '.y.' + x + '.sit.gif');
				}
			}

			// Holders
			this.Players = [];

			// Stats
			this.Stats = {
				ShipsLeft : [],
				TotalShips : []
			};

			// Change Screen
			this.ChangeScreen('welcome');
		},
		LoadImage : function(Width, Height, URL) {
			if (!this.Images.Length)
				this.Images.Length = 0;

			this.Images.Length++;
			var This = this;
			var Temp = new Image(Width, Height);
				Temp.onload = function() { This.Loading(); };
				Temp.src = URL;
			
			if (!this.Images.Holder)
				this.Images.Holder = [];

			this.Images.Holder.push(Temp);
		},
		Loading : function() {
			if (!this.Images.Loaded)
				this.Images.Loaded = 0;

			this.Images.Loaded++;

			document.getElementById('Loading').style.backgroundPosition = parseInt((this.Images.Loaded / this.Images.Length) * 260) + 'px 0px';

			if (this.Images.Loaded == this.Images.Length)
				dom.$('Loading').parentNode.removeChild(dom.$('Loading'));
		},
		MakeField: function(Player) {
			this.Players[Player] = [];
			var ShowShips = (arguments[1]) ? arguments[1] : false;

			var FieldContainer = document.createElement('div');
				FieldContainer.Player	= Player;
				FieldContainer.id		= 'Player' + Player;

			for (var x = 0; x < 8; x++) {
				this.Players[Player][x] = [];
				for (var y = 0; y < 8; y++) {
					var Box = document.createElement('div');
					var Styles = {
						position	: 'absolute',
						height		: '40px',
						width		: '40px',
						overflow	: 'hidden',
						background	: '#FFEEEE url(/img/e1/t1/battleship/npc_water.gif) no-repeat',
						top			: 36 + (y*40) + 'px',
						left		: (x*40) + 'px'
					};
					Misc.ApplyStyle(Box, Styles);
					
					var This = this;
					Box.onclick = function() {
						if (this.Dead || this.parentNode.Player == 2 || This.State == 'Processing')
							return;

						This.ChangeState('Processing');

						if (this.Ship)
							This.Hit(this);
						else
							This.Miss(this);

						setTimeout('Game.ShowPlayer(2);', 1000);
						setTimeout('Game.RunAI();', 2000);
					}

					this.Players[Player][x][y] = Box;
					FieldContainer.appendChild(Box);
				}
			}
			this.Field.appendChild(FieldContainer);

			// Add Ships
			this.AddShip(Player, 'Minesweeper', ShowShips);
			this.AddShip(Player, 'Minesweeper', ShowShips);
//			this.AddShip(Player, 'Minesweeper', ShowShips);
//			this.AddShip(Player, 'Minesweeper', ShowShips);

			this.AddShip(Player, 'Frigate', ShowShips);
			this.AddShip(Player, 'Frigate', ShowShips);
//			this.AddShip(Player, 'Frigate', ShowShips);
//			this.AddShip(Player, 'Frigate', ShowShips);

			this.AddShip(Player, 'Cruiser', ShowShips);
//			this.AddShip(Player, 'Cruiser', ShowShips);
//			this.AddShip(Player, 'Cruiser', ShowShips);
			this.AddShip(Player, 'Cruiser', ShowShips);

//			this.AddShip(Player, 'Battleship', ShowShips);
			this.AddShip(Player, 'Battleship', ShowShips);
		},
		AddShip : function(Player, Type, ShowShip) {
			Ships[Type].Length;
			if (!this.Stats.TotalShips[Player]) {
				this.Stats.TotalShips[Player]	= 0;
				this.Stats.ShipsLeft[Player]	= 0;
			}

			this.Stats.TotalShips[Player]++;
			this.Stats.ShipsLeft[Player]++;

			var Info = this.FindPos(Player, Ships[Type].Length);
			for (var i = Info.Start; i < Info.End; i++) {
				if (Info.Direction == 'X') {
					this.Players[Player][i][Info.Offset].Direction	= Info.Direction;
					this.Players[Player][i][Info.Offset].Pos		= (i - Info.Start);
					this.Players[Player][i][Info.Offset].Ship		= Type;
					if (ShowShip) {
						this.Players[Player][i][Info.Offset].style.background = 'url(/img/e1/t1/battleship/npc_' + Type.toLowerCase() + '.' + Info.Direction.toLowerCase() + '.' + (i - Info.Start) + '.sit.gif)';
					}
				} else {
					this.Players[Player][Info.Offset][i].Direction	= Info.Direction;
					this.Players[Player][Info.Offset][i].Pos		= (i - Info.Start);
					this.Players[Player][Info.Offset][i].Ship		= Type;
					if (ShowShip) {
						this.Players[Player][Info.Offset][i].style.background = 'url(/img/e1/t1/battleship/npc_' + Type.toLowerCase() + '.' + Info.Direction.toLowerCase() + '.' + (i - Info.Start) + '.sit.gif)';
					}
				}
			}
		},
		RunAI : function() {
			var Pos = this.DamagedParts(2);
			if (!Pos) {
				var Pos = false;
				while (!Pos) {
					var RandX = Misc.Random(0, 8);
					var RandY = Misc.Random(0, 8);
					if (!this.Players[2][RandX][RandY].Dead) {
						Pos = {
							'X' : RandX,
							'Y' : RandY
						};
					}
				}
			}
			if (this.Players[2][Pos.X][Pos.Y].Ship) {
				this.Hit(this.Players[2][Pos.X][Pos.Y]);
			} else {
				this.Miss(this.Players[2][Pos.X][Pos.Y]);
			}
			setTimeout('Game.ShowPlayer(1);', 1000);
			this.ChangeState('Idle');
		},
		Hit : function(Section) {
			Section.Dead = true;
			Section.id = 'Temp';
			Section.style.background = 'url(/img/e1/t1/battleship/npc_' + Section.Ship.toLowerCase() + '.' + Section.Direction.toLowerCase() + '.' + Section.Pos + '.sit.gif)';
			Section.innerHTML = '<img src="/img/e1/t1/battleship/npc_explosion.gif" />';

			Player = Section.parentNode.id.replace('Player', '');

			setTimeout('document.getElementById("Temp").innerHTML = \'<img src="/img/e1/t1/battleship/npc_explosion.still.gif" />\'; document.getElementById("Temp").id = "";', 1000);

			this.Stats.ShipsLeft[Player] = this.Stats.TotalShips[Player] - this.ShipsSank(Player);
			if (!this.Stats.ShipsLeft[Player]) {
				this.ChangeState('Over');
				if (confirm( ((Player == 1) ? 'YOU WIN!' : 'YOU LOSE!') + '\nWould you like to play again?')) {
					location.href = location.href.replace('#', '');
				}
			}
		},
		Miss : function(Section) {
			Section.Dead = true;
			Section.id = 'Temp';
			Section.style.background = 'url(/img/e1/t1/battleship/npc_water.hit.gif)';
			setTimeout('document.getElementById("Temp").style.background = \'url(/img/e1/t1/battleship/npc_water.hit.still.gif)\'; document.getElementById("Temp").id = "";', 1000);
		},
		FindPos : function(Player, Length) {
			var RandX = Misc.Random(0, 8);
			var RandY = Misc.Random(0, 8);
			var RandD = (Misc.Random(1, 3) > 1) ? 'X' : 'Y';

			for (var i = 0; i < Length; i++) {
				if (RandD == 'X') {
					if (typeof(this.Players[Player][RandX + i]) == 'undefined' || this.Players[Player][RandX + i][RandY].Ship) {
						var Info = this.FindPos(Player, Length);
						break;
					}
				} else {
					if (typeof(this.Players[Player][RandX][RandY + i]) == 'undefined' || this.Players[Player][RandX][RandY + i].Ship) {
						var Info = this.FindPos(Player, Length);
						break;
					}
				}
			}
			if (!Info) {
				var Info = {
					Start		: eval('Rand' + RandD),
					End			: eval('Rand' + RandD) + Length,
					Direction	: RandD,
					Offset		: (RandD == 'X') ? RandY : RandX
				};
			}
			return Info;
		},
		DamagedParts : function(Player) {
			for (var x = 0; x < this.Players[Player].length; x++) {
				for (var y = 0; y < this.Players[Player][x].length; y++) {
					if (this.Players[Player][x][y].Dead && this.Players[Player][x][y].Ship) {
						var Part = 0;
						for (var i = 0; i < Ships[this.Players[Player][x][y].Ship].Length; i++) {
							if (this.Players[Player][x][y].Direction == 'X') {
								if (this.Players[Player][x + (i - this.Players[Player][x][y].Pos) ][y].Dead) {
									Part++;
								}
							} else {
								if (this.Players[Player][x][y + (i - this.Players[Player][x][y].Pos)].Dead) {
									Part++;
								}
							}
						}
						if (Part != Ships[this.Players[Player][x][y].Ship].Length) {
							for (var i = 0; i < Ships[this.Players[Player][x][y].Ship].Length; i++) {
								if (this.Players[Player][x][y].Direction == 'X') {
									if (!this.Players[Player][x + (i - this.Players[Player][x][y].Pos) ][y].Dead) {
										return { 'X' : (x + (i - this.Players[Player][x][y].Pos)), 'Y' : y };
									}
								} else {
									if (!this.Players[Player][x][y + (i - this.Players[Player][x][y].Pos)].Dead) {
										return { 'X' : x, 'Y' : (y + (i - this.Players[Player][x][y].Pos)) };
									}
								}
							}
						}
					}
				}
			}
			return false;
		},
		ShipsSank : function(Player) {
			var Types = {};
			for (var x = 0; x < this.Players[Player].length; x++) {
				for (var y = 0; y < this.Players[Player][x].length; y++) {
					if (this.Players[Player][x][y].Dead && this.Players[Player][x][y].Ship) {
						var Part = 0;
						for (var i = 0; i < Ships[this.Players[Player][x][y].Ship].Length; i++) {
							if (this.Players[Player][x][y].Direction == 'X') {
								if (this.Players[Player][x + (i - this.Players[Player][x][y].Pos) ][y].Dead) {
									Part++;
								}
							} else {
								if (this.Players[Player][x][y + (i - this.Players[Player][x][y].Pos)].Dead) {
									Part++;
								}
							}
						}
						if (Part == Ships[this.Players[Player][x][y].Ship].Length) {
							if (!Types[Ships[this.Players[Player][x][y].Ship].Length])
								Types[Ships[this.Players[Player][x][y].Ship].Length] = 0;

							Types[Ships[this.Players[Player][x][y].Ship].Length]++;
						}
					}
				}
			}
			var ShipsSank = 0;
			for (var i in Types) {
				ShipsSank += (Types[i] / i);
			}
			return ShipsSank;
		},
		ShowPlayer : function(Player) {
			for (var i = 0; i < this.Players.length; i++) {
				if (document.getElementById('Player' + i))
					document.getElementById('Player' + i).style.display = 'none';
			}
			if (document.getElementById('InfoBar')) {
				document.getElementById('InfoBar').innerHTML = (Player == 1) ? '<div class="Status">ATTACK!</div><div class="Left">' + this.Stats.ShipsLeft[Player] + '</div>' : '<div class="Status">DEFEND!</div><div class="Left">' + this.Stats.ShipsLeft[Player] + '</div>';
				document.getElementById('InfoBar').style.backgroundColor = (Player == 1) ? '#00FF00' : '#FF0000';
			}

			document.getElementById('Player' + Player).style.display = '';
		},
		//------------------------------------------------------[TG]

		// Stop Game -------------------------------------------[TG]
		StopGame : function(Error) {
			alert(Error);
			this.ChangeScreen('scores');
		},
		//------------------------------------------------------[TG]
		
		// Misc Functions --------------------------------------[TG]
		ChangeState: function(State) {
			switch (State) {
				case 'Idle':
				case 'Init':
				case 'Processing':
					this.State = State;
				break;

				case 'Over':
					this.State = State;
				break;
			}
		},
		ChangeScreen: function(Screen) {
			this.Screen = Screen;
			switch (Screen) {
				case 'new_game':
					this.ChangeState('Idle');
					this.MakeField(1);
					this.MakeField(2, true);
					this.ShowPlayer(1);
					if (document.getElementById('Loading'))
						document.getElementById('Loading').parentNode.removeChild(document.getElementById('Loading'));
					xh.loadSection(this.Overlay, '/battleship.' + Screen + '/');
				break;

				case 'enter_code':
				case 'instructions':
				case 'story':
				case 'welcome':
					xh.loadSection(this.Overlay, '/battleship.' + Screen + '/');
					this.ChangeState('Init');
				break;

				case 'scores':
					this.ChangeState('Over');
				break;
			}
		}
		//------------------------------------------------------[TG]
	};
}
//------------------------------------------------------[TG]