/**
 * I provide a simple logging functionality to jQuery that interacts with the firebug console and if
 * that is not available a HTML based javascript logger is created instead.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * @author      William Buick <wilbuick@gmail.com>
 * @copyright   Copyright (c) 2008 William Buick
 * @license     http://www.gnu.org/licenses/gpl.html
 * @version     $Id: $
 * @package     jquery
 * @subpackage  plugins.log
 */
(function($) {

    /**
     * I define a log namespace inside jQuery that contains common methods to provide logging
     * functionality to jQuery.
     */
    $.log = {

        /**
         * Enable or disable logging by setting this value true or false.
         *
         * @access public
         * @var boolean
         */
        enable : false,

        /**
         * I am used to record debug level log messages.
         *
         * @access public
         * @param mixed message
         * @return void
         */
        debug : function(message)
        {
            log(message, 'debug');
        },

        /**
         * I am used to record info level log messages.
         *
         * @access public
         * @param mixed message
         * @return void
         */
        info : function(message)
        {
            log(message, 'info');
        },

        /**
         * I am used to record warning level log messages.
         *
         * @access public
         * @param mixed message
         * @return void
         */
        warn : function(message)
        {
            log(message, 'warn');
        },

        /**
         * I am used to record error level log messages.
         *
         * @access public
         * @param mixed messages
         * @return void
         */
        error : function(message)
        {
            log(message, 'error');
        }

    };

    /**
     * I am a helper method that sends each element matched with the jQuery attribute selector to
        * the log as a debug message. This is useful for finding out esactly which elements a attribute
     * selector has returned.
     *
     * @access public
     * @return void
     */
    $.fn.debug = function()
    {
        return this.each(function() {
            log(this, 'debug');
        });
    };

    /**
     * I send a message to the console of a specified type that is supported by the window.console
     * object.
     *
     * @access private
     * @throws UnsupportedLogType
     * @param mixed message A string or object that is being sent to the logger
     * @param string type The type of log message
     * @return void
     */
    function log(message, type)
    {
        /**
         * If logging is not enabled, then do not continue further than this.
         */
        if (true !== $.log.enable) {
            return;
        }

        /**
         * If the log type is not supported by the window.console object then throw a error here
         * because I am not able to continue,
         */
        if ('function' !== typeof window.console[type]) {
            throw 'UnsupportedLogType';
        }

        /**
         * If the message is an object and firebug is not enabled, then convert the object into a
         * string to provide useful information for our custom logger.
         */
        var str = message;

        if (!window.console.firebug && 'object' === typeof message) {
            str = '&lt;';
            str += message.nodeName.toLowerCase();
            for (var i = 0; i < message.attributes.length; i++) {
                str += ' ' + message.attributes[i].nodeName.toLowerCase() + '="' + message.attributes[i].nodeValue + '"';
            }
            str += '&gt;';
        }

        window.console[type](str, type);
    };

    /**
     * If the browser does not support the window.console property, then mimic the functionality by
     * extending the window object dynamically and creating our own HTML based console within the
     * page its self.
     *
     * This code was borrowed from http://getfirebug.com as an alternative for the firebug
     * javascript console in other browsers.
     */
    if (!window.console || !window.console.firebug) {
        /**
         * I contain an array of debug methods available within the window.console object. All of
         * these are dynamically mapped to our own console writing function that writes debug
         * messages to our own javascript console based in HTML.
         */
        var console_types = [
            "log",
            "debug",
            "info",
            "warn",
            "error",
            "assert",
            "dir",
            "dirxml",
            "group",
            "groupEnd",
            "time",
            "timeEnd",
            "count",
            "trace",
            "profile",
            "profileEnd"
        ];

        window.console = {};

        for (var type in console_types) {
            window.console[console_types[type]] = function(msg, type)
            {
                $('#debug ol').prepend('<li class="' + type + '">' + msg + '</li>');
            };
        }

        /**
         * When the document has loaded, dynamically add the debug window into the html. All debug
         * messages will be written into this as HTML inside an ordered list.
         */
        $(document).ready(function() {
            if ($.log.enable === true) {
                $('html').addClass('debug');
                $(document.body).append('<div id="debug"><h6><span>Javascript Debugger</span></h6><ol></ol></div>');
            }
        });
    }

})(jQuery);

