/*
 * trainer.js - KoL Familar Trainer
 * written by: bigfreak (#692131) for Vladjimir (#243023)
 */

function parseStars( src )
{	return Number( src.replace( /.+?\//g, '' ).replace( /\.gif/g, '' ).replace( /star/g, '' ).replace( /x/g, '0' ) );
}
function gatherOpponents()
{
	var opponents = Array();
	opponents[0] = { name: 'unset', weight: 0, stars: [ 0, 0, 0, 0 ] };
	var objs = document.getElementsByTagName( 'input' );
	for ( var i = 0; i < objs.length; i++ )
	{
		if ( Number( objs[i].value ) <= 0 || !objs[i].parentNode.tagName || objs[i].parentNode.tagName.toLowerCase() != 'td' )
			continue;

		for ( var it = objs[i].parentNode.previousSibling; it && it.tagName != 'TD'; it = it.previousSibling );
		var tds = objs[i].parentNode.parentNode.getElementsByTagName( 'td' );
		opponents[ ( !it || it.tagName != 'TD' || it.childNodes[0].tagName != 'INPUT' ) ? 0 : opponents.length] = 
			{ name: tds[0].innerHTML, weight: Number( objs[i].value ), stars: [ parseStars( tds[4].childNodes[0].src ), 
			parseStars( tds[5].childNodes[0].src ), parseStars( tds[6].childNodes[0].src ),
			parseStars( tds[7].childNodes[0].src ) ], tdObjs: [ tds[4], tds[5], tds[6], tds[7], tds[0], tds[2] ],
			img: tds[1].childNodes[0].src };
	}
	return opponents;
}
function hideMost( opponents )
{
	unchecked_visible = false;
	var objs = document.getElementsByTagName( 'input' );
	for ( var i = 0; i < objs.length; i++ )
		if ( objs[i].parentNode.tagName.toLowerCase() == 'td' )
			objs[i].parentNode.parentNode.style.display = 'none';
	for ( var i = 0; i < opponents.length; i++ )
		if ( opponents[i].tdObjs )
			opponents[i].tdObjs[0].parentNode.style.display = '';
}
function runFight( mybuddy, enemy, event )
{
	var enemyStars = enemy.stars[event];
	var enemyAbility = enemyStars * 3 + enemy.weight;
	if ( enemyStars == 0 )
		enemyAbility = 5;

	var myStars = mybuddy.stars[event];
	var myAbility = myStars * 3 + mybuddy.weight;			
	if ( myStars == 0 )
		myAbility = 5;
	
	var losses = 0; var fives = 0; var fours = 0; var threes = 0; var twos = 0;

	// RNG best / worst case run through (both sides)
	for ( var n = 0; n < 5; n++ )
	{
		var myRNG = myAbility - n - 2;
		for ( var m = 0; m < 5; m++ )
		{
			var enemyRNG = enemyAbility - m - 2;
			var margin = myRNG - enemyRNG;
			if ( margin < 0 )
				losses++;
			else if ( margin <= 5 )
				fives++;
			else if ( margin == 6 )
				fours++;
			else if ( margin == 7 )
				threes++;
			else
				twos++;
		}
	}
	return { 'lose': Math.floor( (losses / 25) * 100 ), 'five': Math.floor( (fives / 25) * 100 ), 
		'four': Math.floor( (fours / 25) * 100 ), 'three': Math.floor( (threes / 25) * 100 ), 
		'two': Math.floor( (twos / 25) * 100 ) };
}
function runFights( mybuddy, opponents, risk, callback )
{
	var bestChance = 0;
	var bestEnemy = Array();
	for ( var i = 1; i < opponents.length; i++ )
	{
		var enemy = opponents[i];
		for ( var j = 0; j < 4; j++ )
		{
			var odds = runFight( mybuddy, enemy, j );
			if ( callback )
				callback( mybuddy, enemy, odds, j );
			if ( odds.five >= bestChance && odds.lose <= risk )
			{
				bestChance = odds.five;
				var index = bestEnemy.length;
				bestEnemy[index] = Array();
				bestEnemy[index].enemy = enemy;
				bestEnemy[index].bestChance = bestChance;
				bestEnemy[index].bestEvent = j;
				bestEnemy[index].odds = odds;
			}
		}
	}
	var ret = Array();
	for( var i = 0 ; i < bestEnemy.length; ++i )
		if ( bestEnemy[i].bestChance == bestChance )
			ret[ret.length] = bestEnemy[i];
	return ret;
}
function calcCallback( mybuddy, enemy, odds, event )
{
	var cell = enemy.tdObjs[event];
	cell.style.border = '';
	if ( cell.innerHTML.toLowerCase().indexOf( '<table' ) > -1 )
		cell.innerHTML = cell.innerHTML.substr( 0, cell.innerHTML.toLowerCase().indexOf( '<table' ) );
	var title = 'Lose: ' + odds.lose + '%\n5xp: ' + odds.five + '%\n4xp: ' + odds.four + '%\n3xp: ' + odds.three + '%\n2xp: ' + odds.two + '%';
	if ( navigator.userAgent.indexOf( "Firefox" ) > -1 )
		title = 'header=[] body=[Lose: ' + odds.lose + '%<br>5xp: ' + odds.five + '%<br>4xp: ' + odds.four + '%<br>3xp: ' + odds.three +
			'%<br>2xp: ' + odds.two + '%] cssbody=[tooltip]';
	cell.innerHTML += "<table border='0' cellpadding='0' cellspacing='0' width='100%' title='" + title + "'><tr>" +
		( odds.lose > 0 ? "<th bgcolor='#F73842' width='" + odds.lose + "%'>&nbsp;</th>" : '' ) +
		( odds.five > 0 ? "<th bgcolor='#00A469' width='" + odds.five + "%'>&nbsp;</th>" : '' ) +
		( odds.four > 0 ? "<th bgcolor='#3376C3' width='" + odds.four + "%'>&nbsp;</th>" : '' ) +
		( odds.three > 0 ? "<th bgcolor='#F6D700' width='" + odds.three + "%'>&nbsp;</th>" : '' ) +
		( odds.two > 0 ? "<th bgcolor='#FF9E29' width='" + odds.two + "%'>&nbsp;</th>" : '' ) +
		"</tr></table>";
}
function updateChart()
{
	
	// prepare the interface
	var opponents = gatherOpponents();
	hideMost( opponents );
	document.getElementById( 'legend' ).style.display = '';
	document.getElementById( 'readoutspan' ).style.display = '';
	for ( var i = 1; i < opponents.length; i++ )
		opponents[i].tdObjs[5].childNodes[0].disabled = true;

	// run the fights and show the results
	var ret = runFights ( opponents[0], opponents, document.getElementById( 'risk' ).value || 10, 
		function( mybuddy, enemy, odds, event ) { calcCallback( mybuddy, enemy, odds, event ); } );
	for( var i = 0 ; i < ret.length; ++i )
		ret[i].enemy.tdObjs[ret[i].bestEvent].style.border = '2px #00A469 solid';
}

function updateSchedule()
{
	var events = [ 'Ultimate Cage Match', 'Scavenger Hunt', 'Obstacle Course', 'Hide and Seek' ];
	var opponents = gatherOpponents();
	var mybuddy = opponents[0];
	var risk = document.getElementById( 'risk' ).value || 10;
	var readout = '<table border="0" cellpadding="1" cellspacing="1" width="400" id="schedule"><tbody>';

	for ( var i = 1; i < 50; ++i )
	{
		if ( i % 10 == 1 )
			readout += '' +
				'<tr class="heading">' +
				'<th colspan="2" width="100">Your Pet</th>' +
				'<th colspan="2" width="100">Opponent</th>' +
				'<th width="100">Event</th>' +
				'<th width="100">Odds</th>' +
				'</tr>';

		mybuddy.weight = i;
		var ret = runFights ( mybuddy, opponents, risk, null );
		if ( !ret.length )
		{
			readout += '<tr><td colspan="8">At ' + i + ' lbs, no good matches exist for ' + risk + '% risk.</td></tr>';
			continue;
		}
		readout += '<tr class="text1" style="display: table-row;">';
		readout += '<td width="30"><img src="' + mybuddy.img + '" title="' + mybuddy.name + '" /></td>';
		readout += '<td width="50"><b>' + i + '</b> lbs</td>';

		readout += '<td width="30"><img src="' + ret[0].enemy.img + '" title="' + ret[0].enemy.name + '" /></td>';
		readout += '<td width="50"><b>' + ret[0].enemy.weight + '</b> lbs</td>';

		readout += '<td width="100"' + ( ret[0].odds.five > 76 ? 'style="border: 2px #00A469 solid;"' : '' ) + '>' + events[ret[0].bestEvent] + '</td>';
		
		readout += '<td width="100">';		
		var title = 'Lose: ' + ret[0].odds.lose + '%\n5xp: ' + ret[0].odds.five + '%\n4xp: ' + 
			ret[0].odds.four + '%\n3xp: ' + ret[0].odds.three + '%\n2xp: ' + ret[0].odds.two + '%';
		if ( navigator.userAgent.indexOf( "Firefox" ) > -1 )
			title = 'header=[] body=[Lose: ' + ret[0].odds.lose + '%<br>5xp: ' + 
				ret[0].odds.five + '%<br>4xp: ' + ret[0].odds.four + '%<br>3xp: ' + ret[0].odds.three +
				'%<br>2xp: ' + ret[0].odds.two + '%] cssbody=[tooltip]';
		readout += "<table border='0' cellpadding='0' cellspacing='0' width='100%' title='" + title + "'><tr>" +
			( ret[0].odds.lose > 0 ? "<th bgcolor='#F73842' width='" + ret[0].odds.lose + "%'>&nbsp;</th>" : '' ) +
			( ret[0].odds.five > 0 ? "<th bgcolor='#00A469' width='" + ret[0].odds.five + "%'>&nbsp;</th>" : '' ) +
			( ret[0].odds.four > 0 ? "<th bgcolor='#3376C3' width='" + ret[0].odds.four + "%'>&nbsp;</th>" : '' ) +
			( ret[0].odds.three > 0 ? "<th bgcolor='#F6D700' width='" + ret[0].odds.three + "%'>&nbsp;</th>" : '' ) +
			( ret[0].odds.two > 0 ? "<th bgcolor='#FF9E29' width='" + ret[0].odds.two + "%'>&nbsp;</th>" : '' ) +
			"</tr></table>";
		readout += '</td>';

		readout += '</tr>';
	}
	readout += '</tbody></table>';

	var divObj = document.createElement( 'div' );
	divObj.innerHTML = readout;

	var obj = document.getElementById( 'schedule' );
	obj.parentNode.replaceChild( divObj.childNodes[0], obj );
}

function toggleSchedule( show )
{
	document.getElementById( 'famchart' ).style.display = show ? 'none' : '';
	document.getElementById( 'readoutchart' ).style.display = !show ? 'none' : '';
	document.getElementById( 'readout' ).innerHTML = show ? 'Show Single-Weight Chart' : 'Show Training Schedule';
	calc();
}

function calc()
{
	if ( document.getElementById( 'famchart' ).style.display == 'none' )
		updateSchedule();
	else
		updateChart();
}

function addControls()
{
	document.body.className = 'text2';

	var objs = document.getElementsByTagName( 'input' );
	var obj = null;
	for ( var i = 0; i < objs.length; i++ )
	{
		if ( !objs[i].parentNode.tagName || objs[i].parentNode.tagName.toLowerCase() != 'td' )
			continue;
		obj = objs[i];
		while ( obj.tagName.toLowerCase() != 'table' )
			obj = obj.parentNode;
		obj.id = 'famchart';
	}

	var div = document.createElement( 'div' );
	div.style.display = 'none';
	div.id = 'readoutchart';
	div.innerHTML = '<table border="0" cellpadding="1" cellspacing="1" width="400" id="schedule"></table>';
	var table = obj;
	table.parentNode.insertBefore( div, table.nextSibling );

	var objs = document.getElementsByTagName( 'a' );
	for ( var i = 0; i < objs.length && objs[i].innerHTML != 'Reset'; ++i );
	if ( i >= objs.length )
		return;
	var obj = objs[i];
	while ( !obj.tagName || obj.tagName.toLowerCase() != 'br' )
		obj = obj.nextSibling;
	var rObj = document.createElement( 'input' );
	rObj.id = 'risk';
	rObj.value = 15;
	rObj.size = 2;
	rObj.maxLength = 2;
	rObj.className = "boxtext";
	rObj.style.width = '20px';
	rObj.onchange = function(){ calc(); };
	obj.parentNode.insertBefore( document.createTextNode( 'Acceptable Risk of Losing ' ), obj );
	obj.parentNode.insertBefore( rObj, obj );
	obj.parentNode.insertBefore( document.createTextNode( '%' ), obj );
	var ao = document.createElement( 'a' );
	ao.id = 'readout';
	ao.href = 'javascript:;';
	ao.onclick = function() { toggleSchedule( document.getElementById( 'famchart' ).style.display != 'none' ); };
	ao.innerHTML = 'Show Training Schedule';
	var sObj = document.createElement( 'span' );
	sObj.id = 'readoutspan';
	sObj.style.display = 'none';
	sObj.appendChild( document.createTextNode( ' [ ' ) );
	sObj.appendChild( ao );
	sObj.appendChild( document.createTextNode( ' ]' ) );
	obj.parentNode.insertBefore( sObj, obj );
}

function initTrainer()
{
	addControls();
	var objs = document.getElementsByTagName( 'input' );
	for ( var i = 0; i < objs.length; i++ )
	{
		for ( var it = objs[i].parentNode.previousSibling; it && it.tagName != 'TD'; it = it.previousSibling );
		if ( !it || it.tagName != 'TD' || it.childNodes[0].tagName != 'INPUT' )
			objs[i].onchange = function(){ calc(); };
	}
}