// --------------------------------------- Error Handling
//
// Written by Brian Davies
// January 2005
// Copyright 2005, Cognitive Arts
//
// --------------

// --------------------------------------- Docs

/*
// Use

Just call parent.activateeventhander from every course page.

Requires 6 variables from lms/prefs.js

PROJECT_ID
PROJECT_COURSE_ID
INCIDENT_POST_PAGE
INCIDENT_SEARCH_PAGE
REPORT_JS_ERRORS_AS_INCIDENTS
SUPPRESS_JS_ERROR_ALERTS


// Nomenclature

parse syntax error means something like:
	var moose.gorf = new VideoRental () [] !!! Yippee;

illegal reference error means something like:
	window.fds.fdsjklfd ();

// Caveats

1.  If you have a parse syntax error in a file that loads before the
file containing window.onerror, or IN the file containing window.error
(even *after* the call to window.onerror) that hoses the whole thing.

2.  If you have an illegal reference error in a file that loads before
window.onerror, that is not caught, but does not hose the whole thing
(later errors are caught).

3.  If you have an illegal reference error in the file containing
window.onerror prior to the window.onerror call, that is not caught,
and it hoses the whole thing.  If the illegal reference error is after
window.onerror, it is caught and all works well.


// Sample Error Causing Code

function causeillegalreferenceerror ()
{
	window.fds.fdsjklfd ();
}

function causeobjectnotfounderror ()
{
	document.getElementById ('missingdiv').style.visibility = "inherit";
}

function causenestederror ()
{
	causeillegalreferenceerror ();
}

causeillegalreferenceerror ();
causeobjectnotfounderror ();
causenestederror ();

var moose.gorf = new VideoRental () [] !!! Yippee;

*/

// --------------------------------------- Invocation Function

function activateerrorhandler (where)
{
	if (REPORT_JS_ERRORS_AS_INCIDENTS)
	{
		where.onerror = reporterrorhandler;
	}
	else
	{
		where.onerror = suppresserrorhandler;
	}
}

// --------------------------------------- Stack Trace

function getfunctionname (func)
{
	var name = func.toString ().match (/function (\w*)/) [1];

	// NN only?  doesn't help firefox
	//if ((name == null) || (name.length == 0))
	//	return "no caller";  // anonymous is something different
	//else
		return name;
}

function stacktrace (offender)
{
	var stack = "";
	var stackelement = "";

	for (var func = offender; func != null; func = func.caller)
	{
		try
		{
			var functionname = getfunctionname (func.callee);
			var functionargs = eval (functionname).arguments;

			stackelement = functioncalltostring (functionname, functionargs) + "\n";
		}
		catch (err)
		{
			stackelement = func.callee.toString () + "\n";
		}

		stack = stackelement + stack;

		// NN only?  doesn't help firefox
		//if (func.caller == func)
		//	break;
	}

	return stack;
}

function functioncalltostring (functionname, functionargs)
{
	var result = functionname + " (";

	for (var i = 0; i < functionargs.length; i ++)
	{
		if (typeof (functionargs [i]) == "string")
			result += "'" + functionargs [i] + "'";
		else
			result += functionargs [i];

		if ((i + 1) < functionargs.length)
			result += ", ";
	}

	result += ")";

	return result;
}

// --------------------------------------- Incident Box Functions

function reportincidenthandler (url)
{
	reporterrorhandler ("", url, null, true);
}

function searchincidents (situation)
{
	var postingurl = INCIDENT_SEARCH_PAGE + "?projectID=" + PROJECT_ID + "&theurl=" + situation;
	var opener = findatlasopener (true);
	
	if (opener != null)
	{
		window.opener.location.href = postingurl;
		window.opener.focus ();
	}
	else
	{
		x = window.open (postingurl, "searchincidents");
		x.focus ();
	}
}

// --------------------------------------- Handlers

