morphinfo = {};
morphing = false;
last_path = [];
current_action = "";
build_func_to_unreg = "";
hud_size = 52;
process_cache = [];
gameStatusDelay = 1;
gameStatusReq = null;

initial_run = function() {
	var chatheight = 473-(parseInt($('user_list').readAttribute('players'))*27)-90;

	$('chat').setStyle({height: chatheight});
	$('map', 'map_grid').invoke('setStyle', { width: $game.mapDims.widthpx, height: $game.mapDims.heightpx }); //  backgroundImage: "url('"+private_map_image+"')",

	if ($game.status != "waiting") {
		map_move = new Draggable($('map_move'), {starteffect: false,endeffect: false,zindex: false,snap:map_move_snap}); // , { snap: unit_constrain }
		if (typeof $user != "undefined") gameStatus();
	}
	var testtesting = new reignMap();
	testtesting.setMap(map_grid);
	//$('map_container').ancestors()[0].insert({bottom: testtesting.findPath([16,20], [45,24]).toJSON() });
}

gameStatus = function() {
	gameStatusDelay = Math.min(Math.max(gameStatusDelay+0.5, 1), 5);
	gameStatusReq = new Ajax.Request("battle_ajax.php", {
		parameters: {game_status: 1, gameid: $game.id, turn: $game.turn},
		onSuccess: function(tr) {
			if (tr.responseText == "1") {
				location.reload(true);
			}
			else {
				gameStatus.delay(2);
			}
		}
	});
}

