var MeetResults = {};

MeetResults.DEFAULT_POINT_INDICATOR = '-';

MeetResults.DivePoint = function(sIndicator, iPointValue, sReason) {
	this.sIndicator = sIndicator || MeetResults.DEFAULT_POINT_INDICATOR;
	this.iPointValue = iPointValue || 1;
	this.sReason = sReason || null;
};

MeetResults.TeamRound = function(aroPoints) {
	this.aroPoints = aroPoints || [];
	this._iTotalPoints = 0;
	this._iTotalBusts = 0;
	
	this.iGetTotalPoints = function() { return this._iTotalPoints; };
	this.iGetTotalBusts = function() { return this._iTotalBusts; };
			
	this.CalculateTotals();
};

MeetResults.TeamRound.prototype.CalculateTotals = function() {
	this._iTotalPoints = 0;
	this._iTotalBusts = 0;
	
	var iPoints;
	for (var ix = 0; ix < this.aroPoints.length; ix++) {
		iPoints = this.aroPoints[ix].iPointValue;
		this._iTotalPoints += iPoints;
		if (iPoints <= 0) {
			this._iTotalBusts += (Math.abs(iPoints) + 1);
		}
	}
	
	if (this._iTotalPoints < 0) {
		this._iTotalPoints = 0;
	}
};

MeetResults.TeamResult = function(sClass, iClassRank, sName, sTeamNumber, sTeamLink, aroTeamRounds, arsTeamMembers) {
	this.sClass = sClass || '';
	this.iClassRank = iClassRank || 1;
	this.sName = sName || '';
	this.sTeamNumber = sTeamNumber || '';
	this.sTeamLink = sTeamLink || null;
	this.aroTeamRounds = aroTeamRounds || [];
	this.arsTeamMembers = arsTeamMembers || [];
	
	this._iTotalPoints = 0;
	this._iTotalBusts = 0;
	this._dblAverage = 0;
	this._iRank = 0;
	
	this.iGetTotalPoints = function() { return this._iTotalPoints; };
	this.iGetTotalBusts = function() { return this._iTotalBusts; };
	this.dblGetAverage = function() { return this._dblAverage; };
	this.iGetRank = function() { return this._iRank; };
	
	this.CalculateTotals();
};

MeetResults.TeamResult.prototype.CalculateTotals = function() {
	this._iTotalPoints = 0;
	this._iTotalBusts = 0;
	this._dblAverage = 0;
	
	if (this.aroTeamRounds.length > 0) {
		for (var ix = 0; ix < this.aroTeamRounds.length; ix++) {
			this._iTotalPoints += this.aroTeamRounds[ix].iGetTotalPoints();
			this._iTotalBusts += this.aroTeamRounds[ix].iGetTotalBusts();
		}
		
		this._dblAverage = (this._iTotalPoints / this.aroTeamRounds.length);
		// round to 2 decimals
		this._dblAverage = Math.round(this._dblAverage * 100) / 100;
	}
};

MeetResults.ClassRounds = function(sClass, arsRounds) {
	this.sClass = sClass;
	this.arsRounds = arsRounds;
};

MeetResults._sortTeamResults = function(oTeamResultA, oTeamResultB) {
	if (oTeamResultA.iClassRank != oTeamResultB.iClassRank) {
		return oTeamResultA.iClassRank - oTeamResultB.iClassRank;
	}
	// return negative since we want the highest score first
	return -(oTeamResultA.iGetTotalPoints() - oTeamResultB.iGetTotalPoints());
};

MeetResults.Results = function(aroClassRounds, aroTeamResults) {
	this.aroClassRounds = aroClassRounds;
	this.aroTeamResults = aroTeamResults.sort(MeetResults._sortTeamResults);
	
	this.CalculateRanks();
};

MeetResults.Results.prototype.CalculateRanks = function() {
	if (this.aroTeamResults.length > 0) {
		var sClass = '';
		var iRank = 1;
		
		var oResults = null;
		for (var ix = 0; ix < this.aroTeamResults.length; ix++) {
			oResults = this.aroTeamResults[ix];
			if (oResults.sClass != sClass) {
				sClass = oResults.sClass;
				iRank = 1;
			}
			else {
				iRank++;
			}
			
			oResults._iRank = iRank;
			if (ix > 0 && oResults.sClass == this.aroTeamResults[ix-1].sClass && oResults.iGetTotalPoints() == this.aroTeamResults[ix-1].iGetTotalPoints()) {
				oResults._iRank = this.aroTeamResults[ix-1].iGetRank();
			}
		}
	}
};