function reporterrorhandler (message, url, line, incidentp)
{
	if (incidentp)
	{
		var title = "Create Incident";
		var blurb = "To have an issue reported to Cognitive Arts, enter your e-mail address, a brief summary of the problem, and any comments you would like to make, and then click \"Submit\"."
		var summary = "";
		var trace = "";
	}
	else
	{
		var title = "Report This Error";
		var blurb = "An error has occurred.  To report this to Cognitive Arts, enter your e-mail address, and any comments you would like to make, and then click \"Submit\"."
		var summary = message;
		var trace = stacktrace (arguments.caller);
	}

	var errwin = window.open ("", "", "menubar=no,status=no,width=440,height=350,scrollbars=no,toolbars=yes,resizable=no");

	errwin.document.write ('<html><head>'
		+ '<title>' + title + '</title>'
		+ '<style type="text/css">body, p, li, td, textarea, button { font-family: Arial,Verdana,sans-serif; font-size: 11px; text-align: top;} h1 { font-weight: bold; font-size: 13px; margin-bottom: 8px; } p { margin: 0px 16px; } button { font-weight: bold; } td.header { font-weight: bold; }</style>'
		// stripcharacter from http://www.shawnolson.net
		+ '\<script type="text/javascript"\>function stripcharacter(words,character){ var spaces = words.length; for(var x = 0; x<spaces; ++x){ words = words.replace(character, ""); } return words; }'
		+ 'function errorformsubmit () { if (window.opener.parent.setSessionVariable) { window.opener.parent.setSessionVariable("errorusername",document.getElementById ("errform").username.value) } if( stripcharacter(document.getElementById("errform").username.value, " ") == "" || stripcharacter(document.getElementById("errform").summary.value," ") == "" || stripcharacter(document.getElementById("errform").comment.value," ") == ""){ alert("All fields are required.");  } else { document.getElementById (\'errform\').submit(); } }\</script\>'
		+ '</head>'
		+ '<body><h1>' + title + '</h1>'
		+ '<p>' + blurb + '</p>'
		+ '<form action="' + INCIDENT_POST_PAGE + '" id="errform" method="post">'
		+ '<input type="hidden" name="url" value="' + url + '"/>'
		+ '<input type="hidden" name="os" value="' + window.navigator.platform + '"/>'
		+ '<input type="hidden" name="browser" value="' + window.navigator.userAgent + '"/>'
		+ '<input type="hidden" name="projectid" value="' + PROJECT_ID + '"/>'
		+ '<input type="hidden" name="projectcourseid" value="' + PROJECT_COURSE_ID + '"/>'
		+ '<input type="hidden" name="stacktrace" value="' + trace + '"/>'
		+ '<input type="hidden" name="submittedp"/>'
		+ '<table cellpadding="5">'
		+ '<tr><td class="header" nowrap>E-mail&nbsp;Address:</td><td><input type="text" name="username" size="20" maxlength="50"  value=""/></td></tr>'
		+ '<tr><td class="header">Summary:</td><td><input type="text" name="summary" size="43" maxlength="120" value="' + summary + '"/></td></tr>'
		+ '<tr><td class="header" valign="top">Comments:</td><td valign="top"><textarea name="comment" rows="8" cols="55"></textarea></td></tr>'
		+ '<tr><td colspan="2" align="right"><button onclick="window.close ();" style="margin-right: 10px;">Cancel</button><button onclick="errorformsubmit();" style="margin-right: 30px;">Submit &raquo;</button></td></tr>'
		+ '</table>'
		+ '</form></body></html>');

	if (parent.sessionVariableDefined && parent.sessionVariableDefined ("errorusername"))
	{
		errwin.document.getElementById ('errform').username.value = parent.getSessionVariable("errorusername");
	}

	errwin.focus ();
	
	return SUPPRESS_JS_ERROR_ALERTS;
}


function suppresserrorhandler ()
{
	return SUPPRESS_JS_ERROR_ALERTS;
}

// --------------------------------------- Utilities

function findatlasopener (findproductionmodeonlyp)
{
	if (window.opener && window.opener.atlasproductionmodep
			&& ((findproductionmodeonlyp && window.opener.atlasproductionmodep () == true) || ! findproductionmodeonlyp))
		return window.opener;
	else
		return null;
}

// --------------------------------------- Invocation

activateerrorhandler (window);

// --------------------------------------- End Of File
