// Functions specific to the Javascript implementation of gcset
// Generally, for the HTML user interface
// by David Turover, November 2003
// uses functions from spawn.js and rgb.js


// Global node pointers
var mwindow;
var lblock;
var rblock;
var mblock;

// arrays for timing out
var stimeout = new Array(SIDE_NUM_MAX);
stimeout[0] = new Array(SIDE_MAX_PER);
stimeout[1] = new Array(SIDE_MAX_PER);

var ytarget = 0;
var ytgtloc = 0;

var mshipID = 0;
var msideID = 0;


function shipFlak(id){
	var n = document.getElementById(id);
	n.setAttribute("src", "flak_2.png");
	triggers[id] = setTimeout("killNodeById(" + id + ")", 200);
}

function shipShowFire(fsideID, fshipID, tshipID){
	// show the firing effect between two ships
	var b = document.createElement("img");	// firing image
	var x = document.createElement("img");	// explosion image
	var sidec = "l";
	var dir = "u";
	var height = Math.abs(fshipID - tshipID);
	var top = 8;	// from top; initially height of border difference
	var tsideID = 1;
	var imgstr = "";

	if(fshipID >= tshipID){
		top += tshipID * 56;
	} else {
		top += fshipID * 56;
		dir = "d";
	}

	if(fsideID == 1){
		sidec = 'r';
		tsideID = 0;
	}
	imgstr = "shot_" + sidec + dir + height + ".png";
	//alert(imgstr);
	b.setAttribute("src", imgstr);
	b.style.position = "absolute";
	b.style.top = top + "px";
	b.style.margin = "0px";
	b.style.padding = "0px";
	b.style.height = 56 * (height + 1) + "px";
	b.style.width = "100px";

	spawnt(mblock, b, 1.5, "killNodeById");

	x.setAttribute("src", "flak_1.png");
	x.setAttribute("class", "shipImg");
	x.setAttribute("style", "z-index: 0");
	x.style.position = "absolute";
	spawnt(side[tsideID][tshipID].block, x, .3, "shipFlak");
}



function shipGetID(s){
	// Reverse-get ship's ID number from the ship pointer (hack)
	
	for(var i = 0; i < SIDE_MAX_PER; i++){
		if(s.block.parentNode.childNodes.item(i) == s.block){
			return i;
		}
	}
	return null;
}
function shipGetIDFromBlock(b){
	for(var i = 0; i < SIDE_MAX_PER; i++){
		if(b.parentNode.childNodes.item(i) == b){
			return i;
		}
	}
	return null;
}

function shipAttack(sideID, shipID){
	var targetShip;
	var targetLoc;
	var myShip;
	var xsideID = Math.abs(sideID - 1);
	if(isNaN(sideID) || sideID < 0 || sideID >= SIDE_NUM_MAX){
		alert("shipAttack: Bad side: " + sideID);
		return null;
	} else if (isNaN(shipID) || shipID < 0 || shipID >= SIDE_MAX_PER
		|| typeof(side[sideID][shipID]) == "undefined"){
		alert("shipAttack: Bad side/ship combination "
			+ sideID + ":" + shipID);
		return null;
	}
	myShip = side[sideID][shipID];
	if(myShip.enabled != 1){
		// Warning -- may be removed
		alert("Attempting to fire with disabled ship");
		return null;
	}

	if(sideID == 0 && shipID == 0){
		if(side[1][ytarget].enabled == 0){
			targetShip = sideShipGetNth(1,0);
			ytarget = 0;
		} else {
			targetShip = side[1][ytarget];
		}
		
		targetLoc  = ytgtloc + 1;
	} else {
		targetShip = shipAIGetTarget(sideID);
		targetLoc = shipAITargetLoc(myShip, targetShip);
	}
	
	//alert(targetShip.block.parentNode.getAttribute("id"));

	//alert("Target ship typeof is " + typeof(targetShip));
	if(typeof(targetShip) == "undefined"){
		alert("Could not find enemy ship to target");
		return null;
	}
	if(targetShip.enabled != 1){
		alert("Attempting to target disabled ship");
		return null;
	}


	var dmg = fire(myShip, targetShip, targetLoc);
	if(shipGetID(targetShip) == mshipID && sideID != msideID){
		dmgReport(dmg);
		setMeters();
	}
	shipShowFire(sideID, shipID, shipGetID(targetShip));
	shipSetStatus(xsideID, shipGetID(targetShip), dmg.starthits);

	// If the ship was killed, do away with the UI stuff for it
	if(targetShip.enabled != 1){
		clearTimeout(stimeout[xsideID][shipGetID(targetShip)]);
		killShip(targetShip.block);
	}
	// TODO: set to timeout at 1 second + 1 second / % of bridge left
	// TODO: Run the firing function;
	

	stimeout[sideID][shipID] = setTimeout("shipAttack("
		 + sideID + "," + shipID + ")",
		((750 * myShip.bridge_max) / myShip.bridge) + 2000);
	return targetShip;
}


