/**
 * Display's a given variable the same as the
 * PHP function var_dump() would
 *
 * @param mixed v   The variabled to dump
 * @param int   lvl The lvl we're in (optional)
 */
function var_dump(v, lvl)
{
    var type   = typeof(v);
    var indent = '&nbsp;&nbsp;&nbsp;&nbsp;';
    var spaces = '';
    var max_depth  = 3;
    if (typeof(lvl) != 'number') {
        lvl = 0;
    }
    for(var _i = 0; _i < lvl; _i++) {
        spaces += indent;
    }

    if (lvl > max_depth) {
        this.out += spaces + '- nesting level too deep ('+max_depth+' = max) -<br />';
        return;
    }
    if (lvl == 0) {
        // clear on 1st lvl
        this.out = '<hr><span style="font-family:courier;font-size:10pt;">';
    }

    switch (type) {
        case 'object':
            if (v === null) {
                this.out += spaces + 'NULL<br />';
                break;
            }
            var constr = v.constructor.toString();
            var index1 = constr.indexOf(' ')+1;
            var index2 = constr.indexOf('(');
            if (index2 < 0) {
                index2 = constr.indexOf(']');
            }
            var objName = '';
            if (index1 && index2) {
                objName = constr.substring(index1, index2);
            }
            this.out += spaces + color(type) + ' ' + objName;
            this.out += spaces + "&nbsp;{<br />";

            for (var indx in v) {
                this.out += spaces + indent + '[' + indx + "]=><br />";
                if (v[indx] != undefined) {
                    try {
                        var_dump(v[indx], lvl+1);
                    } catch (e) {
                        // error
                    }
                }
            }
            this.out += spaces + "}<br />";
            break;
        case 'string':
            this.out += spaces + color(type) + '(' + v.length + ') "'+v+'"<br />';
            break;
        case 'function':
            this.out += spaces + color(type) + '() <br />';
            break;
        case 'number':
            this.out += spaces + color(type) + '(' + v + ')<br />';
            break;
        case 'boolean':
            this.out += spaces + color(type) + '(' + v + ')<br />';
            break;
    }
    if (lvl == 0) {
        this.out += '</span><hr>';
        document.body.innerHTML = this.out + document.body.innerHTML;
        this.out = '';
        return;
    }

    function color(type) {
        var color = '#000';
        switch (type) {
            case 'object':
                color = 'orange';
                break;

            case 'function':
                color = 'purple';
                break;

            case 'boolean':
                color = 'blue';
                break;

            case 'number':
                color ='red';
                break;

            case 'string':
                color = 'green';
                break;

        }
        return '<span style="color:'+color+';">'+type+'</span>';
    }
}


/**
 * Log function
 *
 * @var mixed str The variable to log
 */
function log(varz)
{
    if (typeof(window.console) == 'object') {
        console.log(varz);
        return;
    }
    alert(varz);
}

