
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)
{
  //console.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;
    };
  }

};