reignMap = function () {
	this.map = [],
		this._systems = ["simple"], // ,"euclidean"
		this.system = 1, // array index of this.sytems
		this.obeyCorners = true,
		this.cols = this.rows = 0;

	this.getPoint = function(x,y) { return (this.map[y][x] === 0); };

	this.setPoint = function(x,y,bin) { this.map[y][x] = (bin ? true : false); };

	this.setMap = function(m) { if (typeof m == "object") { this.map = m;this.rows = m.length;this.cols = m[0].length; }; };

	this.setSystem = function(sys) {
		var sys = sys.toLowerCase();
		for (var i=0;i<this._systems.length;i++) {
			if (this_systems[i] == sys) { this.system = i;break; };
		};
	};

	this.createNode = function(p, xy) { //parentNode, [x,y]
		return {
			parentNode:p,
			x:xy[0],
			y:xy[1],
			g:0,
			h:1,
			f:0,
			v:(xy[0] + (xy[1]*this.cols))
		};
	};

	this.findPath = function(start,end) {
		var _start = this.createNode(null, start),
			_end = this.createNode(null, end),
			_off = _locs = [],
			_r_, _dr = (this.rows*this.cols),
			i, j, k, z, _path = {}; // range
		if ((typeof this.map[_start.y] == 'undefined') || (typeof this.map[_end.y] == 'undefined')) return [];
		if ((this.map[_start.y][_start.x] != 0) || (this.map[_end.y][_end.x] != 0)) return [];

		var moreHorizontal = Math.abs(_end.x - _start.x) - Math.abs(_end.y - _start.y);





		if ((_off.length == 0) && (moreHorizontal != 0)) { // first run
			_cur = _start;
			if (moreHorizontal > 0) {
				while (_cur.x < _end.x) {
					if (this.getPoint(_cur.x+1, _cur.y)) {
						_path = this.createNode(_cur, [_cur.x+1, _cur.y]);
						_path.g = _cur.g + 1; // (Math.abs(_path.x - _cur.x) + Math.abs(_path.y - _cur.y))
						_path.h = Math.abs(_path.x - _end.x) + Math.abs(_path.y - _end.y); //_path.l = Math.sqrt(Math.pow(_path.x - _end.x,2) + Math.pow(_path.y - _end.y,2));
						_path.f = (_path.h == 0) ? 0 : (_path.g + _path.h); // this may be slow?
						_locs[_path.v] = true;

						_off.push(_cur);
						//$('map').insert({bottom: "<div style='position:absolute;top:"+(_cur.y*11)+"px;left:"+(_cur.x*11)+";width:11px;height:11px;opacity:0.33;background-color:#E0E0E0;'><!-- --></div>"});
						_cur = _path;
					}
					else break;
				}
			}
			else {
				while (_cur.y < _end.y) {
					if (this.getPoint(_cur.x, _cur.y+1)) {
						_path = this.createNode(_cur, [_cur.x, _cur.y+1]);
						_path.g = _cur.g + 1; // (Math.abs(_path.x - _cur.x) + Math.abs(_path.y - _cur.y))
						_path.h = Math.abs(_path.x - _end.x) + Math.abs(_path.y - _end.y); //_path.l = Math.sqrt(Math.pow(_path.x - _end.x,2) + Math.pow(_path.y - _end.y,2));
						_path.f = (_path.h == 0) ? 0 : (_path.g + _path.h); // this may be slow?
						_locs[_path.v] = true;

						_off.push(_cur);
						//$('map').insert({bottom: "<div style='position:absolute;top:"+(_cur.y*11)+"px;left:"+(_cur.x*11)+";width:11px;height:11px;opacity:0.33;background-color:#E0E0E0;'><!-- --></div>"});
						_cur = _path;
					}
					else break;
				}
			}
			var _on = [_cur];
		}
		else var _on = [_start];
		while (z = _on.length) {
			_r_ = [-1, _dr];
			for (i = 0; i < z; i++) {
				if (_on[i].f < _r_[1]) {
					_r_[0] = i;
					_r_[1] = _on[i].f; 
					//$('map_container').ancestors()[0].insert({bottom: _on[i].x+":"+_on[i].y+" _"+_on[i].f+"<br />"});
				};
			};

			_cur = _on.splice(_r_[0], 1)[0];
			if (_cur.v == _end.v) { // compare int val
				_path = _off[_off.push(_cur) - 1];
				var _route = [];
				do { _route.push([_path.x, _path.y]); } while(_path = _path.parentNode);
				_start = _end = _on = _off = _locs = [];
				return _route.reverse();
			}

			_off.push(_cur);
			var _nearby = this.nearby(_cur.x, _cur.y);
			for (i=0,j=_nearby.length;i<j;i++) {
				_path = this.createNode(_cur, _nearby[i]);
				if (!_locs[_path.v]) {
					_path.g = _cur.g + 1; // (Math.abs(_path.x - _cur.x) + Math.abs(_path.y - _cur.y))
					_path.h = Math.abs(_path.x - _end.x) + Math.abs(_path.y - _end.y); //_path.l = Math.sqrt(Math.pow(_path.x - _end.x,2) + Math.pow(_path.y - _end.y,2));
					_path.f = (_path.h == 0) ? 0 : (_path.g + _path.h); // this may be slow?
					_locs[_path.v] = true;
					_on.push(_path);
				};
			};
			//$('map').insert({bottom: "<div style='position:absolute;top:"+(_cur.y*11)+"px;left:"+(_cur.x*11)+";width:11px;height:11px;opacity:0.33;background-color:#E0E0E0;'><!-- --></div>"});
		};
		return [];
	};
	this.nearby = function(x, y){
		var N = y-1,
			S = y + 1,
			E = x + 1,
			W = x - 1,
			$N = N > -1 && this.getPoint(x, N),
			$S = S < this.rows && this.getPoint(x, S),
			$E = E < this.cols && this.getPoint(E, y),
			$W = W > -1 && this.getPoint(W, y),
			result = [];
		if($N) result.push([x, N]); // x,y
		if($E) result.push([E, y]);
		if($S) result.push([x, S]);
		if($W) result.push([W, y]);
		//__($N, $S, $E, $W, N, S, E, W, result);
		return result;
	};
};

if (typeof document != "undefined") {
	document.observe('dom:loaded', function() {
		initial_run();
	});
}
map_move_snap = function(x,y,inst) { // inst.element is the element being moved, but should always be ID map_move
	var xMax = $game.view.width-$game.mapDims.widthpx; // use PHP, width
	var yMax = $game.view.height-$game.mapDims.heightpx; // use PHP, height

	var xNow = ((x>0) ? 0 : ((x < xMax) ? xMax : x));
	var yNow = ((y>0) ? 0 : ((y < yMax) ? yMax : y));

	return [xNow,yNow];
};

toggleSidebar = function(element) {
	var isvisible = $('sidebar').visible();
	$('sidebar').toggle();
	$game.view.width = isvisible ? '908' : '720';
	$('map_container').style.width = isvisible ? '908px' : '720px';

	if (isvisible) {
		var snapto = map_move_snap((720/2),($game.view.height/2))
		//this isn't right!
		$('map_move').style.left = snapto[0];
		$('map_move').style.top = snapto[1];
	}

	var children = element.childElements();
    children[0].setStyle({backgroundPosition: (isvisible ? "-59px" : "-56px")+" top"});
};