function mkShipBlock(side){
// Create the ShipBlock div for a ship on the screen:
/*
<div class="shipBlock">
  <p class="shipStatus"/>
  <img class="shipImg"/>
</div>
*/
	var n = document.createElement("div");
	var i = document.createElement("img");
	n.setAttribute("class", "shipBlock");
	i.setAttribute("class", "shipImg");
	if(side == 'r'){
		i.setAttribute("src", "ship_r.png");
	} else {
		i.setAttribute("src", "ship_l.png");
	}
	n.appendChild(i);
	return n;
}

function shipStatusNode(ship){
// Retrieve the <p class="shipStatus"/> node
	if(ship){
		var l = ship.childNodes;
		for(var i = 0; i < l.length; i++){
			var n = l.item(i);
			if(n != null && n.getAttribute("class") == "shipStatus"){
				return n;
			}
		}
	}
	return null;
}


function shipSetStatus(sideID, shipID, amt){
	var block;
	if(sideID == 0){ block = lblock; }
	if(sideID == 1){ block = rblock; }
	setStatus(block.childNodes.item(shipID), amt);
}

function setStatus(shipDiv, amt){
	var n = shipStatusNode(shipDiv);
	if(n == null){
		n = document.createElement("p");
		n.setAttribute("class", "shipStatus");
	} else {
		if(!isNaN(parseInt(n.innerHTML))){
			amt += parseInt(n.innerHTML);
		}
		killNode(n);
  	 }
	n.innerHTML = amt;
	n.style.color = "#FF0000";
// Minor bug: If colour was not set as above, leaving the colour
// as inherited, additions to the text will not be reset the colour
// leaving it in a half-faded state.
	spawnt(shipDiv, n, .5, "fade");
}


// Meters:
var M_ARMOR = 0;
var M_ENGINE = 1;
var M_WEAPONS = 2;
var M_REACTOR = 3;
var M_BRIDGE = 4;
var M_OFFSET = 1; // Node offset of first status bar


function setStatusBar(barID, amt, max){
	var m = document.getElementById("meters");
	var i = parseInt(barID) + M_OFFSET;	// +1 for the header

	if(isNaN(i)){ alert("Bad status bar ID" + barID); return; }
	if(!m){ alert("Can't find meters div"); return; }
	var l = m.childNodes.item(i);
	if(!l){ alert("Could not find childNodes in setStatusBar()"); return; }
	l = l.firstChild;
	if(!l){ alert("Could not find child in setStatusBar()"); return; }
	//alert(l.innerHTML);
	l.style.width = parseInt(2 * (amt/max * 100)) + "px";
}

function setMeters(){
	if(typeof(side[msideID][mshipID]) != "undefined"){
		var s = side[msideID][mshipID];
		setStatusBar(0, s.armour, s.armour_max);
		setStatusBar(1, s.engine, s.engine_max);
		setStatusBar(2, s.weapons, s.weapons_max);
		setStatusBar(3, s.reactor, s.reactor_max);
		setStatusBar(4, s.bridge, s.bridge_max);
	}
}

function dmgReport(r){
	if(typeof(side[0][0]) == "undefined"){ return; }
	var s = side[0][0];
	var str =
		"Damage report: "
		+ r.starthits + " total damage   "
		+ r.armourhits + " to hull  "
		+ r.enghits + " to engines  "
		+ r.reachits + " to reactor  "
		+ r.gunhits + " to weapons systems  "
		+ r.bridhits + " to operations  ";
	window.status = str;
}

