// skills.js

/*
  3EProfiler character sheet source file.
  Copyright (C) 2007 Myth-Weavers Games
  **
*/

// void SkillCalcRanks(void)
// Tallies the total number of skill points spent, weighting the ranks in
// each skill with whether or not it's a cross class skill.
function SkillCalcRanks()
{
	var total = 0;
	// Calculate the total ranks.
	var slots = document.getElementById("skills").rows.length - 3;

	for (var i = 1; i <= slots; i++)
	{
		var num = FormatNumber(i);
		total += GetNum(sheet()["Skill" + num + "Rank"]);
	}

	// Set the value.
	document.getElementById("totalbaseranks").innerHTML = total;

}

// void SkillCalc(node)
// Recalculates the skill modifier for a skill. Function expects one of
// the input nodes for the skill row to be passed to it.
function SkillCalc(node)
{

	// Determine which skill is being adjusted (the first 7 chars of the
	// node name are always "SkillXX", regardless of which row the input is
	// from.
	var skill = String(node.name).substr(0, 7);

	ZeroFill(
		sheet()[skill + "AbMod"],
		sheet()[skill + "Rank"],
		sheet()[skill + "MiscMod"]);

	sheet()[skill + "Mod"].value = Add(
		sheet()[skill + "AbMod"].value,
		sheet()[skill + "Rank"].value,
		sheet()[skill + "MiscMod"].value);
}

// void SkillLookUp(node)
// Performs a lookup of the skill name to try to find the skill's
// primary ability. If the skill is found, the ability is set then the
// onchange events for the ability modifier is triggered.
function SkillLookUp(node, extended)
{

	// Parse the info from the node.
	var skill = GetText(node);

	if (typeof skillKeys[skill] == "undefined")
	{
		return;
	}

	if (typeof abilityKeys[skillKeys[skill]] == 'undefined') {
		sheet()[node.name + "Ab"].value = "-";
	} else {
		sheet()[node.name + "Ab"].value = abilityKeys[skillKeys[skill]];
		SkillLookUpKeyAb(sheet()[node.name + "Ab"]);
	}
}

// void SkillLookUpKeyAb(node)
// Retrieves the skills key ability modifier and recalculates the skill
// modifier accordingly. The node passed to this function should be the
// Key Ability node.
function SkillLookUpKeyAb(node)
{

	// Can't make any assumptions about the node value, since the user may
	// have written anything.
	var ability = GetText(node);
  
	if (ability == "str") ability = "Str";
	else if (ability == "dex") ability = "Dex";
	else if (ability == "con") ability = "Con";
	else if (ability == "int") ability = "Int";
	else if (ability == "wis") ability = "Wis";
	else if (ability == "cha") ability = "Cha";
	else
	{
		// Not a valid ability name.
		return;
	}

	// If we don't have a modifier, return without doing anything else.
	if (!(sheet()[ability + "Mod"].value.length || sheet()[ability + "TempMod"].value.length))
		return;

	// Determine if skill is cross-class.
	var skillRow = node.parentNode.parentNode;

	// If a temp mod exists, use it, otherwise use the regular one.
	var mod = String(sheet()[ability + "TempMod"].value).length > 0
		? GetNum(sheet()[ability + "TempMod"])
		: GetNum(sheet()[ability + "Mod"]);
		sheet()[node.name + "Mod"].value = mod;


	SkillCalc(node);
}

// void SkillSort(sortfunc)
// Sorts the skill table according to the sorting function that is passed
// to sortfunc. SkillSort contains members that can act as sorting
// functions for the Array.sort() member.
function SkillSort(sortfunc)
{
	// Create a shortcut to the rows of the skills table.
	var rows = document.getElementById("skills").rows;

	// Now copy all the data in each row (the first two are headers and
	// the last is a footer).
	var rows_c = new Array();
	for (var i = 2; i < rows.length - 3; i++)
	{
		r = new Object();
		r.skill = rows[i].cells[0].firstChild.value;
		r.ab = rows[i].cells[1].firstChild.value;
		r.mod = rows[i].cells[2].firstChild.value;
		r.abmod = rows[i].cells[4].firstChild.value;
		r.rank = rows[i].cells[6].firstChild.value;
		r.misc = rows[i].cells[8].firstChild.value;
		rows_c.push(r);
	}

	// Sort the data.
	rows_c.sort(sortfunc);

	// Now, restore the sorted data.
	for (var i = 2; i < rows.length -3; i++)
	{
		var r = rows_c.shift();
		rows[i].cells[0].firstChild.value = r.skill;
		rows[i].cells[1].firstChild.value = r.ab;
		rows[i].cells[2].firstChild.value = r.mod;
		rows[i].cells[4].firstChild.value = r.abmod;
		rows[i].cells[6].firstChild.value = r.rank;
		rows[i].cells[8].firstChild.value = r.misc;
	}

}

