//debug helper class to control popup windows
function DebugHelper()
{
    this.Active = true;
    this.OpenWindowOnFirstMessage = true;
    this.ShowException = true;
    this.ShowURL = true;
    this.ShowLastModified = false;
    this.ShowReferrer = false;
    this.VerboseMode = false;
    //reference to the popup window
    this.DebugWindow = null;
    this.CssStyleFile = new String("resources/scripts/devtools/debugHelper.css");
    this.WindowStyle = new String("left=0,top=0,width=300,height=300,scrollbars=yes,status=no,resizable=yes");
    //no spaces to run correctly on internet explorer
    this.WindowName = new String("JavascriptDebugWindow");
    this.WindowTitle = new String("Javascript Debug Window");
}

//method to show the debug window
//callback won't work for IE
DebugHelper.prototype.ShowWindow = function(callback, args)
{
   try
   {
       if( this.Active && (!this.DebugWindow || this.DebugWindow.closed) )
       {
          this.DebugWindow = window.open("", this.WindowName, this.WindowStyle);
            
            this.DebugWindow.opener = window;
            //open the document for writing
            this.DebugWindow.document.open();
          
            this.DebugWindow.document.write(
              "<html><head><title>" + this.WindowTitle + "</title>" +
              "<link rel='stylesheet' type='text/css' href='" + this.CssStyleFile + "' />" + 
              "</head><body><div id='renderSurface' style='width: 100%; height: 100%;' /></body></html>\n"
           );

           //prepare window to call callback function when it is loaded
           //callback won't work on IE because onload won't be called
           if( callback )
           {
             this.DebugWindow.context = this;
             this.DebugWindow.onload = function()
             {
                callback.apply(this.context, args);
             }
           }
           
           this.DebugWindow.document.close();
       }
   }
   catch(ex)
   {
      //ignore exception
   }
}      

//if the debug window exists, then write to it
DebugHelper.prototype.$Write = function(cssClass, message, url, lastModified, referrer) 
{
   try
   {
      if( this.Active )
      {
         if( this.OpenWindowOnFirstMessage && (!this.DebugWindow || this.DebugWindow.closed) )
         {
            //there is a issue related to IE's onload method of opened popups
            //IE won't call onload to execute the popup write method asynchronously
            //however, IE can write it directly, appearing that IE window.open releases script
            //flow only when popup's onload method has executed
            if( document.all )
            {            
               this.ShowWindow();
            }
            else
            {
               this.ShowWindow(this.$WriteAsync, [cssClass, message, url, lastModified, referrer]);
               return;
            }
         }

         if( this.DebugWindow && !this.DebugWindow.closed )
         {
             var msg = message;
             
             if( this.ShowURL && url != null )
                 msg += " at " + url;
                 
             if( this.ShowLastModified && lastModified != null )
                 msg += " last modified in " + lastModified;

             if( this.ShowReferrer && referrer != null )
                 msg += " referrer " + referrer;

             this.DebugWindow.document.getElementById("renderSurface").innerHTML = "<span class='" + cssClass + "'>" + msg + "</span>" + this.DebugWindow.document.getElementById("renderSurface").innerHTML;
           }
      }
   }
   catch(ex)
   {
      //ignore exception
   }
}

//window.onload will call this method when using the Just In Time window opening
//this way write don't get called before window document are ready to be used
DebugHelper.prototype.$WriteAsync = function(cssClass, message, url, lastModified, referrer) 
{
   this.$Write(cssClass, message, url, lastModified, referrer);
}

//write a message to debug window
DebugHelper.prototype.Message = function(message, url, lastModified, referrer)
{
   try
   {
       this.$Write("debugMessage", message, url, lastModified, referrer);
   }
   catch(ex)
   {
      //ignore exception
   }
}
//method shortcut
function $dm(message, url, lastModified, referrer)
{
    if( debugHelper )
        debugHelper.Message(message, url, lastModified, referrer);
}

//same as debug, plus another style applyied
DebugHelper.prototype.Warn = function(message, url, lastModified, referrer)
{
   try
   {
       this.$Write("debugWarn", message, url, lastModified, referrer);
   }
   catch(ex)
   {
      //ignore exception
   }
}

//same as debug, plus a strong style applyied
DebugHelper.prototype.Exception = function(message, url, lastModified, referrer)
{
   try
   {
       if( this.ShowException )
       {
           this.$Write("debugException", message, url, lastModified, referrer);
       }
   }
   catch(ex)
   {
      //ignore exception
   }
}

//if the debug window exists, then close it
DebugHelper.prototype.HideWindow = function() 
{
   try
   {
       if( this.DebugWindow && !this.DebugWindow.closed )
       {
          this.DebugWindow.close();
           this.DebugWindow = null;
         }
   }
   catch(ex)
   {
      //ignore exception
   }
}

var GameDebugHelper = function()
{
    this.KeyboardDebug = false;
    this.AIDebug = false;
    this.TilemapDebug = false;
    this.ImageDebug = false;
    this.StateChangeDebug = false;
}

GameDebugHelper.prototype = new DebugHelper();
GameDebugHelper.prototype.constructor = GameDebugHelper;

//create a global debug helper object
var debugHelper = new GameDebugHelper();
//you should show the window right here to get loading time errors or sintax errors
//debugHelper.ShowWindow();

//catch window errors also
function WindowOnError(msg, url, line)
{
   debugHelper.Exception(msg, line + " at " + url);
}

// window.onerror = WindowOnError;

