/***
    OxUI Documentation
***/
var app =  {};
$(function() {
    app.$body = $('body');
    app.$document = $(document);
    app.$window = $(window);

    app.$ui = {};
    app.docstrings = {};

    $("<div>").load('../build/js/ox.ui.js', function(data) {
        app.source = data;
        var docstrings = app.source.match(/\/\*\*\n([\s\S]+?\*\/\n.*?)\n/gm)
        docstrings.forEach(function(doc) {
            doc = Ox.trim(doc);
            var name = doc.match(/Ox\.(.+) = function/);
            if(name) {
                doc = doc.split('\n');
                doc.splice(0, 1);
                doc.pop();
                doc.pop();
                //remove whitespace
                var offset = /^\s+/.exec(doc[0]);
                if(offset)
                    doc = Ox.map(doc, function(line) { return line.substring(offset[0].length)});
                app.docstrings[name[1]] = Ox.trim(doc.join('\n'));
            }
        })
    });
    app.docs = getDocsJSON();
    app.$ui.actionList = constructList();
    app.$ui.actionInfo = Ox.Container().css({padding: '8px'}).html('select action on the left.');

    var $main = new Ox.SplitPanel({
        elements: [
            {
                element: app.$ui.actionList,
                size: 160
            },
            {
                element: app.$ui.actionInfo
            }
        ],
        orientation: 'horizontal'
    });

    $main.appendTo(app.$body);
});

function constructList() {
    return new Ox.TextList({
        columns: [
                {
                    align: "left",
                    id: "name",
                    operator: "+",
                    title: "Name",
                    unique: true,
                    visible: true,
                    width: 140
                },
        ],
        columnsMovable: false,
        columnsRemovable: false,
        id: 'actionList',
        request: function(data, callback) {
            var items = [];
            app.docs.forEach(function(v) {
              items.push(v.name);
            }); 
            items = Ox.map(items, function(i) { return {name: i}});
            items.sort(function(a, b) { if(a.name < b.name) { return -1 } else if( a.name == b.name) { return 0 }else { return 1 } })
            if(!data.keys) {
                var result = {'data': {'items': items.length}};
            } else {
                var result = {'data': {'items': items}};
            }
            Ox.print("items", items);
            callback(result);
        },
        sort: [
            {
                key: "name",
                operator: "+"
            }
        ]
    }).bindEvent({
       select: function(event, data) {
           var info = $('<div>');
           var ids = data.ids;
           ids.forEach(function(v) {
             var docObj = getObjectByName(app.docs, v);
             var html = getDocHtml(docObj);
             info.append(html);
           });            
            app.$ui.actionInfo.html(info);
       }
    });
}

function getDocHtml(doc) {
    function cell(content) {
        return $('<td>').css({'padding-right': '4px'}).html(content);
    }

    var $div = $('<div>');
    var title = $('<h2>').html('Ox.'+doc.name)
                         .appendTo($div);

    if(app.docstrings[doc.name])
        $('<pre>').html(app.docstrings[doc.name]).appendTo($div);

    if(doc.options) {
        var $options = $('<div>').html("Options: ")
                                 .css({'marginBottom': '20px'})
                                 .appendTo($div);
        var $table = $('<table>').attr({'cellpadding': '4'})
                                 .appendTo($options);
        Ox.keys(doc.options).forEach(function(k) {
            var $option = $('<tr>');
            cell(k).appendTo($option);
            if(typeof(doc.options[k]) != 'undefined') {
                cell(typeof doc.options[k]).appendTo($option);
                if(Ox.isNull(doc.options[k]))
                    cell(' <b>null</b>').appendTo($option);
                else
                    cell(' <b>' + doc.options[k].toString() + '</b>').appendTo($option);
            } else {
                cell('&nbsp;').appendTo($option);
                cell('<b>required, no default value</b>').appendTo($option);
            }
            $option.appendTo($options);
        });
    }

    var methods = Ox.keys(doc.methods);
    if (methods.length > 0) {
        var $methods = $('<div>').html("Methods:").appendTo($div);
        methods.forEach(function(m) {
            var $method = $('<div>').appendTo($methods);
            var $code = $('<pre>').html(doc.methods[m]).hide();
            var options = /function \((.*?)\)/.exec(doc.methods[m]);
            var lable = new Ox.Label({
                                    title: m + '('+options[1]+')', 
                                    width: 190
                                })
                                .css({'float': 'left', 'margin-right': '4px'})
                                .addClass("margin")
                                .appendTo($method);
            var $button = new Ox.Button({
                    title: [
                        {id: "one", title: "expand"},
                        {id: "two", title: "collapse"},
                    ],
                    type: "image"
                })
                .addClass("margin")
                .appendTo($method)
                .click(function() { $code.toggle()});
          $code.appendTo($method);
        });
    }

    if(doc.functionString) {
        var $methodcode = $('<pre>').html(doc.functionString.replace(/</g, '&lt;'))
                                    .hide();
        var $button = new Ox.Button({
                title: [
                    {id: "one", title: "expand"},
                    {id: "two", title: "collapse"},
                ],
                type: "image"
            })
            .addClass("margin")
            .click(function() { $methodcode.toggle()})
            .appendTo($div)
        $('<span>').html(' View Source').appendTo($div)
        $methodcode.appendTo($div);
    }
    return $div;
}

function getObjectByName(obj, name) {
  var ret = false;
  obj.forEach(function(o) {
    if (o.name == name) {
      ret = o;
    }
  });
  return ret;
}

function getDocsJSON() {
    var ret = [],
        keys = Ox.keys(Ox);
    keys.forEach(function(v) {
        if (doc = getDoc(v)) {
            ret.push(doc);
        } else {
            $.noop();
        }
    });
    return ret;

    function getDoc(key) {
        //FIXME: eventually we want to document all Ox values and functions
        if (!/^[A-Z][a-z]/.test(key)) {
            return false
        }
        var functionString = Ox[key].toString();
        if (typeof Ox[key] != 'function') {
            return {
                'name': key,
                'functionString': functionString
            }
        }
        try {
            var o = new Ox[key]();
        } catch(err) {
            return {
                'name': key,
                'functionString': functionString
            }
        }
        var methods = {};
        var opts = {};
        if ('options' in o && typeof o['options'] == 'function') {
            var opts = o.options();
            //only inclue methods that are defined in the function
            var _methods = Ox.filter(Ox.keys(o), function(m) { return (functionString.indexOf('that.'+m+' =') > -1 && typeof o[m] === 'function')});
            $.each(_methods, function(i, m) { methods[m] = o[m].toString() });
        }
        return {
            'name': key,
            'options': opts,
            'methods': methods,
            'functionString': functionString
        }
    }
}