SkillSort.ByName = function(a, b)
{
	if ((a.skill.length == 0) && (b.skill.length == 0))
		return 0;
	else if (a.skill.length == 0)
		return 1;
	else if (b.skill.length == 0)
		return -1;
	return a.skill.localeCompare(b.skill);
}

SkillSort.ByAbility = function(a, b)
{
	if ((a.ab.length == 0) && (b.ab.length == 0))
		return SkillSort.ByName(a, b);
	else if (a.ab.length == 0)
		return 1;
	else if (b.ab.length == 0)
		return -1;

	// Custom order:
	var key = {'str': 1, 'dex': 2, 'con': 3, 'int': 4, 'wis': 5, 'cha': 6};
	var comp = key[a.ab.toLowerCase()] - key[b.ab.toLowerCase()];
	if (comp)
		// If different, return the comparison.
		return comp;
	else
		// If equal, return the result of sorting by name.
		return SkillSort.ByName(a, b);
}

SkillSort.ByMod = function(a, b)
{
	return SkillSort._ByNumber(a, b, "mod");
}

SkillSort.ByAbMod = function(a, b)
{
	return SkillSort._ByNumber(a, b, "abmod");
}

SkillSort.ByRank = function(a, b)
{
	return SkillSort._ByNumber(a, b, "rank");
}

SkillSort.ByMisc = function(a, b)
{
	return SkillSort._ByNumber(a, b, "misc");
}

SkillSort._ByNumber = function(a, b, prop)
{
	numa = parseFloat(a[prop]);
	numb = parseFloat(b[prop]);
	if ((isNaN(numa)) && (isNaN(numb)))
		return SkillSort.ByName(a, b);
	else if (isNaN(numa))
		return 1;
	else if (isNaN(numb))
		return -1;
	if (numa == numb)
		return SkillSort.ByName(a, b);
	else
		return (numa > numb) ? -1 : 1;
}

// Fill the skill table with the core SWRPG skill set.
function SkillAutoFill()
{

	// Verify before continuing.
	if (!confirm("AutoFill will initialize the skill table with the core MNM skill set. This will clear any existing data.\n\nAre you sure you want to continue?"))
		return;

	// First clear the table.
	_skillClear();
	_skillFill();
}

// Clear the entire skill table.
function SkillClear()
{

	// Verify before actually clearing.
	if (!confirm("Clearing the skill table will remove ALL skill data.\n\nAre you sure you want to continue?"))
		return;

	_skillClear();
	SkillCalcRanks();
}

//////////////////////////////////////////////////////////////////////////
// Internal functions

// Clear the skill table.
function _skillClear()
{
	var rows = document.getElementById("skills").rows;
	for (var i = 2; i < rows.length - 1; i++)
	{
		rows[i].cells[0].firstChild.value = '';
		rows[i].cells[1].firstChild.value = '';
		rows[i].cells[2].firstChild.value = '';
		rows[i].cells[4].firstChild.value = '';
		rows[i].cells[6].firstChild.value = '';
		rows[i].cells[8].firstChild.value = '';
	}

}

// Fill the skill table with the SWRPG skillset.
function _skillFill()
{
	var row = 2;
	var skilltable = document.getElementById("skills");
	for (var skill in skillKeys)
	{

		// Don't alter if we already have some data.
		// (Can happen from an legacy character on first load).
		if (skilltable.rows[row].cells[0].firstChild.value)
			continue;

		// Set the skill and the key ability.
		skilltable.rows[row].cells[0].firstChild.value = skill;
		SkillLookUp(skilltable.rows[row].cells[0].firstChild, false);
		row++;
	}

}

// void _calcSkills(ability)
// Resets the ability modifier and recalculates the skills whose key
// ability match skillname.
function _calcSkills(ability)
{
	var numskills = document.getElementById("skills").rows.length - 4;
	for (var i = 1; i <= numskills; i++)
	{
		var num = FormatNumber(i);
		if (String(sheet()["Skill" + num + "Ab"].value).toLowerCase() == ability)
			SkillLookUpKeyAb(sheet()["Skill" + num + "Ab"]);
	}
}
