(function() {

    jQuery.extend({
        context: function(context, fn) {
            return function() { 
                return fn.apply(context, arguments); 
            };
        }
    });

})();

var MenuBit = function(elem) {
    var scriptSrc = AXIS.PATH('wikisite.js');
    this.element = jQuery(elem);
    if (scriptSrc.charAt(0) != "/" && !scriptSrc.match(/^[^:/]*:\/\//)) {
        scriptSrc = AXIS.Util.uri.getFolder(location.pathname) + scriptSrc;
    }
    this.path = scriptSrc + '../content/';
    // fetch current-user-privilege-set
    this.allow = function() {
        return false;
    };

    var privs = AXIS.WebDAV.getCUPS({
        asynch: false,
        url: this.path
    });

    if (privs) {
        this.allow = privs.hasPriv;
    };

    this.getItems(jQuery.context(this, this.display));
};

MenuBit.prototype = {
    getItems: function(callback) {
        var self = this;
        var dav = AXIS.WebDAV;
        dav.SEARCH({
            url: self.path,
            props: ['displayname'],
            where: dav.SEARCH.not(dav.SEARCH.is_collection()),
            order: 'ascending',
            orderby: 'getlastmodified',
            callback: function(r) {
                var items = [];
                try {
                  var items = r.responseXMLObject().multistatus.response;
                  if (items.constructor != Array) {
                    items = [items];
                  }
                }
                catch(e) {
                  items = [];
                }
                callback(items);
            }
        });
    },

    displayItem: function(title, path) {
        var self = this;
        var item = jQuery('<li>' + 
                '<a href="#' + title + '" class="menubit-item" id="' + path + '">' + unescape(title) + '</a>' + 
                '<a class="menubit-item-cross">x</a>' + 
               '</li>')
            .insertBefore(self.addItemLink);

        // Register Item specific handlers
        // item selection
        item.click(function() {
            self.selectItem(item, path);
        });
        
        // item deletion
        item.children(".menubit-item-cross").click(function() {
            var cross = jQuery(this);
            var item = cross.parent();
            var url = cross.siblings(".menubit-item")[0].id;
            if (item.hasClass("selected")) {
                item.remove();
                var first_item = jQuery(self.menu.children("li")[0]);
                self.selectItem(first_item, first_item.children(".menubit-item")[0].id);
            }
            AXIS.WebDAV.DELETE({ url: url });
        });

        return item;

    },

    selectItem: function(item, path, wikiBitOptions) {
        var self = this;
        if(self.selectedItem) {
            self.selectedItem.removeClass("selected");
        }
        item.addClass("selected");
        self.selectedItem = item;
        if (this.wikibitElem) {
            this.wikibitElem.remove();
        }

        this.wikibitElem = jQuery('<div class="wikibit article"></div>');
        this.wikibitElem.insertAfter(this.element);
        self.wikibitElem[0].id = path;
wikiBitOptions=wikiBitOptions || {};
        wikiBitOptions.textboxOptions={
          templateArgs: {
            host: AXIS._siteData.hosts.limebits.replace(/\/$/, ""),
            bitshost: AXIS._siteData.hosts.limebits.replace("http://www.", "http://bits.").replace(/\/$/, "")
          }
        };
        this.wikibit = new WikiBit(self.wikibitElem, wikiBitOptions);
        this.wikibit.textbox.onTitleUpdate.subscribe({ callback: function(title) {
            item.children("a.menubit-item").html(title);
            item.children("a.menubit-item").attr("href", "#" + title);
            location.hash = "#" + title;
        }});
    },

    addItem: function() {
        var self = this;
        this.currentNewPageId = this.currentNewPageId + 1;
        var path = self.path + "New%20page%20" + this.currentNewPageId;
        var item = this.displayItem("New page " + this.currentNewPageId, path);
        this.selectItem(item, path, { 
            load: jQuery.context(self, function() {
                this.wikibit.textbox.edit();
            })
        });
    },

    display: function(items) {
        var self = this;
        items = this.sort(items);
        this.menu = jQuery('<ul></ul>');
        this.container = jQuery('<div class="menubit-container"></div>');
        this.element.append(this.container);
        this.container.append(this.menu);

        this.addItemLink = jQuery('<li class="menubit-item-add"><a style="display: none">Add page</a>');
        this.addItemLink.appendTo(this.menu);
        var itemElements = [];
        this.currentNewPageId = 0;

        var idx = 0;
        if (location.hash) {
            var item = location.hash.split("#")[1];
        }

        for(var i=0; i<items.length; i++) {
            var title = items[i].propstat.prop["displayname"];
            if (title == null)
                title = AXIS.Util.uri.basename(items[i].href);

            if (unescape(item) == unescape(title)) {
                var idx = i;
            }

            itemElements.push(self.displayItem(title, items[i].href));
            var n = new Number(items[i].href.replace(/.*New%20page%20(\d*)/, '$1'));
            if (!isNaN(n)) {
                this.currentNewPageId = Math.max(n + 1, this.currentNewPageId);
            }
        };

        if (itemElements.length > 0) {
            this.selectItem(itemElements[idx], items[idx].href);
        }

        this.registerListeners();
    },

    edit: function() {
        var self = this;
        this.link.unbind("click");
        this.link.html('Save');
        this.addItemLink.children().show();
        this.menu.sortable("enable");
        this.link.click(jQuery.context(self, self.save));
    },

    save: function() {
        var self = this;
        this.link.unbind("click");
        this.link.html('Edit');
        this.menu.sortable("disable");
        this.addItemLink.children().hide();
        this.link.click(jQuery.context(self, self.edit));
        this.saveOrder();
    },

    saveOrder: function() {
        var self = this;
        var ns = "http://limebits.com/ns/1.0/";
        var order = [];
        var i = 1;
        this.menu.children().children(".menubit-item").each(function() {
            var item = jQuery(this);
            order.push('"' + item[0].id + '"' + " : " + i);
            i = i + 1;
        });

        AXIS.WebDAV.setProperty({
            url: self.path,
            setProperties: [{ ns: ns, name: "order", value: "{" + order + "}" }]
        });
    },

    getOrder: function() {
        var self = this;
        var order = {};
        var ns = "http://limebits.com/ns/1.0/";

        var r = AXIS.WebDAV.getProperty({
            url: self.path,
            properties: [[ns, "order"]],
            asynch: false
        });

        order = eval("(" + r.responseXMLObject().multistatus.response.propstat.prop["order"] + ")") || {};
        
        return order;
    },

    sort: function(list) {
        var order = this.getOrder();
        var size = 0;
        for ( x in order ) {
            size = size + 1;
        }

        return list.sort(function(a, b) {
            var Va = order[a.href] || (size + 1);
            var Vb = order[b.href] || (size + 1);
            return Va - Vb;
        });
    },

    registerListeners: function() {
        var self = this;
        if (self.allow('write-properties')) {
            var control = jQuery("<div class='menubit-control'></div>").prependTo(self.element);
            this.link = jQuery("<a class='button'>Edit</a>").appendTo(control);
            this.link.click(jQuery.context(self, self.edit));
            this.link.hide();

            this.element.hover(function () { self.link.show(); }, 
                               function () { self.link.hide(); });
        }

        this.menu.sortable({
            stop: jQuery.context(self, self.saveOrder)
        });

        this.menu.sortable("disable");

        // new item
        if (self.allow('bind')) {
            self.addItemLink.children("a").click(jQuery.context(self, self.addItem));
        }
    }
};
