/***

MochiKit.LoggingPane 1.3.1

See <http://mochikit.com/> for documentation, downloads, license, etc.

(c) 2005 Bob Ippolito.  All rights Reserved.

***/
if (typeof(dojo) != 'undefined') {
   dojo.provide('MochiKit.LoggingPane');
   dojo.require('MochiKit.Logging');
   dojo.require('MochiKit.Base');
}

if (typeof(JSAN) != 'undefined') {
   JSAN.use("MochiKit.Logging", []);
   JSAN.use("MochiKit.Base", []);
}

try {
   if (typeof(MochiKit.Base) == 'undefined' || typeof(MochiKit.Logging) == 'undefined') {
       throw "";
   }
} catch (e) {
   throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!";
}

if (typeof(MochiKit.LoggingPane) == 'undefined') {
   MochiKit.LoggingPane = {};
}

MochiKit.LoggingPane.NAME = "MochiKit.LoggingPane";
MochiKit.LoggingPane.VERSION = "1.3.1";
MochiKit.LoggingPane.__repr__ = function () {
   return "[" + this.NAME + " " + this.VERSION + "]";
};

MochiKit.LoggingPane.toString = function () {
   return this.__repr__();
};

MochiKit.LoggingPane.createLoggingPane = function (inline/* = false */) {
   var m = MochiKit.LoggingPane;
   inline = !(!inline);
   if (m._loggingPane && m._loggingPane.inline != inline) {
       m._loggingPane.closePane();
       m._loggingPane = null;
   }
   if (!m._loggingPane || m._loggingPane.closed) {
       m._loggingPane = new m.LoggingPane(inline, MochiKit.Logging.logger);
   }
   return m._loggingPane;
};

