/*
Adapted and made to run standalone from Toskks Calculator V2.1.2

*/

function DebugPrint(msg)
{
	WScript.Echo(msg)
}


var document =
{
	getElementById:function(name){
		return {value:"Al'ar"}
	}
}

function GetDPS(stats, talents)
{
	if (document.getElementById("boss").value == "Attumen the Huntsman") var basearmor = 7500;
	if (document.getElementById("boss").value == "Midnight") var basearmor = 8200;
	if (document.getElementById("boss").value == "The Curator") var basearmor = 6100;
	if (document.getElementById("boss").value == "Shade of Aran") var basearmor = 3800;
	if (document.getElementById("boss").value == "Maiden of Virtue") var basearmor = 6700;
	if (document.getElementById("boss").value == "Julianne") var basearmor = 6100;
	if (document.getElementById("boss").value == "Romulo") var basearmor = 7600;
	if (document.getElementById("boss").value == "Strawman") var basearmor = 7300;
	if (document.getElementById("boss").value == "Roar") var basearmor = 4700;
	if (document.getElementById("boss").value == "Terestian Illhoof") var basearmor = 6700;
	if (document.getElementById("boss").value == "Nightbane") var basearmor = 7600;
	if (document.getElementById("boss").value == "Netherspite") var basearmor = 5500;
	if (document.getElementById("boss").value == "Prince Malchezaar") var basearmor = 7600;
	if (document.getElementById("boss").value == "Doomwalker") var basearmor = 7600;
	if (document.getElementById("boss").value == "Hydross the Unstable") var basearmor = 7700;
	if (document.getElementById("boss").value == "The Lurker Below") var basearmor = 7700;
	if (document.getElementById("boss").value == "Leotheras the Blind") var basearmor = 7700;
	if (document.getElementById("boss").value == "Fathom-Lord Karathress") var basearmor = 6200;
	if (document.getElementById("boss").value == "Morogrim Tidewalker") var basearmor = 7700;
	if (document.getElementById("boss").value == "Lady Vashj") var basearmor = 6200;
	if (document.getElementById("boss").value == "Void Reaver") var basearmor = 8800;
	if (document.getElementById("boss").value == "High Astromancer Solarian") var basearmor = 6200;
	if (document.getElementById("boss").value == "Al'ar") var basearmor = 7700;
	if (document.getElementById("boss").value == "Kael'thas Sunstrider") var basearmor = 6200;
	if (document.getElementById("boss").value == "Rage Winterchill") var basearmor = 6200;
	if (document.getElementById("boss").value == "Anetheron") var basearmor = 6200;
	if (document.getElementById("boss").value == "Kaz'rogal") var basearmor = 6200;
	if (document.getElementById("boss").value == "Azgalor") var basearmor = 6200;
	if (document.getElementById("boss").value == "Archimonde") var basearmor = 6200;
	if (document.getElementById("boss").value == "High Warlord Naj'entus") var basearmor = 7700;
	if (document.getElementById("boss").value == "Supremus") var basearmor = 7700;
	if (document.getElementById("boss").value == "Shade of Akama") var basearmor = 7700;
	if (document.getElementById("boss").value == "Teron Gorefiend") var basearmor = 6200;
	if (document.getElementById("boss").value == "Gurtogg Bloodboil") var basearmor = 7700;
	if (document.getElementById("boss").value == "Mother Shahraz") var basearmor = 6200;

	basearmor -= stats.pen;

	if (stats.sunder == true) basearmor -= 2600;
	if (stats.faerie_fire == true) basearmor -= 610;
	if (stats.recklessness == true) basearmor -= 800;
	if (basearmor < 0) basearmor = 0;
	var modarmor = (basearmor / (basearmor + 10557.5 )) * 100 /* Mitigation conversion from wowwiki */
	var idol_everbloom = 0;
	if (stats.everbloom == true) idol_everbloom = 88;
	var idol_wild = 0;
	if (stats.wild == true) idol_wild = 24;
	var set_nordrassil4 = 0;
	if (stats.nordrassil == true) set_nordrassil4 = 75;

	var idol_shadows = 0;
	if (stats.shadows == true) idol_shadows = 120;
	var set_thunderheart2 = 0;
	if (stats.thunderheart2 == true) set_thunderheart2 = 5;
	var set_thunderheart4 = 1;
	if (stats.thunderheart4 == true) set_thunderheart4 = 1.15;
	var item_relentless_earthstorm = 1;
	if (stats.diamond == true) item_relentless_earthstorm = 1.03;
	var talent_predatory_instincts = 1 + talents.pi * 0.02;
	var hit_bonus = stats.hit*52/82/1000;
	var expertise_bonus = stats.expertise*52/82/2.5*0.0025;
	var chance_crit = stats.crit / 100;
	if (stats.crusade == true) chance_crit += 0.03;
	if (chance_crit > 0.75) chance_crit = 0.75;
	var chance_miss = (0.09 - hit_bonus)
	if (chance_miss < 0) chance_miss = 0;
	var chance_dodge = (0.05 - expertise_bonus);
	if (chance_dodge < 0) chance_dodge = 0;
	chance_miss += chance_dodge;
	var attack_power = stats.ap;
	if (stats.hunter_mark == true) attack_power += 110 * 1.1;
	var melee_damage = stats.wpn + (768 + attack_power) / 14;
	var mangle_cost = 45 - 1 * talents.fe - set_thunderheart2;
	var total_mangle_cost = 1 / (1 - chance_miss) * (mangle_cost * (1 - chance_miss) + mangle_cost / 5 * chance_miss);
	var mangle_damage = (1 + talents.sf * 0.1) * (melee_damage * 1.6 + 264 + idol_wild);
	var shred_cost = 60 - 9 * talents.sa;
	var total_shred_cost = chance_miss * shred_cost / 5 + (1 - chance_miss) * shred_cost;
	var shred_damage = melee_damage * 2.25 + 405 + idol_everbloom + set_nordrassil4;

	var rip_cost = 30;
	var total_rip_cost = 1 / (1 - chance_miss) * rip_cost;


	var chance_white_crit = chance_crit;
	if (chance_white_crit > (0.75 - chance_miss)) chance_white_crit = 0.75 - chance_miss;

	var haste_bonus = stats.haste/15.76/100; /* Patch 2.2 nerf to Haste Rating */
	var attack_speed = 1 / (1 + haste_bonus);



	/* Starting immediately after Ripping, with energy to Mangle and GCD running */
	var dmg_melee = 0;
	var cycle_time = 1.5;
	var segment_time = 1.5;
	var energy_count = mangle_cost + 15;


	dmg_melee += segment_time / attack_speed * melee_damage * (0.7 * 0.25 + (0.75 - chance_miss - chance_white_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (chance_white_crit));

	DebugPrint("dmg_melee = " + String(dmg_melee));
	DebugPrint("segment_time = " + String(segment_time));
	DebugPrint("attack_speed = " + String(attack_speed));
	DebugPrint("melee_damage = " + String(melee_damage));
	DebugPrint("chance_miss = " + String(chance_miss));
	DebugPrint("chance_white_crit = " + String(chance_white_crit));


	if (stats.malorne == true) energy_count += segment_time / attack_speed * 20 * 0.04;
	/* GCD ends, Mangle hits */
	energy_count -= total_mangle_cost * (1 - segment_time / 30);
	DebugPrint("energy_count after mangle = " + String(energy_count));
	//var dmg_mangles = 1 / (1 - chance_miss) * mangle_damage * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit));
	var dmg_mangles = mangle_damage * ((1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (chance_crit));

	DebugPrint("mangle_damage: " + String(mangle_damage));
	DebugPrint("dmg_mangles: " + String(dmg_mangles));


//var combo_points = 1 / (1 - chance_miss) * ((1 - chance_miss) * (1 - chance_crit) + 2 * (1 - chance_miss) * (chance_crit));
	var combo_points = 1 + chance_crit;
	var number_attacks = (4 - 3 * chance_crit + 2 * Math.pow(chance_crit,2) - Math.pow(chance_crit,3)) / (1 - chance_miss);
	DebugPrint("New total Attacks: " + String(number_attacks));
	//var number_shreds = (5 - combo_points) / ((1 - chance_miss) * (1 - chance_crit) + 2 * (1 - chance_miss) * (chance_crit));
	var number_shreds = (number_attacks - (1 / (1 - chance_miss)));
	DebugPrint("number of shreds = " + String(number_shreds));
	if (stats.malorne == true) energy_count += 20 * 0.04;
	/* Mangle Debuff running, waiting for energy to Shred number_shreds times */
	if (stats.malorne == true) energy_count += (number_shreds - 1) * 20 * 0.04;
	segment_time = (number_shreds * total_shred_cost * (1 - number_shreds * total_shred_cost / 10 / number_shreds / 30) - energy_count) / 10;
	if (stats.malorne == true) segment_time -= segment_time / attack_speed * 20 * 0.04 / 10;
	cycle_time += segment_time;
	DebugPrint("total_shred_cost = " + String(total_shred_cost));
	DebugPrint("segment_time for shreds = " + String(segment_time));
	dmg_melee += segment_time / attack_speed * melee_damage * (0.7 * 0.25 + (0.75 - chance_miss - chance_white_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (chance_white_crit));

	DebugPrint("dmg_melee = " + String(dmg_melee));

	if (segment_time <= 12)
	{
					var dmg_shreds = number_shreds * shred_damage * 1.3 * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit));
	}
	else
	{
																																																													 number_shreds * shred_damage * 1.3 * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit));
					var dmg_shreds = ((12 / segment_time) * number_shreds * shred_damage * 1.3 * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit))) + ((1 - 12 / segment_time) * number_shreds * shred_damage * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit)));
	}

	DebugPrint("dmg_shreds = " + String(dmg_shreds));
	energy_count = 0;
	if (stats.malorne == true) energy_count += 20 * 0.04;
	/* 5 Combo points generated, waiting for energy to Rip + Mangle */
	segment_time = (mangle_cost + total_rip_cost * (1 - total_rip_cost / 10 / 30) - energy_count) / 10;
	if (stats.malorne == true) segment_time -= segment_time / attack_speed * 20 * 0.04 / 10;
	cycle_time += segment_time;

	DebugPrint("segment_time = " + String(segment_time));
	DebugPrint("cycle_time = " + String(cycle_time));

	dmg_melee += segment_time / attack_speed * melee_damage * (0.7 * 0.25 + (0.75 - chance_miss - chance_white_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (chance_white_crit));

	DebugPrint("dmg_melee = " + String(dmg_melee));

	var rip5 = (chance_crit - Math.pow(chance_crit,2) + Math.pow(chance_crit,3) - Math.pow(chance_crit,4));
	var rip4 = 1 - rip5;
	/* Checking on the possibility of completing the cycle too quickly */
	if (cycle_time < 12)
	{
					segment_time = 12 - cycle_time;
					cycle_time += segment_time;
					energy_count = segment_time*10;
					dmg_melee += segment_time / attack_speed * melee_damage * (0.7 * 0.25 + (0.75 - chance_miss - chance_white_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (chance_white_crit));
					if (stats.malorne == true) energy_count += segment_time / attack_speed * 20 * 0.04;
					var extra_shred = energy_count / (total_shred_cost * (1 - segment_time / 30));
					dmg_shreds += extra_shred * shred_damage * 1.3 * ((1 - chance_miss) * (1 - chance_crit) + 2 * talent_predatory_instincts * item_relentless_earthstorm * (1 - chance_miss) * (chance_crit));
					rip5 += extra_shred * Math.pow(rip4,2);
					rip4 -= extra_shred * Math.pow(rip4,2);
          number_shreds += extra_shred;
	};
	var dmg_rips = (rip5 * (attack_power * 0.24 + 1553 + idol_shadows) + rip4 * (attack_power * 0.24 + 1272 + idol_shadows * 4 / 5)) * 1.3 * set_thunderheart4;

	DebugPrint("dmg_rips = " + String(dmg_rips));

	DebugPrint("crit = " + String(chance_crit));
	DebugPrint("white crit = " + String(chance_white_crit));
	DebugPrint("miss = " + String(chance_miss));

	DebugPrint("shred dmg = " + String(dmg_shreds));
	DebugPrint("cycle time = " + String(cycle_time));

	DebugPrint("melee dmg = " + String(dmg_melee));
	DebugPrint("rip damage = " + String(dmg_rips));
	DebugPrint("rip = " + String(dmg_rips / ((dmg_mangles +dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) * 100));
	var dps = ((dmg_mangles + dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) / cycle_time; /* armor mitigation */

	DebugPrint("dmg_mangles = " + String(dmg_mangles));
	DebugPrint("dmg_shreds = " + String(dmg_shreds));
	DebugPrint("dmg_melee = " + String(dmg_melee));
	DebugPrint("cycle_time = " + String(cycle_time));

	if (stats.first_run == true)
	{
					var outstr = "Misses + Dodges: " + String(Math.round(chance_miss * 10000) / 100) + "%\n";
					outstr += "Crit % for White: " + String(Math.round(chance_white_crit * 10000) / 100) + "%\n";
					outstr += "Crit % for Yellow: " + String(Math.round((1 - chance_miss) * chance_crit * 10000) / 100) + "%\n";
					outstr += "Number of Shreds: " + String(Math.round(number_shreds * 1000) / 1000) + "\n";
					outstr += "Attack Speed: " + String(Math.round(attack_speed * 1000) / 1000) + "s\n";
					outstr += "Armor Mitigation: " + String(Math.round(modarmor * 10) / 10) + "%\n";
					outstr += "Mangle Damage: " + String(Math.round(dmg_mangles * (1 - modarmor / 100) / ((dmg_mangles + dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) * 10000) / 100) + "%\n";
					outstr +="Melee Damage: " + String(Math.round(dmg_melee * (1 - modarmor / 100) / ((dmg_mangles + dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) * 10000) / 100) + "%\n";
					outstr +="Rip Damage: " + String(Math.round(dmg_rips / ((dmg_mangles + dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) * 10000) / 100) + "%\n";
					outstr += "% Rips at 4cp: " + String(Math.round(rip4 * 10000) / 100) + "%\n";
					outstr += "% Rips at 5cp: " + String(Math.round(rip5 * 10000) / 100) + "%\n";
	outstr += "Shred Damage: " + String(Math.round(dmg_shreds * (1 - modarmor / 100) / ((dmg_mangles + dmg_shreds + dmg_melee) * (1 - modarmor / 100) + dmg_rips) * 10000) / 100) + "%\n";
					outstr += "Cycle Time: " + String(Math.round(cycle_time * 100) / 100) + "s\n";
					DebugPrint(outstr);
	};

	return dps * (1 + 0.02 * talents.nat);
}

DebugPrint(GetDPS(
	{
		pen:0,
		hit:142,
		expertise:20,
		crit:30,
		ap:2500,
		wpn:10,
		haste:50,
		sunder:true,
		faerie_fire:true,
		first_run:true
	},
	{
		pi:5,
		fe:5,
		sf:2,
		sa:2,
		nat:5
	}
));