/* Copyright (c) 2008 Anirudh Sasikumar */
/* Author: Anirudh Sasikumar */
/* URL: http://anirudhs.chaosnet.org/blog/2008.01.22.html */

/* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or sell */
/* copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */
/* conditions: */

/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */

/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
/* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
/* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */

/* Comment: Adds a div to the body tag which gets populated with
 * uncaught javascript exceptions in an HTML AIR application. */


var airConsole = {
    
    /* set this to true if you want the console to trace to adl's
     * output rather than append to a div */
  traceonly: false,

  /* If traceonly is false, a div is appended to the body tag. This is
   * the id of that div. */
  divName: "airConsoleDiv",

  /* buffer if div is not available */
  errBuffer: "",

  /* custom fn to call if registered */
  funcCustom: null,

  /* listen for uncaught javascript exceptions */
  preInit: function()
  {
      window.htmlLoader.addEventListener(window.runtime.flash.events.HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION,
                                         airConsole.htmlErrorHandler);
      
  },
  
  /* append a div to the end of the body tag */
  init: function()
  {      
      var divObj = document.createElement('div');
      
      divObj.setAttribute("id", airConsole.divName);
      if ( document.getElementsByTagName('body').length > 0 )
      {
          document.getElementsByTagName('body')[0].appendChild(divObj);
          if ( airConsole.errBuffer.length > 0 )
          {
              airConsole.out(airConsole.errBuffer, null);
          }
      }
  },

  describeError: function ( errorDetail, stackTraceArr )
  {
      var resString = "<p style=\"border: 3px solid pink;background-color:yellow;\">JS Exception: " + errorDetail;
      if ( stackTraceArr != null )
      {
          for (var i = 0; i < stackTraceArr.length; i++)
          {
              resString += "<br/>Source:" + stackTraceArr[i].sourceURL;
              resString += "<br/>Line:" + stackTraceArr[i].line;
              resString += "<br/>Stack Trace:" + stackTraceArr[i].functionName;
          }
      }
      resString += "</p>";
      return resString;
  },

  /* this is called per exception */
  out: function(errDetail, stackTraceArr)
  {
      if ( airConsole.traceonly )
      {
          window.runtime.trace(airConsole.describeError(errDetail, stackTraceArr));
          return;
      }

      if ( airConsole.funcCustom )

      {
          if ( airConsole.errBuffer.length > 0 )
          {
              /* here only aggregated info is available */
              airConsole.funcCustom(airConsole.errBuffer, null);
              airConsole.errBuffer = "";
              /* check if we were called only to handle the buffered error */
              if ( stackTraceArr == null )
                  return;
          }

          airConsole.funcCustom(errDetail, stackTraceArr);
          return;
      }

      var consoleDiv = document.getElementById(airConsole.divName);
      if ( consoleDiv )
      {
          if ( airConsole.errBuffer.length > 0 )
          {
              consoleDiv.innerHTML += airConsole.errBuffer;
              airConsole.errBuffer = "";
              /* check if we were called only to handle the buffered error */
              if ( stackTraceArr == null )
                  return;
          }
          consoleDiv.innerHTML += airConsole.describeError(errDetail, stackTraceArr);
      }
      else
      {
          airConsole.errBuffer += airConsole.describeError(errDetail, stackTraceArr);
          air.trace("AirConsole Div not available (err buffered and will be printed when next err comes and div is available): " + airConsole.describeError(errDetail, stackTraceArr));
      }
  },

  /* handle the as event */
  htmlErrorHandler: function (event)
  {
      event.preventDefault();
      airConsole.out(event.exceptionValue, event.stackTrace);
  },

  registerHandler: function (fnin)
  {
      airConsole.funcCustom = fnin;
      /* pass all buffered errors */
      if ( airConsole.errBuffer.length > 0 )
      {
          /* here only aggregated info is available */
          airConsole.funcCustom(airConsole.errBuffer, null);
          airConsole.errBuffer = "";
      }
  }
  
};

/* listen for uncaught exceptions immediately */
airConsole.preInit();

/* load the div now */
window.addEventListener("load", airConsole.init, false);