function setMeterStatus(shipNode){
	var n = document.getElementById("meter_header");
	var title = shipNode.getAttribute("shipName");

	// globals:
	msideID = 0;
	mshipID = shipGetIDFromBlock(shipNode);

	// Check for whether you are reading your own status
	if(shipNode.parentNode == rblock){
		// BUG: (minor): Says "targeting" when scanning
		// a disabled enemy ship.
		n.innerHTML = "Targeting: " + title;
		msideID = 1;
		ytarget = mshipID;
	} else {
		if(mshipID == 0){
			n.innerHTML = "Ship Status";
			setMeters(); 
		//	return; // Do not timeout! Will enter infinite loop
		} else {
			n.innerHTML = "Scanning: " + title;
		}
	}

	// Revert to own ship status after a time.
	setMeters(); 
	// timeout gets annoying, removed
	//setTimeout("setMeterStatus(lblock.childNodes.item(0))", 7500);
}

function addShip(side){
	var s = null;
	var block;

	if(side == 'r' && sideNumOn(1) < SIDE_MAX_PER){
		// alert(sideNumOn(1) + " on side 1");
		block = rblock.appendChild(mkShipBlock(side));
		s = sideAddShip(1, new Ship(new shipGenericCruiser()));
		block.setAttribute("shipName", "Enemy Ship " + sideNumOn(1));
	} else if(sideNumOn(0) < SIDE_MAX_PER) {
		//alert(sideNumOn(0) + " on side 0");
		block = lblock.appendChild(mkShipBlock(side));
		s = sideAddShip(0, new Ship(new shipGenericCruiser()));
		block.setAttribute("shipName", "Friendly Ship " + sideNumOn(0));
	}
	if(s){
		//alert("Enabled?" + s.enabled);
		s.block = block;	// Pointer to ship's div in UI
		//alert(s.block);
		//alert(s.block.parentNode.getAttribute("id"));
	}
	s.block.setAttribute("onclick", "setMeterStatus(this);");
	return s;
}




function killShip(shipDiv){
	// Remove the ship's UI etc from play
	var cside = 'l';
	if(shipDiv.parentNode == rblock){ cside = 'r'; }
		
	shipDiv.childNodes.item(0).setAttribute("src", "ship_" + cside + "_die1.png");
	//setTimeout("shipDiv.parentNode.removeChild(" + shipDiv + ")", 1500);
	// BUG: This gives Error: missing ] after element list

	// BUG: Death handling may be iffy. See if battles can continue

	// BUG: After all ships are destroyed, cannot refresh Mozilla
	// possibly hung somewhere

	if(sideNumOn(0) == 0){
		endgame();
		alert("Your side has been defeated!");
	}
	if(side[0][0].enabled == 0){
		endgame();
		alert("You have been defeated!");
	}
	if(sideNumOn(1) == 0){
		endgame();
		alert("Victory!");
	}
}

function endgame(){
	for (var i = 0; i <= SIDE_MAX_PER; i++){
		if(typeof(stimeout[0][i]) != "undefined"){
			clearTimeout(stimeout[0][i]); }
		if(typeof(stimeout[1][i]) != "undefined"){
			clearTimeout(stimeout[1][i]); } 
	}
}


function mylite(n){
	// HACK: replace '5' with number of nodes in a nodelist
	for(var i = 1; i <= 5; i++){
		n.parentNode.childNodes.item(i).style.backgroundColor = "inherit";
	}

	// BUG: This fails on Safari 1.0
	n.style.backgroundColor = "teal";
}




function init_all(){
	var ok = 0;
	var i = 0;
	var n = 0;
	// Initialize the node pointers
	mwindow=document.getElementById("mwindow");
	lblock=document.getElementById("lblock");
	rblock=document.getElementById("rblock");
	mblock=document.getElementById("mblock");

	// UI hack to keep this turned on by default
	document.getElementById("hack_01").style.backgroundColor="teal";

	// Add some ships
	i = 0;
	while(!ok){
		n = Math.floor(Math.random() * 5) + 1;
		ok = confirm("Battle with " + n + " ships on each side."
		+ "\nAccept?");
	}
	for(i=0; i<n; i++){
		addShip('l');
		addShip('r');
		stimeout[0][i] = setTimeout("shipAttack(0," + i + ")",250);
		stimeout[1][i] = setTimeout("shipAttack(1," + i + ")",250);
	}
}