closestCirclePoint = function(px, py, x, y, ray){
    var tg = (x += ray, y += ray, 0);

    return function(x, y, x0, y0){return Math.sqrt((x -= x0) * x + (y -= y0) * y);}(px, py, x, y) > ray ?
		{x: Math.cos(tg = Math.atan2(py - y, px - x)) * ray + x, y: Math.sin(tg) * ray + y}
		//{x: (px - x) / (length / ray) + x, y: (py - y) / (length / ray) + y}
		: {x: px, y: py};
};

GridGenerator = function(width, height, water_area) {
	var result = new Array(height);

	for(var	j, i = 0; i < height; i++) {
		result[i] = new Array(width);

		for(j = 0; j < width; j++) {
			result[i][j] = 0;

			if (typeof water_area["x"+j] != "undefined") {
				for (var k = 0,z=water_area["x"+j].length; ((k < z) && (result[i][j] == 0)); k++) {
					result[i][j] = ( (water_area["x"+j][k][0] <= i) && (water_area["x"+j][k][1] >= i) ) ? 1 : 0;
				}
			}

		}
	}

	return result;
};

if (typeof $game != "undefined") {
	var map_grid = GridGenerator($game.mapDims.width,$game.mapDims.height, water_area);
}
//var bench = (new Date()).getTime(), map_grid = GridGenerator(mapDims.width,mapDims.height), endTime = (new Date()).getTime() - bench;alert (endTime);
/*blah = "";
for (var j = 0,k=map_grid.length; j < k; j++) {
	for (var k = 0,l=map_grid[j].length; k < l; k++) { blah = blah+""+map_grid[j][k]; }
blah = blah+"\n";
}
alert (blah);*/


unit_constrain = function(x,y, inst) {
	var pdims = {width: $game.widthpx, height: $game.heightpx};
	var useid = inst.element.readAttribute('objectid');
	var edims = {width: parseInt($allobjects[useid].width), height: parseInt($allobjects[useid].height)};
	var xMax = pdims.width-edims.width;
	var yMax = pdims.height-edims.height;

	x = x<0 ? 0 : (x>xMax ? xMax : x);
	y = y<0 ? 0 : (y>yMax ? yMax : y);

	var cx = inst.element.readAttribute("startx")-(edims.width/2);
	var cy = inst.element.readAttribute("starty")-edims.height;
	var speed = (inst.element.readAttribute("speed")*11)-1;
	var distance = Math.sqrt(Math.pow((x - cx),2) + Math.pow((y - cy),2));

	if (distance >= speed) {
		var ddee = closestCirclePoint(x,y,(cx-speed),(cy-speed),speed);
		var xNow = ddee.x;
		var yNow = ddee.y;
	}
	else { var xNow = x;var yNow = y; }

	var xgrid = Math.floor((xNow+(edims.width/2))/11);
	var ygrid = Math.floor((yNow+edims.height)/11);

	if (map_grid[ygrid][xgrid] == 1) {
			var defxy = Element.positionedOffset(inst.element);
			xNow = defxy.left;
			yNow = defxy.top;
	}

	if (morphing) {
		xNow = Math.floor(xNow/11)*11;
		yNow = Math.floor(yNow/11)*11;
		var distance = Math.sqrt(Math.pow((x - cx),2) + Math.pow((y - cy),2));
		if (distance >= speed) {
			var ddee = closestCirclePoint(x,y,(cx-speed),(cy-speed),speed);
			xNow = Math.floor(ddee.x/11)*11;
			yNow = Math.floor(ddee.y/11)*11;
		}
	}

	if (process_cache.length > 0) {
		for (var i=0,j=process_cache.length;i < j;i++) {
			var par = { objectid: process_cache[i].readAttribute("objectid"), y: parseInt(process_cache[i].readAttribute("starty")), x: parseInt(process_cache[i].readAttribute("startx")) };

			// We need to do this 2 different ways for structures/units that are in the way
			if (((yNow+edims.height) > (par.y-$allobjects[par.objectid].height)) && ((yNow+(edims.height/2)) < par.y)) {
				if (((xNow+edims.width) > (par.x-($allobjects[par.objectid].width/2))) && (xNow < (par.x+($allobjects[par.objectid].width/2)))) {
					var defxy = Element.positionedOffset(inst.element);
					xNow = defxy.left;
					yNow = defxy.top;
					break;
				}
			}

		}
	}

	return [xNow,yNow];
};


