IkariamCRCEngine = {
	ResourceImages: [
		'http://img196.imageshack.us/img196/1127/woodsmall.gif',	// wood 
		'http://img193.imageshack.us/img193/2796/winesmall.gif',	// wine 
		'http://img194.imageshack.us/img194/421/iconmarble.gif',	// marb  
		'http://img190.imageshack.us/img190/5090/glasssmall.gif',	// glas  
		'http://img195.imageshack.us/img195/2010/sulfursmall.gif'	// sulf  
	],
	UnitMapping: {
		name: { 
			slinger: 		"army s301", 
			swordsman: 		"army s302", 
			phalanx: 		"army s303", 
			archer: 		"army s313", 
			marksman: 		"army s304", 
			gyrocopter: 		"army s312", 
			"steam giant": 		"army s308", 
			bombardier: 		"army s309", 
			ram: 			"army s307", 
			catapult: 		"army s306", 
			mortar: 		"army s305", 
			doctor: 		"army s311", 
			cook: 			"army s310", 
			barbarian:		"army s316"
		},
		costs: {
			slinger: 		20, 
			swordsman: 		60, 
			phalanx: 		70, 
			archer: 		55, 
			marksman: 		200, 
			gyrocopter: 		125, 
			"steam giant": 		310, 
			bombardier: 		290, 
			ram: 			220, 
			catapult: 		560, 
			mortar: 		1550, 
			doctor: 		200, 
			cook: 			30,
			barbarian:		0
		},
		clas: { 
			"army s301": "slinger", 
			"army s302": "swordsman", 
			"army s303": "phalanx", 
			"army s313": "archer", 
			"army s304": "marksman", 
			"army s312": "gyrocopter", 
			"army s308": "steam giant", 
			"army s309": "bombardier", 
			"army s307": "ram", 
			"army s306": "catapult", 
			"army s305": "mortar", 	
			"army s311": "doctor", 
			"army s310": "cook", 
			"army s315": "spearmen", 
			"army s316": "barbarian" 
		}
	},
	ShipMapping: {
		name: { 
			cargo: 		"fleet s201", 
			ram: 		"fleet s210", 
			ballista:	"fleet s213", 
			flame: 		"fleet s211", 
			catapult: 	"fleet s214", 
			paddle: 	"fleet s216", 
			mortar: 	"fleet s215", 
			diving: 	"fleet s212" 
		},
		clas: { 
			"fleet s201": "cargo", 
			"fleet s210": "ram", 
			"fleet s213": "ballista", 
			"fleet s211": "flame", 
			"fleet s214": "catapult", 
			"fleet s216": "paddle", 
			"fleet s215": "mortar", 
			"fleet s212": "diving" 
		}
	},
	Engines: {
		"v.0.3.2": {
			BuildReport:function(formatter, cr, lang, script_version, events) 
			{
				if (formatter == null) return "NullReferenceException: formatter";
				// Initialize the "Units" for the current version.
				Units.Initialize($('li.version').text());
				// Add Place & Time of Attack 
				output = formatter.AddColor(cr.info.place + '\n' + cr.info.time + '\n\n', 'HEADER');		
				// Add Attackers + Defenders Involved 
				output += formatter.AddColor(cr.info.attacker, 'ATTACKING');
				output += cr.info.defender != undefined ? '\nvs\n' + formatter.AddColor(cr.info.defender, 'DEFENDING') + '\n\n' : '\n\n';
				// Some magic numbers to help align the report
				var nName = 19;
				var nLeft = 5;
				var nLost = 8;
				var nReserve = 8;
				var nTotal = cr.info.round == undefined ? nName + nLeft + nLost : nName + nLeft + nLost + nReserve; 
				// Display each unit (if present)
				attackersLosses = 0; defendersLosses = 0; 
				output += formatter.AddSeparator(nTotal * 2 + 3) + '\n'; 
				for (var unit in Units.Details) {
					if (cr.attacker[unit] != null || cr.defender[unit] != null) {
						key = Units.Details[unit].key; 
						unitName = cr.info.type == "army" ? lang.units[key] : lang.ships[key];
						if (cr.attacker[unit] != null) {
							lost = cr.attacker[unit].lost == null ? 0 : cr.attacker[unit].lost;
							output += formatter.PadString('right', unitName, nName, '.', 'ATTACKING');
							output += formatter.PadString('left', cr.attacker[unit].left == null ? '' : cr.attacker[unit].left, nLeft, '.', 'UNITLEFT');
							output += formatter.PadString('right', cr.attacker[unit].lost == null ? '' : '(-' + 
							          formatter.AddColor(cr.attacker[unit].lost, 'UNITLOST') + ')', nLost, '.', '');
							output += cr.info.round == undefined ? '' : (cr.attacker[unit].reserve == undefined 
								? formatter.PadString('left', '', nReserve, '.', '')
								: formatter.PadString('left', '{' + formatter.AddColor(cr.attacker[unit].reserve, 'UNITRESERVE') + '}', nReserve, '.', '')
								);
							output += ' - ';
							attackersLosses += lost * Units.Damage(unit); 
						} else {
							output += formatter.PadString('right', '', nTotal, '.', '') + ' - ';
						}
						if (cr.defender[unit] != null) {
							var lost = cr.defender[unit].lost == null ? 0 : cr.defender[unit].lost;
							output += formatter.PadString('right', unitName, nName, '.', 'DEFENDING');
							output += formatter.PadString('left', cr.defender[unit].left == null ? '' : cr.defender[unit].left, nLeft, '.', 'UNITLEFT');
							output += formatter.PadString('right', cr.defender[unit].lost == null ? '' : '(-' + 
							          formatter.AddColor(cr.defender[unit].lost, 'UNITLOST') + ')', nLost, '.', '');
							output += cr.info.round == undefined ? '' : (cr.defender[unit].reserve == undefined 
								? formatter.PadString('left', '', nReserve, '.', '')
								: formatter.PadString('left', '{' + formatter.AddColor(cr.defender[unit].reserve, 'UNITRESERVE') + '}', nReserve, '.', '')
								);
							defendersLosses += lost * Units.Damage(unit);

						} else {
							output += formatter.PadString('right', '', nTotal, '.', '');
						}
						output += '\n';
					}
				}		
				// Add Table to display Net Losses/Gains + Loot 
				output += formatter.AddSeparator(nTotal * 2 + 3) + '\n';
				var metricTranslations = [lang.highscore.army_score_main, lang.report.damage];
				var metricAttackers = [ parseInt(attackersLosses*-1*.02), parseInt(attackersLosses) ];
				var metricDefenders = [ parseInt(defendersLosses*-1*.02), parseInt(defendersLosses + cr.results.loot.total) ];
				for (var m = 0; m < metricTranslations.length; m++) {
					output += formatter.PadString('right', metricTranslations[m], nTotal - 10, '.', 'ATTACKING');
					output += formatter.PadString('left', IkariamCRCEngine.AddCommas(metricAttackers[m]) + '', 10, '.', 'ATTACKING') + ' - ';
					output += formatter.PadString('right', metricTranslations[m], nTotal - 10, '.', 'DEFENDING'); 
					output += formatter.PadString('left', IkariamCRCEngine.AddCommas(metricDefenders[m]) + '', 10, '.', 'DEFENDING') + '\n';
				}
				output += formatter.AddSeparator(nTotal * 2 + 3) + '\n';
				// Add Victor(s) 
				if (cr.results.victors != null) {
					output += '\n' + formatter.AddColor(cr.results.victors, 'VICTOR') + '\n';
				}
				else if (cr.info.round != null) {
					output += '\n' + formatter.AddColor(cr.info.round, 'VICTOR') + '\n';
				}
				// Add Loot 
				if (cr.results.loot.total > 0) {
					results = '\n';
					results += lang.report.loot + ': ';
					var lootTotals = [
						cr.results.loot.wood, cr.results.loot.wine, cr.results.loot.marble, cr.results.loot.glass, cr.results.loot.sulfur 
					];
					var lootString = [
						lang.resources.wood, 
						lang.resources.wine, 
						lang.resources.marble, 
						lang.resources.glass, 
						lang.resources.sulfur
					];
					for (var r = 0; r < lootTotals.length; r++) {
						if (lootTotals[r] > 0 ) {
							var imageString = formatter.AddImage(IkariamCRCEngine.ResourceImages[r]);
							if (imageString == '') imageString = '\n' + lootString[r];
							results += imageString + " " + IkariamCRCEngine.AddCommas(lootTotals[r]) + ' ';
						}
					}
					output += results + '\n';
				}
				// Add Event(s)
				if (events && cr.events != null) {
					output += '\n'; events = '';
					for (var e in cr.events){
						events += cr.events[e] + '\n';
					}
					output += formatter.AddColor(events, 'EVENTS');
				}

				// Add Homepage Link
				if (script_version)
				{
					output += "\nCreated using DLR's " + 
				formatter.AddLink("Ikariam CR Converter", "http://board.ikariam.org/index.php?page=Thread&threadID=56204") + ' (' +
				formatter.AddLink('Version ' + script_version, "http://userscripts.org/scripts/show/50784") + ')';
				}
				else
				{
					output += "\n" + lang.report.copy +
				formatter.AddLink("Ikariam CR Converter", "http://board.en.ikariam.com/index.php?page=Thread&threadID=70526") + " " +
				formatter.AddLink("[" + lang.report.web + "]", "http://tools.betawarriors.com/ikcrc/?lang=" + IkariamWebConverter.lang);
				}

				// Add Size, Font, Bold-Styling and Alignment 
				output = formatter.AddSize(output, 85);
				output = formatter.AddFont(output, 'Courier New');
				output = formatter.AddBold(output);
				output = formatter.AddAlignment(output, 'center');

				return output;
			},
			ParseReport:function(cr, lang)
			{
				if ($("#troopsReport").size() > 0)
				{ 
					// Get the CR details 
					cr.info.time     = $('#troopsReport span.date').text(); 
					cr.info.place    = $('#troopsReport h3.header:eq(0)').html().match(/(.+)\s\</)[1];
					cr.info.attacker = $('#troopsReport div.attacker span').text();
					cr.info.defender = $('#troopsReport div.defender span').text();
					switch ($('li.version').text())
					{
					case "v0.4.0":
					case "v0.4.1":
						cr.info.type = $("#troopsReport table.overview tr th div[class^='army']").size() > 0 ? "army" : "fleet";
						break; 
					default:
						cr.info.type = $("#troopsReport table.overview tr td.headline div[class^='army']").size() > 0 ? "army" : "fleet";
					break;
					}
					var unitSide = null;
					var unitKeys = new Array();
					var unitQuery = "";
					switch ($('li.version').text())
					{
					case "v0.4.0":
					case "v0.4.1":
						unitQuery = "th div";
					break;
					default:
						unitQuery = "td.headline div";
					break;
					} 
					$("#troopsReport table.overview tr").each(function() {
						// re-define units that are being parsed 
						if ($(this).find(unitQuery).size() > 0) {
							unitSide = cr.attacker;
							unitKeys = []; 
							$(this).find(unitQuery).each(function() { unitKeys.push($(this).attr("class")); });
						}
						else
						if ($(this).find("td[colspan='8'][class^='col1 nobg']").size() == 1) { 
							unitSide = cr.defender;
						}
						else
						if ($(this).find("td.numbers").size() == unitKeys.length) {
							unitCount = 0; 
							$(this).find("td.numbers").each(function() {
								var unit = unitKeys[unitCount++].match(/\d+/)[0];
								var details = $(this).text();
								if (unit != null && details.indexOf("(") != -1) {
									if (unitSide[unit] == null || unitSide[unit] == null) { unitSide[unit] = { left: 0, lost: 0 } }
									unitSide[unit].left += parseInt(details.substr(0, details.indexOf('(')).replace(/\s+/, ''));
									unitSide[unit].lost += parseInt(details.substr(details.indexOf('(') + 2).replace(/\s+/, '').replace(/\)/, ''));
								}
							});
						}
					}); 
					// Victors 
					cr.results.victors = $("#troopsReport div.result div.winners").text().replace(/^\s*/, '').replace(/\s*$/, ''); 
					// Results 
					var events = {}; var count = 0;
					$("#troopsReport div.result div").not("div.winners,div.losers").each(function() {
						if ($(this).find("ul.resources").size() == 0) {
							events[count++] = $(this).text(); 
						}
					});
					if (events != '') cr.events = events;
					// Loot, If Available 
					cr.results.loot = {total:0};
					$("div.result ul.resources li").each(function() {
						var type = $(this)[0].className;
						var amount = parseInt($(this).contents()[1].nodeValue.replace(/,/,''));
						cr.results.loot[type] = cr.results.loot[type] == null ? amount : cr.results.loot[type] + amount;
						cr.results.loot.total += amount;
					});
				}
				else if ($("#battlefield").size() > 0)
				{
					// Get the CR details 
					cr.info.time     = $('#rounds li.roundTime').text();
					cr.info.place    = $('#mainview div.buildingDescription h1').text();
					cr.info.round    = $('#rounds ul li.roundNo').text();
					cr.info.type     = $("#battlefield[class*='land'],#battlefield[class*='city']").size() > 0 ? "army" : "fleet";  
					try { cr.info.attacker = $('#attacker').text().match(/:\n\s+(.+)/)[1]; } catch(e) {}
					try { cr.info.defender = $('#defender').text().match(/:(.+)/)[1]; } catch(e) {}
					// Attacker field units 
					$("#fieldAttacker ul li").each(function() {
						var unit = $('div:eq(0)', this).attr('class'); try { unit = unit.match(/\d+/)[0] } catch(e) { };
						if (Units.Details[unit] != undefined) { 
							var left = parseInt($('div.number', this).text().match(/(\d+)/)[1]); 
							var lost = parseInt($('div.number', this).text().match(/\(-(\d+)\)/)[1]); 
							if (cr.attacker[unit] == undefined) {
								cr.attacker[unit] = { "left":left, "lost":lost, "reserve":0 };
							} else {
								cr.attacker[unit].left += left; 
								cr.attacker[unit].lost += lost;
							}
						}
					});
					// Defender field units 
					$("#fieldDefender ul li").each(function() {
						var unit = $('div:eq(0)', this).attr('class'); try { unit = unit.match(/\d+/)[0] } catch(e) { };
						if (Units.Details[unit] != undefined) { 
							var left = parseInt($('div.number', this).text().match(/(\d+)/)[1]); 
							var lost = parseInt($('div.number', this).text().match(/\(-(\d+)\)/)[1]); 
							if (cr.defender[unit] == undefined) {
								cr.defender[unit] = { "left":left, "lost":lost, "reserve":0 };
							} else {
								cr.defender[unit].left += left; 
								cr.defender[unit].lost += lost;
							}
						}
					});
					// Attacker reserve units 
					//$("#resAttacker div.units ul li").each(function() {
					$("ul[id^='attackerPage'] li").each(function() {
						var unit = $("div", this).attr('class'); try { unit = unit.match(/\d+/)[0] } catch(e) { };
						if (Units.Details[unit] != undefined) { 
							if (cr.attacker[unit] == undefined) { cr.attacker[unit] = {}; }
							cr.attacker[unit].reserve = parseInt($(this).text().match(/(\d+)/));
						}
					});
					// Defender reserve units 
					//$("#resDefender div.units ul li").each(function() {
					$("ul[id^='defenderPage'] li").each(function() {
						var unit = $("div", this).attr('class'); try { unit = unit.match(/\d+/)[0] } catch(e) { };
						if (Units.Details[unit] != undefined) { 
							if (cr.defender[unit] == undefined) { cr.defender[unit] = {}; }
							cr.defender[unit].reserve = parseInt($(this).text().match(/(\d+)/));
						}
					});
					// Results 
					var events = {}; var count = 0;
					$("#events div span").each(function() {
						//if (Settings.get('nameEventUnits')) {
							var html = $(this).html();
							$("ul.unitlist", this).before('\n');
							$("ul.unitlist li", this).each(function() {
								var unit = $(this).attr('class').match(/\d+/)[0];
								if (Units.Details[unit] != undefined) { 
									var key = Units.Details[unit].key;
									var unitName = cr.info.type == "army" ? lang.units[key] : lang.ships[key];
									$(this).text(unitName + ':' + $(this).text() + ' ');
								}
							});
						//}
						events[count++] = $(this).text().replace(/^\s+|\s+$/g, '');
						$(this).html(html);
					});
					if (events != '') cr.events = events;
					// Loot
					cr.results.loot = { total:0 };
				} 
			}
		}
	},
	AddCommas:function(nStr) {
		nStr += '';
		x = nStr.split('.');
		x1 = x[0];
		x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		}
		return x1 + x2;
	}
}

