var buffer = [];

function docWrite(html) {
	buffer.push(html);
}

function docOut() {
	doc.write(buffer.join(''));
}

function insertTick(testName, className) {
	var elTick = doc.createElement('div');
	elTick.className = className + ' tick';
	elTick.title = testName + ' ' + className;
	elTick.id = 'dc' + count + 's' + set;
	elProgress.appendChild(elTick);
}

function progressClick(e) {
	e = e || window.event;

	var el = e.target || e.srcElement;
	if (el.nodeType == 3) {
		el = el.parentNode;
	}

	if (el && el.id) {
		window.location.href = '#' + el.id.substring(1);
	}
}

function writeResult(str, className, testName) {
	docWrite('<div id="c' + count + 's' + set + '" class="result ' + className + '">' + className.substring(0, 1).toUpperCase() + className.substring(1) + ': ' + testName + (str ? ': ' + str : '') + '<\/div>');
}
function assertEquals(a, b, testName) {
	var c = a, d = b;

	count++;

	if (typeof c == 'string') {
		c = "'" + c + "'";
	}
	if (typeof d == 'string') {
		d = "'" + d + "'";
	}
	if (a === b) {
		writeResult(c + ' is ' + d, 'pass', testName);
		insertTick(testName, 'pass');
		return true;
	}
	insertTick(testName, 'fail');
	failures++;
	writeResult(c + ' is not ' + d, 'fail', testName);
}
function assertNotEquals(a, b, testName) {
	var c = a, d = b;

	count++;

	if (typeof c == 'string') {
		c = "'" + c + "'";
	}
	if (typeof d == 'string') {
		d = "'" + d + "'";
	}
	if (a !== b) {
		writeResult(c + ' is not ' + d, 'pass', testName);
		insertTick(testName, 'pass');
		return true;
	}
	insertTick(testName, 'fail');
	failures++;
	writeResult(c + ' is ' + d, 'fail', testName);
}
function skipTest(testName) {
	count++;
	insertTick(testName, 'indeterminate');
	skips++;
	writeResult('', 'indeterminate', testName);
}

function testErrored(testName) {
	count++;
	insertTick(testName, 'error');
	failures++;
	errors++;
	writeResult('', 'error', testName);
}

function getPercent(score, total) {
	var str = Math.round(score * 10000 / total) + '', l = str.length;
	if (l == 1) {
		return str == '0' ? '0.00' : '0.0' + str;
	}
	return (str.slice(0, -2) || '0') + '.' + str.substring(str.length - 2);
}

function writeResults(caption, summary) {
	docWrite('<table summary="' + summary + '" rules="groups" class="results"><caption>' + caption + '<\/caption><thead><tr><th><\/th><th>Count<\/th><th>Percent<\/th><\/tr><\/thead><tbody><tr><td class="pass">Passed<\/td><td class="total">' + (count - failures - skips) + '<\/td><td class="total">' + getPercent(count - failures - skips, count) + '<\/td><\/tr><\/tbody><tbody><tr class="subtotals"><td>Usable<\/td><td class="total">' + (count - failures - skips) + '<\/td><td class="total">' + getPercent(count - failures - skips, count) + '<\/td><\/tr><\/tbody><tr><td class="error">Errored<\/td><td class="total">' + errors + '<\/td><td class="total">' + getPercent(errors, count) + '<\/td><\/tr><tr><td class="fail">Failed<\/td><td class="total">' + (failures - errors) + '<\/td><td class="total">' + getPercent(failures - errors, count) + '<\/td><\/tr><\/tbody><tbody><tr class="subtotals"><td>Dysfunctional<\/td><td class="total">' + failures + '<\/td><td class="total">' + getPercent(failures, count) + '<\/td><\/tr><\/tbody><tbody><tr><td class="indeterminate">Skipped<\/td><td class="total">' + skips + '<\/td><td class="total">' + getPercent(skips, count) + '<\/td><\/tr><\/tbody><tbody><tr class="subtotals"><td>Impossible<\/td><td class="total">' + skips + '<\/td><td class="total">' + getPercent(skips, count) + '<\/td><\/tr><\/tbody><tfoot><tr><td>Totals<\/td><td class="total">' + count + '<\/td><td class="total">100.00<\/td><\/tr><\/tfoot><\/table>');
}

