/*@
Ox.DocPage <f> DocPage
    () ->              <o> DocPage object
    (options) ->       <o> DocPage object
    (options, self) -> <o> DocPage object
    options <o> Options object
        item <o> doc item
    self    <o> Shared private variable
@*/
Ox.DocPage = function(options, self) {

    self = self || {};
    var that = Ox.Element({}, self)
        .defaults({
            item: {}
        })
        .options(options || {})
        .addClass('OxDocPage OxDocument')
        .css({
            overflow: 'auto'
        });

    that.append(
        $('<h1>')
            .css({
                marginTop: 0,
                WebkitMarginBefore: 0
            })
            .html('<code>' + self.options.item.name + '</code>')
        );

    getItem(self.options.item, 0).forEach(function($element) {
        that.append($element);
    });

    function getItem(item, level, name) {
        var $elements = [$('<div>')
            .css({paddingLeft: (level ? level * 32 - 16 : 0) + 'px'})
            .html(
                '<code><b>' + (name || item.name) + '</b> ' +
                '&lt;' + item.types.join('&gt;</code> or <code>&lt;') + '&gt; </code>' +
                (item['default'] ? 'default: <code>' + item['default'] + ' </code>' : '') +
                Ox.parseHTML(item.summary)
            )
        ];
        [
            'description', 'usage', 'arguments', 'properties',
            'events', 'examples', 'source'
        ].forEach(function(section) {
            var className = 'OxLine' + Ox.uid();
            if (item[section]) {
                if (section == 'description') {
                    $elements.push($('<div>')
                        .css({
                            paddingTop: (level ? 0 : 8) + 'px',
                            borderTopWidth: level ? 0 : '1px',
                            marginTop: (level ? 0 : 8) + 'px',
                            marginLeft: (level * 32) + 'px',
                        })
                        .html(Ox.parseHTML(item.description))
                    );
                } else {
                    $elements.push($('<div>')
                        .css({
                            paddingTop: (level ? 0 : 8) + 'px',
                            borderTopWidth: level ? 0 : '1px',
                            marginTop: (level ? 0 : 8) + 'px',
                            marginLeft: (level * 32) + 'px',
                        })
                        .append(
                            $('<img>')
                                .attr({src: Ox.UI.getImagePath('symbolDown.svg')})
                                .css({
                                    width: '12px',
                                    height: '12px',
                                    margin: '0 4px -1px 0'
                                })
                                .click(function() {
                                    var $this = $(this),
                                        isExpanded = $this.attr('src') == Ox.UI.getImagePath('symbolDown.svg');
                                    $this.attr({
                                        src: isExpanded ?
                                        Ox.UI.getImagePath('symbolRight.svg') :
                                        Ox.UI.getImagePath('symbolDown.svg')
                                    });
                                    $('.' + className).each(function() {
                                        var $this = $(this);
                                        $this[isExpanded ? 'addClass' : 'removeClass'](className + 'Hidden');
                                        if (isExpanded) {
                                            $this.hide();
                                        } else {
                                            var hidden = false;
                                            Ox.forEach(this.className.split(' '), function(v) {
                                                if (/Hidden$/.test(v)) {
                                                    hidden = true;
                                                    return false;
                                                }
                                            });
                                            if (!hidden) {
                                                $this.show()
                                            }
                                        }
                                    });
                                })
                        )
                        .append('<b>' + Ox.toTitleCase(section) + '</b>')
                    );
                    if (section == 'examples') {
                        item.examples.forEach(function(example) {
                            $elements.push($('<div>')
                                .addClass(className)
                                .css({marginLeft: (level * 32 + 16) + 'px'})
                                .html(
                                    '<code><b>&gt;&nbsp;' + 
                                    Ox.encodeHTML(example.statement)
                                    .replace(/ /g, '&nbsp;')
                                    .replace(/\n/g, '<br/>\n&nbsp;&nbsp;') +
                                    '</b></code>'
                                )
                            );
                            example.result && $elements.push($('<div>')
                                .addClass(className)
                                .css({marginLeft: (level * 32 + 16) + 'px'})
                                .html(
                                    '<code>' + Ox.encodeHTML(example.result) + '</code>'
                                )                            
                            )
                        });
                    } else if (section == 'source') {
                        // fixme: not the right place to fix path
                        $elements.push($('<div>')
                            .addClass(className)
                            .css({marginLeft: 16 + 'px'})
                            .html(
                                '<code><b>' + self.options.item.file.replace(Ox.PATH, '') +
                                '</b> line ' + self.options.item.line + '</code>'
                            )
                        );
                        $elements.push(
                            Ox.SyntaxHighlighter({
                                showLineNumbers: true,
                                // fixme: silly
                                source: item.source.map(function(token) {
                                    return token.source;
                                }).join(''),
                                offset: self.options.item.line
                            })
                            .addClass(className)
                            .css({
                                borderWidth: '1px',
                                marginTop: '8px',
                            })
                        );
                    } else {
                        item[section].forEach(function(v) {
                            var name = section == 'usage' ?
                                item.name + v.name + ' </b></code>returns<code> <b>' : null;
                            $elements = Ox.merge(
                                $elements,
                                Ox.map(getItem(v, level + 1, name), function($element) {
                                    return $element.addClass(className);
                                })
                            );
                        });
                    }
                }
            }
        })
        return $elements;
    }

    return that;

};
