/**
 * jquery.dump.js
 * @author Torkild Dyvik Olsen
 * @version 1.0
 * 
 * A simple debug function to gather information about an object.
 * Returns a nested tree with information.
 * 
 */
(function($) {

    $.fn.dump = function() {
        return $.dump(this);
    }

    $.dump = function(object) {
        var recursion = function(obj, level) {
            if(!level) level = 0;
            var dump = '', p = '';
            for(i = 0; i < level; i++) p += "\t";
      
            t = type(obj);
            switch(t) {
                case "string":
                    return '"' + obj + '"';
                    break;
                case "number":
                    return obj.toString();
                    break;
                case "boolean":
                    return obj ? 'true' : 'false';
                case "date":
                    return "Date: " + obj.toLocaleString();
                case "array":
                    dump += 'Array ( \n';
                    $.each(obj, function(k,v) {
                        dump += p +'\t' + k + ' => ' + recursion(v, level + 1) + '\n';
                    });
                    dump += p + ')';
                    break;
                case "object":
                    dump += 'Object { \n';
                    $.each(obj, function(k,v) {
                        dump += p + '\t' + k + ': ' + recursion(v, level + 1) + '\n';
                    });
                    dump += p + '}';
                    break;
                case "jquery":
                    dump += 'jQuery Object { \n';
                    $.each(obj, function(k,v) {
                        dump += p + '\t' + k + ' = ' + recursion(v, level + 1) + '\n';
                    });
                    dump += p + '}';
                    break;
                case "regexp":
                    return "RegExp: " + obj.toString();
                case "error":
                    return obj.toString();
                case "document":
                case "domelement":
                    dump += 'DOMElement [ \n'
                    + p + '\tnodeName: ' + obj.nodeName + '\n'
                    + p + '\tnodeValue: ' + obj.nodeValue + '\n'
                    + p + '\tinnerHTML: [ \n';
                    $.each(obj.childNodes, function(k,v) {
                        if(k < 1) var r = 0;
                        if(type(v) == "string") {
                            if(v.textContent.match(/[^\s]/)) {
                                dump += p + '\t\t' + (k - (r||0)) + ' = String: ' + trim(v.textContent) + '\n';
                            } else {
                                r--;
                            }
                        } else {
                            dump += p + '\t\t' + (k - (r||0)) + ' = ' + recursion(v, level + 2) + '\n';
                        }
                    });
                    dump += p + '\t]\n'
                    + p + ']';
                    break;
                case "function":
                    var match = obj.toString().match(/^(.*)\(([^\)]*)\)/im);
                    match[1] = trim(match[1].replace(new RegExp("[\\s]+", "g"), " "));
                    match[2] = trim(match[2].replace(new RegExp("[\\s]+", "g"), " "));
                    return match[1] + "(" + match[2] + ")";
                case "window":
                default:
                    dump += 'N/A: ' + t;
                    break;
            }
      
            return dump;
        }
   
        var type = function(obj) {
            var type = typeof(obj);
      
            if(type != "object") {
                return type;
            }
      
            switch(obj) {
                case null:
                    return 'null';
                case window:
                    return 'window';
                case document:
                    return 'document';
                case window.event:
                    return 'event';
                default:
                    break;
            }
      
            if(obj.jquery) {
                return 'jquery';
            }
      
            switch(obj.constructor) {
                case Array:
                    return 'array';
                case Boolean:
                    return 'boolean';
                case Date:
                    return 'date';
                case Object:
                    return 'object';
                case RegExp:
                    return 'regexp';
                case ReferenceError:
                case Error:
                    return 'error';
                case null:
                default:
                    break;
            }
      
            switch(obj.nodeType) {
                case 1:
                    return 'domelement';
                case 3:
                    return 'string';
                case null:
                default:
                    break;
            }
      
            return 'Unknown';
        }
   
        return recursion(object);
    }

    function trim(str) {
        return ltrim(rtrim(str));
    }

    function ltrim(str) {
        return str.replace(new RegExp("^[\\s]+", "g"), "");
    }

    function rtrim(str) {
        return str.replace(new RegExp("[\\s]+$", "g"), "");
    }

})(jQuery);