function writeAggregateResults(caption, summary, propTotals, attrTotals) {
	var totalFailures = propTotals.failures + attrTotals.failures;
	var totalErrors = propTotals.errors + attrTotals.errors;
	var totalSkips = propTotals.skips + attrTotals.skips;

	var totalCount = count * 2;

	docWrite('<table summary="' + summary + '" rules="groups" class="results"><caption>' + caption + '<\/caption><thead><tr><th><\/th><th>Count<\/th><th>Percent<\/th><\/tr><\/thead><tbody><tr><td class="sectiontitle">Passed<\/td><td colspan="2"><\/td><\/tr><tr><td class="pass">Attributes<\/td><td class="total">' + (count - attrTotals.failures - attrTotals.skips) + '<\/td><td class="total">' + getPercent(count - attrTotals.failures - attrTotals.skips, count) + '<\/td><\/tr><tr><td class="pass">Properties<\/td><td class="total">' + (count - propTotals.failures - propTotals.skips) + '<\/td><td class="total">' + getPercent(count - propTotals.failures - propTotals.skips, count) + '<\/td><\/tr><\/tbody><tbody><tr class="subtotals"><td>Usable<\/td><td class="total">' + (totalCount - totalFailures - totalSkips) + '<\/td><td class="total">' + getPercent(totalCount - totalFailures - totalSkips, totalCount) + '<\/td><\/tr><\/tbody><tr><td class="sectiontitle">Errored<\/td><td colspan="2"><\/td><\/tr>' + '<tr><td class="error">Attributes<\/td><td class="total">' + attrTotals.errors + '<\/td><td class="total">' + getPercent(attrTotals.errors, totalCount) + '<\/td><\/tr><tr><td class="error">Properties<\/td><td class="total">' + propTotals.errors + '<\/td><td class="total">' + getPercent(propTotals.errors, totalCount) + '<\/td><\/tr>' + '<tr><td class="sectiontitle">Failed<\/td><td colspan="2"><\/td><\/tr>' + '<tr><td class="fail">Attributes<\/td><td class="total">' + (attrTotals.failures - attrTotals.errors) + '<\/td><td class="total">' + getPercent(attrTotals.failures - attrTotals.errors, totalCount) + '<\/td><\/tr><tr><td class="fail">Properties<\/td><td class="total">' + (propTotals.failures - propTotals.errors) + '<\/td><td class="total">' + getPercent(propTotals.failures - propTotals.errors, totalCount) + '<\/td><\/tr>' + '<\/tbody><tbody><tr class="subtotals"><td>Dysfunctional<\/td><td class="total">' + totalFailures + '<\/td><td class="total">' + getPercent(totalFailures, totalCount) + '<\/td><\/tr><\/tbody><tbody><tr><td class="sectiontitle">Skipped<\/td><td colspan="2"><\/td><\/tr>' + '<tr><td class="indeterminate">Attributes<\/td><td class="total">' + attrTotals.skips + '<\/td><td class="total">' + getPercent(attrTotals.skips, totalCount) + '<\/td><\/tr><tr><td class="indeterminate">Properties<\/td><td class="total">' + propTotals.skips + '<\/td><td class="total">' + getPercent(propTotals.skips, totalCount) + '<\/td><\/tr>' + '<\/tbody><tbody><tr class="subtotals"><td>Impossible<\/td><td class="total">' + totalSkips + '<\/td><td class="total">' + getPercent(totalSkips, totalCount) + '<\/td><\/tr><\/tbody><tfoot><tr><td>Totals<\/td><td class="total">' + totalCount + '<\/td><td class="total">100.00<\/td><\/tr><\/tfoot><\/table>');
	
}
