// JavaScript Document
//Point Source identifiers
var PSYCHE = 0, HIDE = 1, PROTECTION = 2, STEALTH = 3, ATTACK = 4, SHOOTING = 5, 
	SPEED = 6, FLIGHT = 7, SWIM = 8, CLIMB = 9, VITALS = 10, MAGIC = 11;

//Quick Mastery value and Custom value identifiers		
var	VALUE = 11;
var CLASSIFICATION = 12;

UPS   = new Array(4, 2, 4, 6, 4, 8, 4, 8, 4, 4);
DOWNS = new Array(2, 1, 2, 0, 2, 0, 2, 4, 0, 0);

//Point Source Object
function PointSource(id, value, upPoints, downPoints)
{
	/*FIELDS*/
	this.sourceId = id;
	this.sourceValue = value;
	this.sourceBase = value;
	this.skillPoints = 0;
	this.pointIncrease = upPoints;
	this.pointDecrease = downPoints;
}

//Skill Object
function Skill(name, source, phase, d, val, proc, always, success, fail, mastery, maint)
{
	this.skillName = name;
	this.pointSource = source;
	this.skillPhase = phase;
	this.dice = parseInt(d);
	this.proficiency = parseInt(d);
	this.value = parseInt(val);
	this.mastery = false;
	
	this.skillProcedure = proc;
	this.skillAlways = always;
	this.skillSuccess = success;
	this.skillFailure = fail;
	this.skillMastery = mastery;
	this.skillMaintenance = maint;

	this.getPrerequisite = getPrerequisite;
}

function getPrerequisite()
{
	req	= this.skillAlways.indexOf("Prerequisite:");
	if (req < 0)
		return ("none");
		
	reqSkillStart = this.skillAlways.indexOf(": ") + 2;
	reqSkillEnd = this.skillAlways.indexOf(":", reqSkillStart);
	return this.skillAlways.substr(reqSkillStart, reqSkillEnd - reqSkillStart);
}

//Figure Object
function Figure(type, name, mult)
{
	/*FIELDS*/
	//A list of skill objects.
	this.figureSkills = new Array();
	
	//A list of point sources
	this.pointSources = new Array();
	
	//A semicolon delimited string listing all of the expansions
	this.expansions = "";
		
	this.figureName = name;						//The name of the figure typed in by the user
	this.figureType = type;						//
	this.figureClassification = ""				//The figure's classification, read from the database
	this.figureValue = 0;						//The figure's point value
	this.figureBaseValue = 0;
	this.multiplier = mult;						//The multiplier used during customization

	/*METHODS*/
	this.generateSkillPoints = generateSkillPoints;		//Determines the number of skill points per source
	this.modifySkillPoints = modifySkillPoints;
	this.addToSource = addToSource;
	this.subtractFromSource = subtractFromSource;
}

//Uses the multiplier to determine how many skill points the figure has for each point source
function generateSkillPoints()
{
	//Generates the basic skill points
	for (i = PSYCHE; i <= CLIMB; i++)
	{
		if (i == STEALTH)
		{
			var srcval = parseInt(this.pointSources[i].sourceValue) + parseInt(this.pointSources[PROTECTION].sourceValue);
			this.pointSources[i].skillPoints = srcval * this.multiplier;
		}
		else
			if (i == SHOOTING)
			{
				var srcval = parseInt(this.pointSources[i].sourceValue) + parseInt(this.pointSources[ATTACK].sourceValue);
				this.pointSources[i].skillPoints = srcval * this.multiplier;
			}
			else
				if (i == FLIGHT)
				{
					var srcval = parseInt(this.pointSources[i].sourceValue) * parseInt(this.pointSources[SPEED].sourceValue);
					this.pointSources[i].skillPoints = srcval * this.multiplier;
				}
				else
					if (i == SWIM)
					{
						var srcval = parseInt(this.pointSources[i].sourceValue) + parseInt(this.pointSources[SPEED].sourceValue);
						this.pointSources[i].skillPoints = srcval * this.multiplier;
					}
					else
						if (i == CLIMB)
						{
							var srcval = parseInt(this.pointSources[i].sourceValue) + parseInt(this.pointSources[SPEED].sourceValue);
							this.pointSources[i].skillPoints = srcval * this.multiplier;
						}
						else
						{
							var srcval = parseInt(this.pointSources[i].sourceValue);
							this.pointSources[i].skillPoints = srcval * this.multiplier;
						}
		if (this.pointSources[i].skillPoints < 0)
			this.pointSources[i].skillPoints = 0;
	}

	//If the figure is Magical, this loads the magic points.
	if (this.figureClassification.indexOf("Magical") >= 0)
	{
		this.pointSources[MAGIC].skillPoints = this.pointSources[PSYCHE].sourceValue * this.multiplier;
		this.pointSources[MAGIC].sourceValue = this.pointSources[PSYCHE].sourceValue * this.multiplier;
	}
}

