// abilities.js



/*

  3EProfiler character sheet source file.

  Copyright (C) 2008 Myth-Weavers Games

  **

*/



// **



// Maintains the ability scores.



// Dependencies:

//    everytning...almost



// void OnAbilityChanged(node)

// Called by the document when an ability score is changed.

function OnAbilityChanged(node)

{

	// Check if the node is a Temp score or not.

	var isTemp = _isTempAbility(node);

	// Determine the name of the ability we're working with.

	var ability = String(node.name).substr(0, 3);

	

	// If the score was deleted, delete the modifier...

  



	if (!isTemp) {

		// if it is not, check if there is a temp score. If yes, do not modify the modifier.

		if (String(sheet()[node.name + "Temp"].value).length != 0) {

			return;

		} else { // if there isn't a temp score, fill in the modifier and parse the rest.

			sheet()[node.name + "Mod"].value = _calcMod(sheet()[node.name].value);

		}

	} else {

		// If it IS a temp score, do the rest.

		

		// Check if the temp score is deleted

		if (String(node.value).length == "") { // if it is, use the base one instead.

    		sheet()[ability + "Mod"].value = _calcMod(sheet()[ability].value);

  		} else {

			sheet()[ability + "Mod"].value = _calcMod(sheet()[node.name].value);
			
		}

	}

	

  // Attempt to call the ability's apply method (extract the ability

  // name from the first three characters of the node name.

  _applyAbility(node.name);

  // Calculates Workspace

  AttackCalc();

  DamageCalc();

}



//////////////////////////////////////////////////////////////////////////

// Internal functions



// void _applyAbility(string)

// Applies an ability modifier to all dependent objects.

function _applyAbility(nodename)

{

  // Determine the name of the ability we're working with.

  var ability = String(nodename).substr(0, 3);



  eval("_calcDep" + ability + "('" + sheet()[ability + "Mod"].value + "')");

}



// void _calcDepStr(string)

// Calculates the strength dependencies, using the supplied modifier

// to fill in any slots that use a strength modifier.

function _calcDepStr(mod)

{



  // Remove the leading "+" if it exists.

  mod = Clean(mod);

  

  var halfLevel = _calcHalfLevel();

  

  sheet().StrModPlusHalfLevel.value = Add(sheet().StrMod.value, halfLevel);



  if ( parseInt(sheet().ConMod.value) <= parseInt(sheet().StrMod.value) ) {

    //The fortitude save.

  	sheet().FortAbility.value = mod;

	SaveCalc('Fort');

  }



  // Update the skills.

  _calcSkills('str');

}



// void _calcDepCon(string)

// Calculate the constitution dependencies, using the supplied modifier

// to fill in any slots that use a constitution modifier.

function _calcDepCon(mod)

{



  mod = Clean(mod);

  

  var halfLevel = _calcHalfLevel();

  sheet().ConModPlusHalfLevel.value = Add(sheet().ConMod.value, halfLevel);

  

  if ( parseInt(sheet().ConMod.value) >= parseInt(sheet().StrMod.value) ) {



    //The fortitude save.

  	sheet().FortAbility.value = mod;

	 	 SaveCalc('Fort');

  }



  // Update the skills.

  _calcSkills('con');

}



// void _calcDepDex(string)

// Calculate the dexterity dependencies, using the supplied modifier

// to fill in any slots that use a dexterity modifier.

function _calcDepDex(mod)

{



  // Remove the leading "+" from the mod if it exists.

  mod = Clean(mod);

  

  sheet().InitDexMod.value = mod;



  var halfLevel = _calcHalfLevel();

  sheet().DexModPlusHalfLevel.value = Add(sheet().DexMod.value, halfLevel);



  if (parseInt(sheet().DexMod.value) >= parseInt(sheet().IntMod.value)) {

    // The reflex save.

  	sheet().ReflexAbility.value = mod + parseInt(sheet().ShieldBonus.value);

	  	SaveCalc('Reflex');

  }



  InitCalc();



	ACCalc();



  // Update the skills.

  _calcSkills('dex');

}





// void _calcDepInt(string)

// Calculate the intelligence dependencies, using the supplied modifier

// to fill in any slots that use an intelligence modifier.

function _calcDepInt(mod)

{

  mod = Clean(mod);



  var halfLevel = _calcHalfLevel();

  sheet().IntModPlusHalfLevel.value = Add(sheet().IntMod.value, halfLevel);

  

    if (parseInt(sheet().DexMod.value) <= parseInt(sheet().IntMod.value)) {

  // The reflex save.

  		sheet().ReflexAbility.value = mod + parseInt(sheet().ShieldBonus.value);

			  SaveCalc('Reflex');

	}

  

	ACCalc();

	

  // Update the skills.

  _calcSkills('int');

}



// void _calcDepWis(string)

// Calculate the wisdom dependencies, using the supplied modifier

// to fill in any slots that use a wisdom modifier.

function _calcDepWis(mod)

{



  mod = Clean(mod);

  

  var halfLevel = _calcHalfLevel();

  sheet().WisModPlusHalfLevel.value = Add(sheet().WisMod.value, halfLevel);

  

  if ( parseInt(sheet().WisMod.value) >= parseInt(sheet().ChaMod.value)) {

    // The will save.

 	 sheet().WillAbility.value = mod;

	 SaveCalc('Will');

  }



  // Update the skills

  _calcSkills('wis');

}



// void _calcDepCha(string)

// Calculate the charisma dependencies, using the supplied modifier

// to fill in any slots that use a charisma modifier.

function _calcDepCha(mod)

{



  mod = Clean(mod);

  

  var halfLevel = _calcHalfLevel();

  sheet().ChaModPlusHalfLevel.value = Add(sheet().ChaMod.value, halfLevel);

  

  if ( parseInt(sheet().WisMod.value) <= parseInt(sheet().ChaMod.value)) {

    // The will save.

  	sheet().WillAbility.value = mod;

	 	 SaveCalc('Will');

  }



  //Update the skills

  _calcSkills('cha');

}



// string _calcMod(string)

// Returns the modifier for a supplied ability score. The return value is

// a string with a leading "+" sign if the modifier is positive.

function _calcMod(abilityScore)

{

  // Ensure a numeric value.

  var score = parseInt(abilityScore);

  if (isNaN(score))

    return "--";



  // Calculate the modifier.

  if ((score % 2) == 1)

    score -= 11;

  else

    score -= 10;

  score /= 2;



  // Append a "+" sign if positive

  if (score > 0)

    score = "+" + score;



  // Return the modifier.

  return score;

}



// bool _isTempAbility(node)

// Returns true if the supplied node is a temporary ability score.

function _isTempAbility(node)

{

  var names = new Array("Str", "Dex", "Con", "Int", "Wis", "Cha");

  for (var i in names)

    if (node.name == names[i])

      return false;

  return true;

}