unit_moved = function(inst) {
	var startX = inst.element.readAttribute("startx"),
		startY = inst.element.readAttribute("starty"),
		useid = inst.element.readAttribute("objectid"),
		endXY = Element.positionedOffset(inst.element);
	var edims = {width: parseInt($allobjects[useid].width), height: parseInt($allobjects[useid].height)};

	var theX = endXY.left+(edims.width/2), theY = endXY.top+edims.height; // center of bottom
	startX = Math.floor(startX/11);
	startY = Math.floor(startY/11);
	endX = Math.floor(theX/11);
	endY = Math.floor(theY/11);

	//popup("<br><br><br>Move attempt: [water? "+map_grid[endY][endX]+"] start ["+startX+","+startY+"] - end ["+theX+","+theY+"] ["+endX+","+endY+"]");

	if (map_grid[endY][endX] == 0) {
		if (map_grid[startY][startX] == 0) var blah = AStar(map_grid, [startX,startY], [endX,endY], "Manhattan");
		else var blah = [1];
	}
	else var blah = [];

	if (blah.length == 0) {
		popup("<br>No path from "+inst.element.readAttribute("startx")+"px,"+inst.element.readAttribute("starty")+"px to "+theX+"px,"+theY+"px");
		inst.element.style.top = (inst.element.readAttribute("starty")-edims.height)+"px";
		inst.element.style.left = (inst.element.readAttribute("startx")-(edims.width/2))+"px";
	}
	else {
		last_path = blah;
        var newZ = Math.floor((theY*2000)+theX);
        inst.options.zindex = false; // scriptaculous disable zindex reset
        inst.element.style.zIndex = newZ;
		/*blah2 = "";
		for (var x, y, i = 0, j = blah.length; i < j; i++) {
			x = blah[i][0];
			y = blah[i][1];
			blah2 += x+","+y+"\n<br/>";
		}
		$('logger').innerHTML = "Path:"+blah2;*/
	}
};

