
onerror=errorHandler;

var exception_logged = false;

function errorHandler(errMessage,url,line){
	if (exception_logged) return;
	
	exception_logged = true;
	
  var error="Exception: " + errMessage+ "\n";
  error+="URL: " + url + "\n";
  error+="Line: " + line + "\n\n";
	error+="Sign: " + sign.to_string() + "\n\n";

	var d = new Date();
	var curr_min = d.getMinutes();
	var curr_sec = d.getSeconds();
	var curr_msec = d.getMilliseconds();

	error+="Time: " + curr_min + ":" + curr_sec + ":" + curr_msec + "\n\n";
	error+="Log: \n" + log_text();
	
	if ($$('admin')) alert(error);
	
	error = encodeURIComponent(error);
	var url = "/contact/report_exception?user_question[name]=exception&user_question[email_or_phone]=0&user_question[question]=" + error;
	
	$.ajax({
		url: "/contact/report_exception?user_question[name]=exception&user_question[email_or_phone]=0&user_question[question]=" + error,
		data: "",
		type: "post"
	});

  return true;
}

var debug_log = [];
var debug_log_index = 0;
var max_debug_log_items = 40;

function log_text()
{
	var i = debug_log_index-1;
	var cnt = 0;
	
	var result = "";
	
	for (var cnt = 0; cnt < max_debug_log_items; cnt++)
	{
		var j = (i - cnt + max_debug_log_items) % max_debug_log_items;
		result += debug_log[j] + "\n";
	}

	result += debug_log[debug_log_index] + "\n";
	return result;
}

function log(_log_text)
{
	var d = new Date();
	var curr_min = d.getMinutes();
	var curr_sec = d.getSeconds();
	var curr_msec = d.getMilliseconds();
	
	debug_log[debug_log_index] = curr_min + ":" + curr_sec + ":" + curr_msec + " " + _log_text;
	debug_log_index++;
	if (debug_log_index == max_debug_log_items)
		debug_log_index = 0;
}

function getStackTrace() {

var mode;
try {(0)()} catch (e) {
    mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
}

switch (mode) {
    case 'Firefox' : return function () {
        try {(0)()} catch (e) {
            return e.stack.replace(/^.*?\n/,'').
                           replace(/(?:\n@:0)?\s+$/m,'').
                           replace(/^\(/gm,'{anonymous}(').
                           split("\n");
        }
    };

    case 'Opera' : return function () {
        try {(0)()} catch (e) {
            var lines = e.message.split("\n"),
                ANON = '{anonymous}',
                lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
                i,j,len;

            for (i=4,j=0,len=lines.length; i<len; i+=2) {
                if (lineRE.test(lines[i])) {
                    lines[j++] = (RegExp.$3 ?
                        RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
                        ANON + RegExp.$2 + ':' + RegExp.$1) +
                        ' -- ' + lines[i+1].replace(/^\s+/,'');
                }
            }

            lines.splice(j,lines.length-j);
            return lines;
        }
    };

    default : return function () {
        var curr  = arguments.callee.caller,
            FUNC  = 'function', ANON = "{anonymous}",
            fnRE  = /function\s*([\w\-$]+)?\s*\(/i,
            stack = [],j=0,
            fn,args,i;

        while (curr) {
            fn    = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
            args  = stack.slice.call(curr.arguments);
            i     = args.length;

            while (i--) {
                switch (typeof args[i]) {
                    case 'string'  : args[i] = '"'+args[i].replace(/"/g,'\\"')+'"'; break;
                    case 'function': args[i] = FUNC; break;
                }
            }

            stack[j++] = fn + '(' + args.join() + ')';
            curr = curr.caller;
        }

        return stack;
    };
}

};