MochiKit.LoggingPane.LoggingPane = function (inline/* = false */, logger/* = MochiKit.Logging.logger */) {
   /* Use a div if inline, pop up a window if not */
   /* Create the elements */
   if (typeof(logger) == "undefined" || logger === null) {
       logger = MochiKit.Logging.logger;
   }
   this.logger = logger;
   var update = MochiKit.Base.update;
   var updatetree = MochiKit.Base.updatetree;
   var bind = MochiKit.Base.bind;
   var clone = MochiKit.Base.clone;
   var win = window;
   var uid = "_MochiKit_LoggingPane";
   if (typeof(MochiKit.DOM) != "undefined") {
       win = MochiKit.DOM.currentWindow();
   }
   if (!inline) {
       // name the popup with the base URL for uniqueness
       var url = win.location.href.split("?")[0].replace(/[:\/.><&]/g, "_");
       var name = uid + "_" + url;
       var nwin = win.open("", name, "dependent,resizable,height=200");
       if (!nwin) {
           alert("Not able to open debugging window due to pop-up blocking.");
           return undefined;
       }
       nwin.document.write(
           '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
           + '"http://www.w3.org/TR/html4/loose.dtd">'
           + '<html><head><title>[MochiKit.LoggingPane]</title></head>'
           + '<body></body></html>'
       );
       nwin.document.close();
       nwin.document.title += ' ' + win.document.title;
       win = nwin;
   }
   var doc = win.document;
   this.doc = doc;

   // Connect to the debug pane if it already exists (i.e. in a window orphaned by the page being refreshed)
   var debugPane = doc.getElementById(uid);
   var existing_pane = !!debugPane;
   if (debugPane && typeof(debugPane.loggingPane) != "undefined") {
       debugPane.loggingPane.logger = this.logger;
       debugPane.loggingPane.buildAndApplyFilter();
       return debugPane.loggingPane;
   }

   if (existing_pane) {
       // clear any existing contents
       var child;
       while ((child = debugPane.firstChild)) {
           debugPane.removeChild(child);
       }
   } else {
       debugPane = doc.createElement("div");
       debugPane.id = uid;
   }
   debugPane.loggingPane = this;
   var levelFilterField = doc.createElement("input");
   var infoFilterField = doc.createElement("input");
   var filterButton = doc.createElement("button");
   var loadButton = doc.createElement("button");
   var clearButton = doc.createElement("button");
   var closeButton = doc.createElement("button");
   var logPaneArea = doc.createElement("div");
   var logPane = doc.createElement("div");

   /* Set up the functions */
   var listenerId = uid + "_Listener";
   this.colorTable = clone(this.colorTable);
   var messages = [];
   var messageFilter = null;

   var messageLevel = function (msg) {
       var level = msg.level;
       if (typeof(level) == "number") {
           level = MochiKit.Logging.LogLevel[level];
       }
       return level;
   };

   var messageText = function (msg) {
       return msg.info.join(" ");
   };

   var addMessageText = bind(function (msg) {
       var level = messageLevel(msg);
       var text = messageText(msg);
       var c = this.colorTable[level];
       var p = doc.createElement("span");
       p.className = "MochiKit-LogMessage MochiKit-LogLevel-" + level;
       p.style.cssText = "margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: " + c;
       p.appendChild(doc.createTextNode(level + ": " + text));
       logPane.appendChild(p);
       logPane.appendChild(doc.createElement("br"));
       if (logPaneArea.offsetHeight > logPaneArea.scrollHeight) {
           logPaneArea.scrollTop = 0;
       } else {
           logPaneArea.scrollTop = logPaneArea.scrollHeight;
       }
   }, this);

   var addMessage = function (msg) {
       messages[messages.length] = msg;
       addMessageText(msg);
   };

   var buildMessageFilter = function () {
       var levelre, infore;
       try {
           /* Catch any exceptions that might arise due to invalid regexes */
           levelre = new RegExp(levelFilterField.value);
           infore = new RegExp(infoFilterField.value);
       } catch(e) {
           /* If there was an error with the regexes, do no filtering */
           logDebug("Error in filter regex: " + e.message);
           return null;
       }

       return function (msg) {
           return (
               levelre.test(messageLevel(msg)) &&
               infore.test(messageText(msg))
           );
       };
   };

   var clearMessagePane = function () {
       while (logPane.firstChild) {
           logPane.removeChild(logPane.firstChild);
       }
   };

   var clearMessages = function () {
       messages = [];
       clearMessagePane();
   };

   var closePane = bind(function () {
       if (this.closed) {
           return;
       }
       this.closed = true;
       if (MochiKit.LoggingPane._loggingPane == this) {
           MochiKit.LoggingPane._loggingPane = null;
       }
       this.logger.removeListener(listenerId);

       debugPane.loggingPane = null;

       if (inline) {
           debugPane.parentNode.removeChild(debugPane);
       } else {
           this.win.close();
       }
   }, this);

   var filterMessages = function () {
       clearMessagePane();

       for (var i = 0; i < messages.length; i++) {
           var msg = messages[i];
           if (messageFilter === null || messageFilter(msg)) {
               addMessageText(msg);
           }
       }
   };

   this.buildAndApplyFilter = function () {
       messageFilter = buildMessageFilter();

       filterMessages();

       this.logger.removeListener(listenerId);
       this.logger.addListener(listenerId, messageFilter, addMessage);
   };


   var loadMessages = bind(function () {
       messages = this.logger.getMessages();
       filterMessages();
   }, this);

   var filterOnEnter = bind(function (event) {
       event = event || window.event;
       key = event.which || event.keyCode;
       if (key == 13) {
           this.buildAndApplyFilter();
       }
   }, this);

   /* Create the debug pane */
   var style = "display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: " + this.logFont;
   if (inline) {
       style += "; height: 10em; border-top: 2px solid black";
   } else {
       style += "; height: 100%;";
   }
   debugPane.style.cssText = style;

   if (!existing_pane) {
       doc.body.appendChild(debugPane);
   }

   /* Create the filter fields */
   style = {"cssText": "width: 33%; display: inline; font: " + this.logFont};

   updatetree(levelFilterField, {
       "value": "FATAL|ERROR|WARNING|INFO|DEBUG",
       "onkeypress": filterOnEnter,
       "style": style
   });
   debugPane.appendChild(levelFilterField);

   updatetree(infoFilterField, {
       "value": ".*",
       "onkeypress": filterOnEnter,
       "style": style
   });
   debugPane.appendChild(infoFilterField);

   /* Create the buttons */
   style = "width: 8%; display:inline; font: " + this.logFont;

   filterButton.appendChild(doc.createTextNode("Filter"));
   filterButton.onclick = bind("buildAndApplyFilter", this);
   filterButton.style.cssText = style;
   debugPane.appendChild(filterButton);

   loadButton.appendChild(doc.createTextNode("Load"));
   loadButton.onclick = loadMessages;
   loadButton.style.cssText = style;
   debugPane.appendChild(loadButton);

   clearButton.appendChild(doc.createTextNode("Clear"));
   clearButton.onclick = clearMessages;
   clearButton.style.cssText = style;
   debugPane.appendChild(clearButton);

   closeButton.appendChild(doc.createTextNode("Close"));
   closeButton.onclick = closePane;
   closeButton.style.cssText = style;
   debugPane.appendChild(closeButton);

   /* Create the logging pane */
   logPaneArea.style.cssText = "overflow: auto; width: 100%";
   logPane.style.cssText = "width: 100%; height: " + (inline ? "8em" : "100%");

   logPaneArea.appendChild(logPane);
   debugPane.appendChild(logPaneArea);

   this.buildAndApplyFilter();
   loadMessages();

   if (inline) {
       this.win = undefined;
   } else {
       this.win = win;
   }
   this.inline = inline;
   this.closePane = closePane;
   this.closed = false;

   return this;
};

MochiKit.LoggingPane.LoggingPane.prototype = {
   "logFont": "8pt Verdana,sans-serif",
   "colorTable": {
       "ERROR": "red",
       "FATAL": "darkred",
       "WARNING": "blue",
       "INFO": "black",
       "DEBUG": "green"
   }
};


MochiKit.LoggingPane.EXPORT_OK = [
   "LoggingPane"
];

MochiKit.LoggingPane.EXPORT = [
   "createLoggingPane"
];

MochiKit.LoggingPane.__new__ = function () {
   this.EXPORT_TAGS = {
       ":common": this.EXPORT,
       ":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK)
   };

   MochiKit.Base.nameFunctions(this);

   MochiKit.LoggingPane._loggingPane = null;

};

MochiKit.LoggingPane.__new__();

MochiKit.Base._exportSymbols(this, MochiKit.LoggingPane);