unit_select = function(element) {
	if (typeof unit_selected !== "undefined") {
		if (unit_selected != null) {
        	if (current_action == "attack") {

				if ($user.id != element.readAttribute('uid')) {
					var x = element.readAttribute('startx'), y = element.readAttribute('starty');
                    var cx = unit_selected.element.readAttribute('startx'), cy = unit_selected.element.readAttribute('starty');
					var distance = Math.sqrt(Math.pow((x - cx),2) + Math.pow((y - cy),2));
					var speed = unit_selected.element.readAttribute("range")*11;

					if (distance <= speed) {
						new Ajax.Request("battle_ajax.php", {
							parameters: {unit_attack: 1, game_id: $game.id, unitid: unit_selected.element.readAttribute('unitid'), defender: element.readAttribute('unitid')},
							onSuccess: function(tr) {
								var re = eval("("+tr.responseText+")");

								if (re.success == 1) {
									element.writeAttribute("attacked", 1);

									if (typeof re.killed != "undefined") {
										for (var i=0,j=re.killed;i < j;i++) { // should this be .length?  Or is it an object?  Not sure, FIXME
											if ($("unit_"+re.killed[i])) $("unit_"+re.killed[i]).remove();
											alert("You killed the unit!");
										}
									}
									else {
										var msg = "You did "+re.damage+" damage.";
										if (parseInt(re.critical) > 0) { msg += " Critical hit (+"+re.critical+")!";
										msg += " You did "+re.total+" total damage!"; }
										alert(msg);
									}

								}
								else {
									popup('<br>'+re.error);
								}
							}
						});

						return true;
					}
                    else alert("Unable to attack, too far!");
				}
			}

			if (current_action == "move" || current_action == "build") unit_cancelmove();
			unit_unselect();
		}
	}


	var element = $(element);
	element.onclick = function () { };

	var useid = element.readAttribute('objectid');
	var classnames = $w(element.className);
	var hud_top = (hud_size-parseInt($allobjects[useid].imgheight))/2;

	$("hud_unit").className = classnames[0]; // the unit name has to be the first class!
	$("hud_unit").setStyle({top: hud_top+"px"});

	var unitimg = $("hud_unit").getElementsByClassName('unitimg');
	var unitimg2 = element.getElementsByClassName('unitimg');
	unitimg[0].setStyle({backgroundPosition: unitimg2[0].getStyle('backgroundPosition')});

	$("hud_unit_name").setStyle({left: (parseInt($allobjects[useid].imgwidth)+15)+"px"});
	$("hud_unit_name").innerHTML = $allobjects[useid].name;
	$('hud_unit_hp').setStyle({top: (parseInt($allobjects[useid].height)-7)}); //element.getHeight()

	var huhpe = $('hud_unit_hp').childElements(); // not nodes!
	var unit_hp = element.readAttribute("hp");

	huhpe[0].className = (unit_hp.length > 1) ? "hp"+unit_hp.substr(0,1)+"l" : "hpblankl" ;
	huhpe[1].className = (unit_hp.length > 1) ? "hp"+unit_hp.substr(1,1)+"r" : "hp"+unit_hp.substr(0,1)+"r";

	$("hud_unit").show();
	$("hud_unit_name").show();

	if ((typeof $user != "undefined") && ($game.turn == $user.id) && ($user.id == element.readAttribute('uid'))) {

		if (parseInt($allobjects[useid].attack_max) > 0) {
			$("hud_attack").observe("click", action_attack);
			$("hud_attack").show();
		}

		var is_moved = element.readAttribute("moved");

		if (($allobjects[useid].type != 'str') && (is_moved != "1")) {
			unit_move(element);
			if (useid == 1) {
				build_func_to_unreg = buildStructures;
				$("hud_build").observe("click", build_func_to_unreg);
				$("hud_build").show();
			}
		}
		else { unit_selected = {element: element}; }
		if (useid == 2 && is_moved != "1") {
				build_func_to_unreg = buildUnits;
				$("hud_build").observe("click", build_func_to_unreg);
				$("hud_build").show();
		}
	}
	else { unit_selected = {element: element}; }
};

str_select = function(element) { unit_select(element); };

unit_attack = function() {
};

unit_move = function(element) {
	var allunits = $$('#map div[aunit="1"]'),
		useid = element.readAttribute('objectid');
	var edims = {width: parseInt($allobjects[useid].width), height: parseInt($allobjects[useid].height)},
		xypos = {x: parseInt(element.readAttribute("startx")), y: parseInt(element.readAttribute("starty"))},
		uspeed = parseInt(element.readAttribute("speed"));

	process_cache = [];

	for (var i=0,j=allunits.length;i < j;i++) {
		if (allunits[i] == element) continue;
		//var unitid = allunits[i].readAttribute("objectid");
		// 22 instead of 11 because we're not calculating exact units to process, only estimating
        // this really should calculate the comparison figure (2nd half of if statement) 1 time before the foreach
		if (allunits[i].readAttribute("startx") < (xypos.x-(uspeed*22))) continue;
		if (allunits[i].readAttribute("startx") > (xypos.x+(uspeed*22))) continue;
		if (allunits[i].readAttribute("starty") < (xypos.y-(uspeed*22))) continue;
		if (allunits[i].readAttribute("starty") > (xypos.y+(uspeed*22))) continue;
		process_cache.push(allunits[i]);
	}

	$("unit_selector").setStyle({ top: (xypos.y-(uspeed*11)), left: (xypos.x-(uspeed*11)) });
	$("unit_selector").className = "selected"+uspeed;

	$("move_actions").show();
	$("hud_move").show();
	$("unit_selector").show();

	set_action('move');
	unit_selected = new Draggable(element.id, { onEnd: unit_moved, snap: unit_constrain });
};

action_attack = function() {
	if (current_action == "move" || current_action == "build") unit_cancelmove();
	set_action('attack');
};

action_move = function() {
	unit_move(unit_selected.element);
};