//Adjusts the skill points based on input from the user.
/*
	skillIdx = index of the skill in the list
	
	source = identifier of the source
	
	Modifier is + for adding points from the source to the skill and - for taking points from the
	skill and adding them to the source.
*/
function modifySkillPoints(skillIdx, source, modifier)
{
	//Copy the skill into a temporary variable.
	skill = this.figureSkills[skillIdx];
	
	//You can't modify a skill if there are no skill points OR
	//you are reducing the skill below the minimum proficiency OR
	//you are raising the skill above the maximum proficiency
	if (this.pointSources[source].skillPoints - modifier < 0 || skill.proficiency + modifier < skill.dice || 
		skill.proficiency + modifier > skill.dice * 6 )
		return false;
		
	this.pointSources[source].skillPoints -= modifier;
	skill.proficiency += modifier;
	
	//If raising the proficiency, check to see if the value of the figure goes up.
	if (modifier > 0)
	{
		fig.figureValue = parseInt(fig.figureValue) + parseInt(skill.value);
	}
	
	if (modifier < 0)
	{
			fig.figureValue -= skill.value;
	}
	
	return true;
}

function addToSource(sourceIdx)
{
	var srcval = parseInt(this.pointSources[sourceIdx].sourceValue);
	var srcbase = parseInt(this.pointSources[sourceIdx].sourceBase);
	
	//Can't add to the source modifiers if they've reached 10
	if (sourceIdx == STEALTH || sourceIdx == SHOOTING || sourceIdx == FLIGHT || sourceIdx == CLIMB || sourceIdx == SWIM)
	{
		if (srcval >= 10)
			return;
	}
	else
		//Can't add to a source if it's greater than its base + half its base
		if (srcval >= srcbase + (srcbase / 2))
			return;
			
	//Not enough skill points
	if (sourceIdx == STEALTH || sourceIdx == SHOOTING || sourceIdx == FLIGHT || sourceIdx == CLIMB || sourceIdx == SWIM)
		if (this.pointSources[sourceIdx].skillPoints < Math.abs(this.pointSources[sourceIdx].sourceValue) * 2)
			return;
			
	if (this.pointSources[sourceIdx].skillPoints < Math.abs(this.pointSources[sourceIdx].sourceValue))
		return;

	//All is well, raise the source.
	if (this.pointSources[sourceIdx].sourceValue >= this.pointSources[sourceIdx].sourceBase)
	{
		this.pointSources[sourceIdx].skillPoints -= Math.abs(this.pointSources[sourceIdx].sourceValue);
		if (sourceIdx == STEALTH || sourceIdx == SHOOTING || sourceIdx == FLIGHT || sourceIdx == CLIMB || sourceIdx == SWIM)
			this.pointSources[sourceIdx].skillPoints -= Math.abs(this.pointSources[sourceIdx].sourceValue);
		this.figureValue =  parseInt(this.figureValue) + parseInt(this.pointSources[sourceIdx].pointIncrease);
	}
	else
		this.figureValue = parseInt(this.figureValue) + parseInt(this.pointSources[sourceIdx].pointDecrease);
		
	this.pointSources[sourceIdx].sourceValue += 1;

	//Ajust the magic points
	if (this.pointSources[MAGIC].sourceValue > 0)
	{
		this.pointSources[MAGIC].sourceBase = this.pointSources[PSYCHE].sourceValue * this.multiplier;
		this.pointSources[MAGIC].sourceValue = this.pointSources[MAGIC].sourceBase;
	}
}

function subtractFromSource(sourceIdx)
{
	var srcval = parseInt(this.pointSources[sourceIdx].sourceValue);
	var srcbase = parseInt(this.pointSources[sourceIdx].sourceBase);
	
	//Can't lower the source modifiers past -10
	if (sourceIdx == STEALTH || sourceIdx == SHOOTING || sourceIdx == FLIGHT || sourceIdx == CLIMB || sourceIdx == SWIM)
	{
		if (srcval <= -10)
			return;
	}
	else
	//A source cannot go below 1 or half again its base value.
	if (srcval <= 1 || srcval < srcbase / 2)
		return;

	//Perform the reduction.
	if (this.pointSources[sourceIdx].sourceValue > this.pointSources[sourceIdx].sourceBase)
	{
		this.pointSources[sourceIdx].skillPoints += Math.abs(this.pointSources[sourceIdx].sourceValue - 1);
		if (sourceIdx == STEALTH || sourceIdx == SHOOTING || sourceIdx == FLIGHT || sourceIdx == CLIMB || sourceIdx == SWIM)
			this.pointSources[sourceIdx].skillPoints += Math.abs(this.pointSources[sourceIdx].sourceValue - 1);
		this.figureValue =  parseInt(this.figureValue) - parseInt(this.pointSources[sourceIdx].pointIncrease);
	}
	else
		this.figureValue = parseInt(this.figureValue) - parseInt(this.pointSources[sourceIdx].pointDecrease);

	this.pointSources[sourceIdx].sourceValue -= 1;

	//Ajust the magic points
	if (this.pointSources[MAGIC].sourceValue > 0)
	{
		this.pointSources[MAGIC].sourceBase = this.pointSources[PSYCHE].sourceValue * this.multiplier;
		this.pointSources[MAGIC].sourceValue = this.pointSources[MAGIC].sourceBase;
	}
}


