function Forum(Parent, Uri) {
    var MAX = 15;
    var cpage = -1;
    var fv;
    var forum;
    var pages;
    var sortpager;
    var cpage;
    var topictemp;

    var loadTopic = function(line, data) {
        if (!data.forum) {
            fetch('topic', data, function(d) { loadTopic(line, d); });
            return;
        }
        //TODO: submitter, first comment date, last comment date

        line.find('.topictitle').attr('href', '/forum/'+data.forum+'/'+data.id).text(data.title);

        line.find('.commcount').text(data.comments.length-1);

        line.find('.commdate').text(format_datetime(make_date(data.last_modified.datetime)));
    };

    var submitNewTopic = function() {
        var data = {cmd:'create'};

        data.title = $('div.newtopicform input.topictitle', fv).val();
        if (!data.title || data.title.length == 0) {
            $('div.newtopicform input.topictitle', fv).focus();
            return false;
        }

        data.tags = $('div.newtopicform input.topictags', fv).val();

        data.text = $('div.newtopicform textarea', fv).val();
        if (!data.text || data.text.length == 0) {
            $('div.newtopicform textarea', fv).focus();
            return false;
        }

        if (forum.forum == "events") {
            var dates = $('div.newtopicform input.dates', fv).datepicker("getDate");
            if (dates[0]) { data.start = dates[0].toUTCString(); }
            if (dates[1]) { data.end = dates[1].toUTCString(); }

            var loc = $('div.newtopicform input.location').val();
            if (loc) { data.location = loc; }

            var web = $('div.newtopicform input.website').val();
            if (web) { data.website = web; }
        }

        $.post(Uri,
               data,
               function(data) {
                   window.location = '/forum/'+data.forum+'/'+data.id;
               },
               'json');
        return false;
    };

    var updatePreview = function(data) {
        $('div.newtopicform h3.preview', fv).show();
        $('div.newtopicform div.preview', fv).html(data);
    };

    var previewNewTopic = function() {
        var text = $('div.newtopicform textarea', fv).val();

        $.post('/preview', {text:text}, updatePreview, 'html');
        return false;
    };

    var cancelNewTopic = function() {
        $('div.newtopic a.show', fv).show();
        $('div.newtopicform', fv).hide();
        return false;
    };

    var newTopic = function() {
        $('div.newtopicform', fv).show();
        $('div.newtopic a.show', fv).hide();

        $('div.newtopicform input.topictitle').focus();
        return false;
    };

    var loggedIn = function() {
        $('.newtopic', fv).show()
        .find('a.show.button').click(newTopic).end()
        .find('a.cancel.button').click(cancelNewTopic).end()
        .find('a.preview.button').click(previewNewTopic).end()
        .find('a.submit.button').click(submitNewTopic)
        .attr('href', data_uri);

        $('input.topictags', fv).autocomplete(
          '/api/autocomplete/tag',
          {dataType:'json',
           parse:function(data) {
             var res = [];
             for (var i = 0; i < data.results.length; i++) {
               res[i] = {data:data.results[i],
                         value:data.results[i].title,
                         result:data.results[i].title};
             }
             return res;
           },
           formatItem: function(row) { return row.title; },
           multiple:true
          });
    };

    var loadPage = function(u, d, page) {
        if (page < 0) { page = 0; }
        else if (page >= pages) { page = pages-1; }

        cpage = page;

        sortpager.setPageDisplay(cpage, pages);

        if (!topictemp) {
            topictemp = $('tr.topic', fv);
            topictemp.remove();
        }

        var offset = MAX*cpage;
        var topiclist = $('table.topic tbody', fv).empty();
        for (var i = 0; i < MAX && i+offset < forum.topics.length; i++) {
            loadTopic(
                topictemp.clone()
                .find('.topictitle').attr('href', '/forum/'+forum.forum+'/'+forum.topics[i])
                .end().appendTo(topiclist),
                forum.topics[i]);
        }

        get_user('forum', loggedIn);
    };

    var loadForum = function(data) {
        forum = data;
        $('.forumtitle.'+data.forum, fv).show();

        if (data.forum == "events") {
            $('tr.eventdetails', fv).show();
            $('input.dates', fv).datepicker(
              {'dateFormat':'yy.m.d',
               'duration':'fast',
               'rangeSelect':'true'
              });
        }

        pages = Math.ceil(data.topics.length/MAX);

        sortpager = SortPager($('.sortpager', fv), [{uri:Uri}], loadPage);
    };

    var loadTemplate = function(data) {
        fv = $(data).appendTo(Parent);
        $.getJSON(Uri, [], loadForum);
    };

    $.get('/'+stv+'/html/forum.html', [], loadTemplate);
};

$(function() { Forum($('#view'), data_uri); });