buildStructures = function() {
	var keys = Object.keys($allobjects);
	var keylen = keys.length,
		fromright = fromy = 0;

	$("hud_build_list").innerHTML = "";

	for (var i = 0;i < keylen;i++) {
		if ($allobjects[keys[i]].type == 'str') {
			var fromx = $allobjects[keys[i]].imgleft+"px",
				fromy = $allobjects[keys[i]].imgheight*($user.color*-1)+"px",
				makeel = document.createElement('div'),
				makeel2 = document.createElement('div');

			makeel.id = "build_unit_"+keys[i];
			makeel.onclick = function() { build_morph(this) }.bindAsEventListener(makeel);
			makeel.writeAttribute('objectid', $allobjects[keys[i]].id);
			makeel.className = $allobjects[keys[i]].name+" msel";
			makeel.setStyle({position: 'absolute', right: fromright+"px", top: 0});


			makeel2.className = 'unitimg';
			makeel2.style.backgroundPosition = fromx+" "+fromy;
			makeel.appendChild(makeel2);

			$("hud_build_list").appendChild(makeel);
			fromright = fromright+parseInt($allobjects[keys[i]].imgwidth)+2;
		}
	}

	$("hud_actions").hide();
	$("hud_build_list").show();
	set_action('build');
};

queue_unit = function(element) {
	var unitid = element.readAttribute("objectid");

	new Ajax.Request("battle_ajax.php", {
		parameters: {unit_build: 1, gameid: $game.id, unitid: element.readAttribute("source"), objectid: unitid},
		onSuccess: function(tr) {
			var re = eval("("+tr.responseText+")");
			if (parseInt(re.success) == re.success) {
				var useelement = unit_selected.element;
				useelement.writeAttribute("moved", 1);
				unit_unselect();
				popup(re.message);
/*				var element = $("unit_"+re.unitid);
				element.writeAttribute("hp", re.hp);
				element.onmouseover = function() { unit_hover(this,true); }.bindAsEventListener(element);
				element.onclick = function() {}; // add something for this for this structure?
				*/
			}
			else {
				popup('<br>'+re.error);
				unit_cancelmove();
			}
		}
	});
};

buildUnits = function() {
	var keys = Object.keys($allobjects);
	var keylen = keys.length,
		fromright = 0;

	$("hud_build_list").innerHTML = "";

	for (var i = 0;i < keylen;i++) {
		if ($allobjects[keys[i]].type != 'str') {
			var fromx = $allobjects[keys[i]].imgleft+"px",
				fromy = $allobjects[keys[i]].imgheight*($user.color*-1)+"px",
				makeel = document.createElement('div'),
				makeel2 = document.createElement('div');

			makeel.id = "build_unit_"+keys[i];
			makeel.onclick = function() { queue_unit(this) }.bindAsEventListener(makeel);
			makeel.writeAttribute('source', unit_selected.element.readAttribute("unitid"));
			;makeel.writeAttribute('objectid', $allobjects[keys[i]].id);
			makeel.className = $allobjects[keys[i]].name+" msel";
			makeel.setStyle({position: 'absolute', right: fromright+"px", top: 0});

			makeel2.className = 'unitimg';
			makeel2.style.backgroundPosition = fromx+" "+fromy;
			makeel.appendChild(makeel2);

			$("hud_build_list").appendChild(makeel);
			//$("hud_build_list").innerHTML += "<div id='build_unit_"+keys[i]+"' onclick='build_morph(this)' objectid='"+$allobjects[keys[i]].id+"' class='"+$allobjects[keys[i]].name+" msel' style='position:absolute;right:"+fromright+"px;top:0;'><div class='unitimg'></div></div>";
			fromright = fromright+parseInt($allobjects[keys[i]].width)+2;
		}
	}

	$("hud_actions").hide();
	$("hud_build_list").show();
	set_action('build');
};

set_action = function(action, opt) {
	$('hud_build').writeAttribute("isselected", "false");
	$('hud_attack').writeAttribute("isselected", "false");
	$('hud_move').writeAttribute("isselected", "false");

	$('hud_move').setStyle({backgroundPosition: "left top"});
	$('hud_attack').setStyle({backgroundPosition: "-27px top"});

	switch (action) {
		case 'build':
			current_action = "build";
		break;

		case 'attack':
			current_action = "attack";
            $('hud_attack').setStyle({backgroundPosition: "-27px -27px"});
            $('hud_attack').writeAttribute("isselected", "true");
			$("unit_selector").setStyle({
				top: (parseInt(unit_selected.element.readAttribute("starty"))-(parseInt(unit_selected.element.readAttribute("range"))*11)),
				left: (parseInt(unit_selected.element.readAttribute("startx"))-(parseInt(unit_selected.element.readAttribute("range"))*11)),
				display: 'block'
			});
			$('unit_selector').className = 'attack'+unit_selected.element.readAttribute('range');
		break;

		case 'move':default:
			current_action = "move";
            $('hud_move').setStyle({backgroundPosition: "left -27px"});
            $('hud_move').writeAttribute("isselected", "true");
		break;
	}
};