MeetResults.GenerateResults = function(aroTeamInfo, aroTeamRoundWithInfo, aroClassRounds) {
	aroTeamRoundWithInfo = aroTeamRoundWithInfo.sort(MeetResults._sortTeamRoundWithInfo);
	var aroTeamResults = [];
	for (var ixTeam = 0; ixTeam < aroTeamInfo.length; ixTeam++) {
		var oTeamResult = MeetResults._oTeamResultFromTeamAndRounds(aroTeamInfo[ixTeam], aroTeamRoundWithInfo);
		if (oTeamResult !== null) {
			aroTeamResults.push(oTeamResult);
		}
	}
	
	return new MeetResults.Results(aroClassRounds, aroTeamResults);
};

MeetResults._oTeamResultFromTeamAndRounds = function(oTeamInfo, aroTeamRoundWithInfo) {
	var aroTeamRounds = [];
	for (var ixRound = 0; ixRound < aroTeamRoundWithInfo.length; ixRound++) {
		if (aroTeamRoundWithInfo[ixRound].sTeamNumber == oTeamInfo.sTeamNumber) {
			aroTeamRounds.push(aroTeamRoundWithInfo[ixRound].oTeamRound);
		}
	}
	if (aroTeamRounds.length > 0) {
		//function(sClass, iClassRank, sName, sTeamNumber, sTeamLink, aroTeamRounds, arsTeamMembers) {
		return new MeetResults.TeamResult(oTeamInfo.sClass, oTeamInfo.iClassRank, oTeamInfo.sName, oTeamInfo.sTeamNumber, oTeamInfo.sTeamLink, aroTeamRounds, oTeamInfo.arsTeamMembers);
	}
	else {
		return null;
	}
};

MeetResults._sortTeamRoundWithInfo = function(oTeamRoundWithInfoA, oTeamRoundWithInfoB) {
	if (oTeamRoundWithInfoA.sTeamNumber != oTeamRoundWithInfoB.sTeamNumber) {
		return oTeamRoundWithInfoA.sTeamNumber - oTeamRoundWithInfoB.sTeamNumber;
	}
	else {
		return	oTeamRoundWithInfoA.iRound - oTeamRoundWithInfoB.iRound;
	}
};

MeetResults.TeamRoundWithInfo = function(sTeamNumber, iRound, oTeamRound) {
	this.sTeamNumber = sTeamNumber;
	this.iRound = iRound;
	this.oTeamRound = oTeamRound;
};

MeetResults.TeamInfo = function(sClass, iClassRank, sName, sTeamNumber, sTeamLink, arsTeamMembers) {
	this.sClass = sClass;
	this.iClassRank = iClassRank;
	this.sName = sName;
	this.sTeamNumber = sTeamNumber;
	this.sTreamLink = sTeamLink;
	this.arsTeamMembers = arsTeamMembers;
};

// shorthand function for building a TeamRound
function _a() {
	var aroTeamRounds = [];
	for (var ix = 0; ix < arguments.length; ix++) {
		var oRound = arguments[ix];
		if (typeof oRound == 'number') {
			var oPoint = new MeetResults.DivePoint();
			oPoint.iPointValue = oRound;
			if (oPoint.iPointValue == 0) { oPoint.sIndicator = 'X'; }
			aroTeamRounds.push(oPoint);
		}
		else if (typeof oRound == 'string') {
			aroTeamRounds.push(new MeetResults.DivePoint('X', 0, oRound));
		}
		else {
			aroTeamRounds.push(new MeetResults.DivePoint(oRound[0], oRound[1], oRound[2]));
		}
	}
	return new MeetResults.TeamRound(aroTeamRounds);
}

// shorthand function for building a TeamResult
function _b() {
	//MeetResults.TeamResult = function(sClass, iClassRank, sName, sTeamNumber, sTeamLink, aroTeamRounds, arsTeamMembers) {
	return new MeetResults.TeamResult(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6]);
}

// shorthand function for building a TeamRoundWithInfo
function _c() {
	return new MeetResults.TeamRoundWithInfo(arguments[0], arguments[1], arguments[2]);
}

// shorthand function for building a TeamInfo object
function _d() {
	return new MeetResults.TeamInfo(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5]);
}

// shorthand function for building a ClassRounds object
function _e() {
	return new MeetResults.ClassRounds(arguments[0], arguments[1]);
}