Units = {
	Details: {
	/* Sea */
		/* ram   */ "210" : { wood:220, wine:0,   sulfur:50,   glass:0,   key:"ram" },
		/* bal   */ "213" : { wood:180, wine:0,   sulfur:160,  glass:0,   key:"ballista" },
		/* fire  */ "211" : { wood:80,  wine:0,   sulfur:230,  glass:0,   key:"flame" },
		/* cat   */ "214" : { wood:180, wine:0,   sulfur:140,  glass:0,   key:"catapult" },
		/* pad   */ "216" : { wood:300, wine:0,   sulfur:1500, glass:0,   key:"paddle" },
		/* mort  */ "215" : { wood:220, wine:0,   sulfur:900,  glass:0,   key:"mortar" },
		/* div   */ "212" : { wood:160, wine:0,   sulfur:0,    glass:750, key:"diving" },
	/* Land */
		/* sling */ "301" : { wood:20,  wine:0,   sulfur:0,    glass:0,   key:"slinger" },
		/* sword */ "302" : { wood:30,  wine:0,   sulfur:30,   glass:0,   key:"swordsman" },
		/* hop   */ "303" : { wood:40,  wine:0,   sulfur:30,   glass:0,   key:"phalanx" },
		/* arch  */ "313" : { wood:30,  wine:0,   sulfur:25,   glass:0,   key:"archer" },
		/* guns  */ "304" : { wood:50,  wine:0,   sulfur:150,  glass:0,   key:"marksman" },
		/* gyro  */ "312" : { wood:25,  wine:0,   sulfur:100,  glass:0,   key:"gyrocopter" },
		/* steam */ "308" : { wood:130, wine:0,   sulfur:180,  glass:0,   key:"steam giant" },
		/* bomb  */ "309" : { wood:40,  wine:0,   sulfur:250,  glass:0,   key:"bombardier" },
		/* ram   */ "307" : { wood:220, wine:0,   sulfur:0,    glass:0,   key:"ram" },
		/* cat   */ "306" : { wood:260, wine:0,   sulfur:300,  glass:0,   key:"catapult" },
		/* mort  */ "305" : { wood:300, wine:0,   sulfur:1250, glass:0,   key:"mortar" },
		/* doc   */ "311" : { wood:50,  wine:0,   sulfur:0,    glass:450, key:"doctor" },
		/* cook  */ "310" : { wood:50,  wine:150, sulfur:0,    glass:0,   key:"cook" },
		/* spear */ "315" : { wood:30,  wine:0,   sulfur:0,    glass:0,   key:"spearmen" },
		/* barb  */ "316" : { wood:0,   wine:0,   sulfur:0,    glass:0,   key:"barbarian" },
		/* wall  */ "314" : { wood:0,   wine:0,   sulfur:0,    glass:0,   key:"wall" }
	},
	Details045: {
	/* Sea */
		/* ram     */ "210" : { wood:250, wine:0,   sulfur:0,    glass:0,   key:"ram" },		// changed 0.4.5
		/* bal     */ "213" : { wood:180, wine:0,   sulfur:160,  glass:0,   key:"ballista" },
		/* fire    */ "211" : { wood:80,  wine:0,   sulfur:230,  glass:0,   key:"flame" },
		/* cat     */ "214" : { wood:180, wine:0,   sulfur:140,  glass:0,   key:"catapult" },
		/* paddle  */ "216" : { wood:400, wine:0,   sulfur:800,  glass:0,   key:"paddle" },		// changed 0.4.5
		/* mort    */ "215" : { wood:220, wine:0,   sulfur:900,  glass:0,   key:"mortar" },
		/* diving  */ "212" : { wood:160, wine:0,   sulfur:100,  glass:750, key:"diving" },		// changed 0.4.5
		/* rocket  */ "217" : { wood:200, wine:0,   sulfur:1200, glass:0,   key:"rocket" },		// new 0.4.5
		/* speed   */ "218" : { wood:40,  wine:0,   sulfur:280,  glass:0,   key:"speed" },		// new 0.4.5
		/* balloon */ "219" : { wood:700, wine:0,   sulfur:700,  glass:0,   key:"balloon" },		// new 0.4.5
		/* tender  */ "220" : { wood:300, wine:0,   sulfur:250,  glass:250, key:"tender" },		// new 0.4.5
	/* Land */
		/* sling   */ "301" : { wood:20,  wine:0,   sulfur:0,    glass:0,   key:"slinger" },
		/* sword   */ "302" : { wood:30,  wine:0,   sulfur:30,   glass:0,   key:"swordsman" },
		/* hop     */ "303" : { wood:40,  wine:0,   sulfur:30,   glass:0,   key:"phalanx" },
		/* arch    */ "313" : { wood:30,  wine:0,   sulfur:25,   glass:0,   key:"archer" },
		/* guns    */ "304" : { wood:50,  wine:0,   sulfur:150,  glass:0,   key:"marksman" },
		/* gyro    */ "312" : { wood:25,  wine:0,   sulfur:100,  glass:0,   key:"gyrocopter" },
		/* steam   */ "308" : { wood:130, wine:0,   sulfur:180,  glass:0,   key:"steam giant" },
		/* bomb    */ "309" : { wood:40,  wine:0,   sulfur:250,  glass:0,   key:"bombardier" },
		/* ram     */ "307" : { wood:220, wine:0,   sulfur:0,    glass:0,   key:"ram" },
		/* cat     */ "306" : { wood:260, wine:0,   sulfur:300,  glass:0,   key:"catapult" },
		/* mort    */ "305" : { wood:300, wine:0,   sulfur:1250, glass:0,   key:"mortar" },
		/* doc     */ "311" : { wood:50,  wine:0,   sulfur:0,    glass:450, key:"doctor" },
		/* cook    */ "310" : { wood:50,  wine:150, sulfur:0,    glass:0,   key:"cook" },
		/* spear   */ "315" : { wood:30,  wine:0,   sulfur:0,    glass:0,   key:"spearmen" },
		/* barb    */ "316" : { wood:0,   wine:0,   sulfur:0,    glass:0,   key:"barbarian" },
		/* wall    */ "314" : { wood:0,   wine:0,   sulfur:0,    glass:0,   key:"wall" },
	},
	Damage:function(unit) {
		if (Units.Details[unit] == undefined) 
			throw "Units::Damage() - unit undefined!";
		return Units.Details[unit].wood + Units.Details[unit].wine + Units.Details[unit].sulfur + Units.Details[unit].glass;
	},
	Initialize:function(version) {
		if (version != "v0.4.4"){
		  Units.Details = Units.Details045;
		}
	}
};