build_morph = function(element) {
	morphinfo['doclass'] = unit_selected.element.className;
	var xyvar = unit_selected.element.positionedOffset();
	var oldid = unit_selected.element.readAttribute('objectid');
	var useid = element.readAttribute('objectid');

	unit_selected.element.className = $allobjects[element.readAttribute('objectid')].name+" msel";
	unit_selected.element.setStyle({top: (Math.floor(xyvar.top/11)*11), left: (Math.floor(xyvar.left/11)*11) });

	var unitimg = unit_selected.element.getElementsByClassName('unitimg');
    var buildimg = element.getElementsByClassName('unitimg');

	morphinfo.bgpos = unitimg[0].getStyle('backgroundPosition');
	unitimg[0].setStyle({backgroundPosition: buildimg[0].getStyle('backgroundPosition') });
	unit_selected.element.writeAttribute("morphid", useid);
	unit_selected.element.onmouseover = function() { };

	morphing = true;
};

unit_cancelmove = function() {
	var element = unit_selected.element, useid = element.readAttribute("objectid"), edims = {width: parseInt($allobjects[useid].width), height: parseInt($allobjects[useid].height)};

	if (morphing) {
		element.className = morphinfo.doclass;
		var unitimg = element.getElementsByClassName('unitimg');
		unitimg[0].setStyle({backgroundPosition: morphinfo.bgpos});
		element.onmouseover = function() { unit_hover(this,true); }
		element.writeAttribute("morphid", "");
	}

	var startXY = {y: parseInt(element.readAttribute("starty")), x: parseInt(element.readAttribute("startx")) };

	var newZ = Math.floor((startXY.y*2000)+startXY.x);
	element.setStyle({top: (startXY.y-edims.height), left: (startXY.x-(edims.width/2)), zIndex: newZ });
	if (typeof unit_selected.destroy != "undefined") unit_selected.destroy();

	$("move_actions").hide();
    unit_selected.element = element;
};

unit_unselect = function() {
	if (typeof unit_selected.destroy != "undefined") unit_selected.destroy();
	var element = unit_selected.element;
	morphing = false;
	current_action = "";


	$("move_actions").hide();
	$("hud_build").stopObserving("click", buildStructures);
    $("hud_build").stopObserving("click", buildUnits);

	$("actions", "unit_selector", "hud_unit", "hud_unit_name", "hud_move", "hud_attack", "hud_build", "hud_build_list").invoke('hide');
	$("hud_actions").show(); // doesn't really show anything, just recycles for next use
	element.onclick = function() { unit_select(this); };
	unit_selected = null;
};

buildStructure = function(e,str) {
	var ssss = $('map').cumulativeOffset();
	var xpx = (e.realpointerX-ssss.left);
	var ypx = (e.realpointerY-ssss.top);

	popup("Are you sure you want to build a "+str+" here? [at "+xpx+" "+ypx+"]");
};