/***********************************************************************************************************************************/

function displayFigure(figure)
{
	win = window.open("", figure.figureName);
	doc = win.document;

	doc.open();
	//doc.title = figure.figureName;
	
	//The Static Stuff
	doc.write("<html><head><title>" + figure.figureName + "</title>");
	doc.write("<style type = 'text/css'>table{background-color:gainsboro;font-family:Bookman Old Style;font-size:12;");
	doc.write("border-style:outset;border-width:5;border-spacing:3;}");
	doc.write("td{border-style:inset;border-width:1;padding:3 3 3 3;}</style>");
	doc.write("</head><body style = 'orphans:0;font-size:10pt'>");

	drawFigure(doc, figure, 0);

	doc.write("</body></html>");

	doc.close();
}

function drawFigure(doc, fig, idx)
{

	//OUTER TABLE
	doc.write("<table style = 'width:100%;'>");
	doc.write("<tr><td>");
	
	//BASIC INFO TABLE
	doc.write("<table id = 'tbl_figureDescription' style = 'width:100%'>");
	doc.write("<tr>");
	doc.write("<td style = 'width:25%;background-color:darkgray'>" + fig.figureName + "</td>");
	doc.write("<td style = 'width:25%;background-color:darkgray'>" + fig.figureType + " ");
	doc.write("</td>");
	doc.write("<td style = 'width:25%;background-color:darkgray'>" + fig.figureClassification + "</td>");
	doc.write("<td style = 'width:15%;background-color:darkgray'>" + fig.figureValue + " points ");
	doc.write("</td>");
	doc.write("</td>");
	doc.write("<td style = 'width:10%;background-color:darkgray'>Multiplier: " + fig.multiplier);
	doc.write("</td>");
	doc.write("</tr>");
	doc.write("</table></td></tr>");
	//CLOSE BASIC INFO TABLE
	
	//POINT DISPLAY TABLE NEW
	doc.write("<tr><td>");
	doc.write("<table style = 'width:100%'>");

	doc.write("<tr>");
	doc.write("<td id = 'td_psychebase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("<td id = 'td_hidebase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("<td id = 'td_protectionbase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("<td id = 'td_attackbase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("<td id = 'td_speedbase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("<td id = 'td_vitalsbase" + idx + "' style = 'background-color:darkgray'></td>");
	doc.write("</tr>");
	
	doc.write("</table></td></tr>");
	//CLOSE POINT DISPLAY TABLE NEW
	
	//SKILLS TABLE
	doc.write("<tr><td>");
	doc.write("<table id = 'tbl_skills'" + idx + " style = 'width:100%'>");
	doc.write("<tr>");
	doc.write("<td style = 'width:33%;vertical-align:top'><table id = 'tbl_skillsleft" + idx + "' style = 'width:100%;border-width:0px'><tr>");
	doc.write("<td>Skill</td><td>Source</td><td>Phase</td><td>Dice</td><td>Proficiency</td>");
	doc.write("</tr></table></td>");
	doc.write("<td style = 'width:33%;vertical-align:top'><table id = 'tbl_skillsmid" + idx + "' style = 'width:100%;border-width:0px'><tr>");
	doc.write("<td>Skill</td><td>Source</td><td>Phase</td><td>Dice</td><td>Proficiency</td>");
	doc.write("</tr></table></td>");
	doc.write("<td style = 'width:33%;vertical-align:top'><table id = 'tbl_skillsright" + idx + "' style = 'width:100%;border-width:0px'><tr>");
	doc.write("<td>Skill</td><td>Source</td><td>Phase</td><td>Dice</td><td>Proficiency</td>");
	doc.write("</tr></table></td>");
	doc.write("</table></td></tr>");
	//CLOSE SKILLS TABLE
	
	doc.write("</table>");
	//CLOSE OUTER TABLE
	
	doc.getElementById("td_psychebase" + idx).innerHTML = "Psyche: " + fig.pointSources[PSYCHE].sourceValue + " & Magic Points: " + fig.pointSources[MAGIC].sourceValue;
	doc.getElementById("td_hidebase" + idx).innerHTML = "Hide: " + fig.pointSources[HIDE].sourceValue;
	doc.getElementById("td_protectionbase" + idx).innerHTML = "Protection: " + fig.pointSources[PROTECTION].sourceValue + " <i>stealth</i>(";
	if (fig.pointSources[STEALTH].sourceValue > 0)
		doc.getElementById("td_protectionbase" + idx).innerHTML += "+";
	doc.getElementById("td_protectionbase" + idx).innerHTML += fig.pointSources[STEALTH].sourceValue + ")";
			
	doc.getElementById("td_attackbase" + idx).innerHTML = "Attack: " + fig.pointSources[ATTACK].sourceValue + " <i>shooting</i>(";
	if (fig.pointSources[SHOOTING].sourceValue > 0)
		doc.getElementById("td_attackbase" + idx).innerHTML += "+";
	doc.getElementById("td_attackbase" + idx).innerHTML += fig.pointSources[SHOOTING].sourceValue + ")";
			
	doc.getElementById("td_speedbase" + idx).innerHTML = "Speed: " + fig.pointSources[SPEED].sourceValue + " <i>flight</i>(x";
	doc.getElementById("td_speedbase" + idx).innerHTML += fig.pointSources[FLIGHT].sourceValue + ") <i>swim</i>(";
	if (fig.pointSources[SWIM].sourceValue > 0)
		doc.getElementById("td_speedbase" + idx).innerHTML += "+";
	doc.getElementById("td_speedbase" + idx).innerHTML += fig.pointSources[SWIM].sourceValue + ") <i>climb</i>(";
	if (fig.pointSources[CLIMB].sourceValue > 0)
		doc.getElementById("td_speedbase" + idx).innerHTML += "+";
	doc.getElementById("td_speedbase" + idx).innerHTML += fig.pointSources[CLIMB].sourceValue + ")";
			
	doc.getElementById("td_vitalsbase" + idx).innerHTML = "Vitals: " + fig.pointSources[VITALS].sourceValue;
	
	//The Dynamic Stuff
	leftRowNum = 1;
	midRowNum = 1;
	rightRowNum = 1;
	for (ctr = 0; ctr < fig.figureSkills.length; ctr++)
	{
		if (ctr < fig.figureSkills.length / 3)
		{
			skillDisplay = doc.getElementById("tbl_skillsleft" + idx);
			tr = skillDisplay.insertRow(leftRowNum);
			leftRowNum++;
		}
		else
		if (ctr < (fig.figureSkills.length * 2) / 3)
		{
			skillDisplay = doc.getElementById("tbl_skillsmid" + idx);
			tr = skillDisplay.insertRow(midRowNum);
			midRowNum++;
		}
		else
		{
			skillDisplay = doc.getElementById("tbl_skillsright" + idx);
			tr = skillDisplay.insertRow(rightRowNum);
			rightRowNum++;
		}
		
			td = tr.insertCell(0);
			td.innerHTML = fig.figureSkills[ctr].skillName;
			if (fig.figureSkills[ctr].dice == 0)
				td.style.fontStyle = "italic";

			td = tr.insertCell(1);
			td.innerHTML = fig.figureSkills[ctr].pointSource;

			td = tr.insertCell(2);
			td.innerHTML = fig.figureSkills[ctr].skillPhase;

			td = tr.insertCell(3);
			td.innerHTML = fig.figureSkills[ctr].dice;
			
			td = tr.insertCell(4)
			td.innerHTML = fig.figureSkills[ctr].proficiency;
	}
}

function displaySquad(squad)
{
	doc = window.open().document;
	doc.open();
	
	//The Static Stuff
	doc.write("<html><head><title>Squad</title>");
	doc.write("<style type = 'text/css'>");
		doc.write("table{width:100%;font-size:8pt;border-style:solid;border-width:1}");
	doc.write("</style>");
	doc.write("</head><body style = 'orphans:0;>");

	numlines = new Array();
	for (f = 0; f < squad.length; f++)
	{
		numlines.push(squad[f].figureSkills.length / 3 + 4);
	}

	currpage = 0;
	pagenum = 1
	for (f = 0; f < squad.length; f++)
	{
		if (currpage + numlines[f] > 33)
		{
			doc.write("<div style = 'page-break-after:always;text-align:center'>- page " + pagenum + " -</div>");
			currpage = 0;
			pagenum++;
		}
		
		drawFigure(doc, squad[f], f);
		currpage += numlines[f];
	}
	
	doc.write("<div style = 'text-align:center'>- page " + pagenum + " -</div>");
	doc.write("</body></html>");
	
	doc.close();
}