ajax_savemove = function() {
	var element = unit_selected.element, endXY = Element.positionedOffset(element);

	if (morphing) {
		var useid = element.readAttribute('morphid');
		var endX = endXY.left, endY = endXY.top;

		new Ajax.Request("battle_ajax.php", {
			parameters: {str_build: 1, gameid: $game.id, id: element.readAttribute("unitid"), str_id: useid, newX: endX, newY: endY},
			onSuccess: function(tr) {
				var re = eval("("+tr.responseText+")");

				if (parseInt(re.success) == re.success) {
					unit_unselect();
					var element = $("unit_"+re.unitid);
					element.writeAttribute("startx", re.x);	
					element.writeAttribute("starty", re.y);
					element.writeAttribute("objectid", re.objectid);
					element.writeAttribute("hp", re.hp);
					element.onmouseover = function() { unit_hover(this,true); }.bindAsEventListener(element);
					element.onclick = function() {}; // add something for this for this structure?
				}
				else {
					popup('<br>'+re.error);
					unit_cancelmove();
				}

			}
		});

	}
	else {
		var useid = element.readAttribute("objectid");
		var edims = {width: parseInt($allobjects[useid].width), height: parseInt($allobjects[useid].height)};
		var endX = endXY.left+(edims.width/2);
		var endY = endXY.top+edims.height; // Get bottom center location!
		//var distance = Math.sqrt(Math.pow((endX - element.readAttribute("startx")),2) + Math.pow((endY - element.readAttribute("starty")),2));
		// saving can be off by up to 0.1, unfortunately this is lost somewhere in the math above and I haven't found where - Mark

		new Ajax.Request("battle_ajax.php", {
			parameters: {unit_move: 1, game_id: $game.id, id: element.readAttribute("unitid"), newX: endX, newY: endY},
			onSuccess: function(tr) {

				if (tr.responseText == 1) {
					unit_unselect();
					element.writeAttribute("moved", 1);
					//element.setStyle({opacity: 0.33});
					element.writeAttribute("startx", endX);	
					element.writeAttribute("starty", endY);
				}
				else {
					var re = eval('('+tr.responseText+')');
					popup('<br>'+re.error, {onEnd: function () { window.location = re.redirect; } });
					unit_cancelmove();
				}

			}
		});
	}
};

str_hover = function(element,showit) {
	/*unit_hover($(el.id),showit);*/
};

unit_hover = function(element, showit) {
	if ($(element+"_hp")) {
		if (showit == true) $(element+"_hp").show();
		else $(element+'_hp').hide();
	}
};

endturn = function() {
	new Ajax.Request("battle_ajax.php", {
		parameters: {end_turn: 1, game_id: $game.id},
		onSuccess: function(tr) {

			if (tr.responseText == parseInt(tr.responseText)) {
				$('user_pane_'+parseInt(tr.responseText)).insert($("turn_marker").remove());
				$('endturn').hide();
				$game.turn = parseInt(tr.responseText);
				var user_units = $('map').select('[uid="'+$user.id+'"]');
				user_units.invoke('setStyle', {opacity: 1});
				user_units.invoke('writeAttribute', 'moved', '0');
			}
			else {
				popup('<br>'+tr.responseText);
			}

		}
	});
};

joinGame = function() {
	new Ajax.Request("battle_ajax.php", {
		parameters: {join_game: 1, gameid: $game.id},
		onSuccess: function(tr) {
			var re = eval("("+tr.responseText+")");

			if (re.success == 1) {

				if (re.full == 1) {
					window.location = 'battle.php?id='+re.gameid;
				}
				else {
					var keys = Object.keys(re.players);
					var len = (typeof re.players.length == "undefined") ? keys.length : re.players.length; // re.players.keys().length
					$('user_list').writeAttribute("players", len);
					var chatheight = 473-(len*27)-90;
					$('chat').setStyle({height: chatheight});
					$('user_list').innerHTML = "";
					for (var i=0;i < len;i++) {
						$('user_list').innerHTML += "<div id='user_pane_"+re.players[i].id+"' class='user'><div class='color_marker' style='background-color:#999999;'><!-- --></div><div class='icon_marker' style=''><!-- --></div><div class='name_marker'>"+re.players[i].user+"</div></div>";
					}
				}

			}
			else {
				popup('<br>'+re.error);
			}

		}
	});
};



_popupOnEnd = "";

popup = function(msg, options) {
	if (typeof options == 'object') {
		if (typeof options.onEnd != 'undefined') {
			_popupOnEnd = options.onEnd;
		}
	}
	var size = document.viewport.getDimensions();
	var winscroll = document.viewport.getScrollOffsets();

	var dims = {width: 250, height: 150};
	var pos = {top: winscroll.top+(size.height/2)-(dims.height/2), left: (size.width/2)-(dims.width/2)};

	if ($('_popup')) {
		$('_popupContent').innerHTML += "<br />\n" + msg;
	}
	else $(document.body).insert("<div id='_popup' style='color:#FFFFFF;z-index:10000;position:absolute;top:"+pos.top+"px;left:"+pos.left+"px;width:"+dims.width+"px;height:"+dims.height+"px;background-color:#000000;'><div id='_popupContent'>"+msg+"</div> <input type='button' onclick='closePopup();' value='Continue' /></div>");
};

closePopup = function() {
	if (_popupOnEnd != "") { _popupOnEnd();_popupOnEnd = ""; }
	$('_popup').remove();
};
