//******************************************************************************
// MooDataTable 0.1: A data table for MooTools 1.2
// License: MIT License
// Copyright (c) 2008 Jean-Nicolas Jolivet [http://www.silverscripting.com]

var MooTable_Artist = new Class({
    Implements: [Events, Options],
    options: {
        url: '',
        method: 'get',
        perPage: 15,
        headers: [],
        width: 80
    },

    initialize: function(el, options) {
        this.setOptions(options);
        this.el =  document.id(el);
        this.pages = 0;
        this.createElements();
        this.showAll = 0;
        this.yearSort = 'DESC';
        this.ratingSort = 'DESC';
        this.sizeSort = 'DESC';
    },

    createElements: function() {
		// build the table structure...
        var structureHtml = "<table><thead><tr></tr></thead><tfoot><tr><td colspan=\"6\"><span class=\"moo-foot-left\"></span><span class=\"moo-foot-right\"></span></td></tr></tfoot><tbody></tbody></table>";

        // Assign the HTML and CSS class to our element
        this.el.set('html', structureHtml);
        this.el.addClass('moo-table');
        this.el.setStyle('width', this.options.width + "%");
        // Grab the important elements
        this.table = this.el.getChildren("table")[0];
        this.tableBody = this.table.getChildren("tbody")[0];
        this.tableHead = this.table.getChildren("thead")[0];
        this.footerLeft = this.table.getElements('tfoot > tr > td > span.moo-foot-left')[0];
        this.footerRight = this.table.getElements('tfoot > tr > td > span.moo-foot-right')[0];

        // initiate and create the headers
        this.headersEl = [];
        this.createHeaders();
    },
    createHeaders: function() {
        var headerTr = this.tableHead.getChildren("tr")[0];

        // Create the column headers
        this.options.headers.each(function(header, index){
            var headerTd = new Element('th', {
                id: header['id']
            });
            headerTd.set('html', header['caption']);

            // add the click event for column re-ordering
            if(header['sortable']) {
                headerTd.addEvent("click", function(arg1){
                this.reorder(arg1.get('id'));
                }.bind(this, headerTd));
            }
            this.headersEl.push(headerTd);
            headerTd.inject(headerTr);
        }, this);

        // Set the initial page and sort column...
        this.page = 1;
        this.sort = 'id';
        // set the sort order to DESC, it will be inverted to ASC by default on first call...
        this.sortOrder = "ASC";
        // sort by "Crowd Rating (SemanticRating)"
        this.reorder(this.options.headers[3]['id']);
    },

    reorder: function(id) {
        var orderClass = "";
        if(this.sort == id) {
            // same column clicked... just reverse the order...
            this.sortOrder = this.sortOrder == "DESC" ? "ASC" : "DESC";
        }
        else {
            if ((id == "SemanticRating") || (id == "NanocrowdPopularityScale") || (id == "TitleYear")) {
                this.sortOrder = "DESC";
            }
            else {
                // new column clicked, set to ASC by default
                this.sortOrder = "ASC";
            }
        }

        orderClass = this.sortOrder == "ASC" ? "moo-active-asc" : "moo-active-desc";
        this.activeColumnEl = this.tableHead.getChildren("tr")[0].getChildren("th#" + id)[0];
        this.headersEl.each(function(el){
            el.removeClass('moo-active-column');
            el.removeClass('moo-active-asc');
            el.removeClass('moo-active-desc');
        });
        this.activeColumnEl.addClass("moo-active-column");
        this.activeColumnEl.addClass(orderClass);
        this.sort = id;
        // send the new request
        this.requestData(this.page);
    },

    requestData: function(page) {
        // initiate the ajax request...
        this.footerLeft.set('html', 'Loading Data...');

        var jsonRequest = new Request.JSON({
            url: this.options.url,
            method: this.options.method,
            onSuccess: function(resp){
                if(resp == null) {
                    this.footerLeft.set('html', "OOPS! Sorry for the hiccup. Our engineers are working fanatically to resolve this.");
                } else {
                    this.parseData(resp.total, resp.page, resp.rows);
                }
                smartHoverBox(1000, 500, 100, -16, '_smartgboxshort', 'smartgbox_close', 0);
                smartHoverBox(1000, 500, 200, -16, '_smartgboxlong', 'smartgbox_close', 0);
                smartHoverBox(1000, 500, 250, -16, '_smartgboxxlong', 'smartgbox_close', 0);
            }.bind(this),
            onFailure: function() {
                this.footerLeft.set('html', "The request failed...");
            }.bind(this)
        }).send("page=" + page + "&perPage=" + this.options.perPage
            + '&sort=' + this.sort + '&sortOrder=' + this.sortOrder
            + '&bust=' + new Date().getTime());
        this.page = page;
    },

    parseData: function(total, page, rows) {
        // empty the table first...
        this.tableBody.empty();
        rows.each(function(row, index) {
            var index = index + 1;
            // Create a new row...
            var tr = new Element('tr');
            // Check if it's an even row...
            var cssClass = index % 2 == 0 ? 'moo-table-even' : 'moo-table-odd';
            tr.addClass(cssClass);

            row.each(function(cell) {
                var td = new Element('td');
                td.set('html', cell);
                td.inject(tr);
            }, this);
            tr.inject(this.tableBody);
        //			if(index == this.options.perPage) {
        //				tr.addClass('moo-table-last');
        //			}
        }, this);
        // set the total pages if not set...
        if(this.pages === 0) {
            this.pages = Math.ceil(total / this.options.perPage);
        }
        var recMax = this.options.perPage * page;
        recMax = recMax > total ? total : recMax;
        var recMin = (this.options.perPage * page) - (this.options.perPage - 1);
        // Set the footer data
        if (this.showAll == 0)
        {
            this.footerLeft.set('html', "Page " + page + " of " + this.pages);
        }
        else
        {
            this.footerLeft.set('html', "Page 1 of 1");
        }
        this.paginate();
    },

    paginate: function() {
        // clear the old pagination...
        //alert(this.page + " " + this.pages);
        this.footerRight.empty();

        if (this.page == -1) {
            var showAllText = new Element('span', {'html': '<font color=white>Show All</font>'});
            showAllText.inject(this.footerRight);
            var pageSpacer = new Element('span', {'html': '<strong><font color=white> | </font></strong>'});
            pageSpacer.inject(this.footerRight);
            for (var pageIndex = 1; pageIndex < this.pages + 1; pageIndex++) {
                if (pageIndex == 1) {
                    var pageLink = new Element('a', {
                        'html': pageIndex,
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked(1);
                                return false;
                            }.bind(this)
                        }
                    });
                    pageLink.inject(this.footerRight);
                }
                else if (pageIndex == 2) {
                    pageLink = new Element('a', {
                        'html': pageIndex,
                        'href': "#",
                        'events': {
                        'click': function() {
                            this.pageClicked(2);
                            return false;
                            }.bind(this)
                        }
                    });
                    pageLink.inject(this.footerRight);
                }
                else if (pageIndex == 3) {
                    pageLink = new Element('a', {
                        'html': pageIndex,
                        'href': "#",
                        'events': {
                        'click': function() {
                            this.pageClicked(3);
                            return false;
                            }.bind(this)
                        }
                    });
                    pageLink.inject(this.footerRight);
                }
            }
        }
        else {
            if(this.pages == 1) {
                return;
            }
            else {
                var showAllLink = new Element('a', {
                    'html': "Show All",
                    'href': "#",
                    'events': {
                        'click': function() {
                            this.pageClicked("all");
                            return false;
                        }.bind(this)
                    }
                });
                showAllLink.inject(this.footerRight);
                var pageSpacer = new Element('span', {'html': '<strong><font color=white> | </font></strong>'});
                pageSpacer.inject(this.footerRight);
                if(this.page > 1) {
                    // previous link
                    var prevLink = new Element('a', {
                        'html': "<img src='/public/images/arrownav_left.gif' border=0 alt='Prev' />",
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked("prev");
                                return false;
                            }.bind(this)
                        }
                    });
                    prevLink.inject(this.footerRight);
                }
                // First page
                if(this.page == 1) {
                    // We are on the first page so, non-clickable...
                    var page1Span = new Element('span', {
                        'html': "1",
                        'class': 'moo-active-page'
                    });
                    page1Span.inject(this.footerRight);
                } else {
                    // Not on first page so... clickable...
                    var page1Link = new Element('a', {
                        'html': '1',
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked("first");
                                return false;
                            }.bind(this)
                        }
                    });
                    page1Link.inject(this.footerRight);
                }


                if(this.page > 2) {
//                    var leftSpacer = new Element('span', {'html': '...'});
//                    leftSpacer.inject(this.footerRight);
                    if(this.page == this.pages && this.pages > 3) {
                        var minusTwo = new Element('a', {
                            'html': this.page - 2 + "",
                            'href': "#",
                            'events': {
                                'click': function() {
                                    this.pageClicked(this.page - 2);
                                    return false;
                                }.bind(this)
                            }
                        });
                        minusTwo.inject(this.footerRight);
                    }
                    var minusOne = new Element('a', {
                        'html': this.page - 1 + "",
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked(this.page - 1);
                                return false;
                            }.bind(this)
                        }
                    });
                    minusOne.inject(this.footerRight);
                }
                if(this.page != 1 && this.page != this.pages) {
                    var current = new Element('span', {
                        'html': this.page + "",
                        'class': 'moo-active-page'
                    });
                    current.inject(this.footerRight);
                }
                if(this.page < this.pages - 1) {
                    var plusOne = new Element('a', {
                        'html': this.page + 1 + "",
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked(this.page + 1);
                                return false;
                            }.bind(this)
                        }
                    });
                    plusOne.inject(this.footerRight);

                    if(this.page == 1 && this.pages > 3) {
                        var plusTwo = new Element('a', {
                            'html': this.page + 2 + "",
                            'href': "#",
                            'events': {
                                'click': function() {
                                    this.pageClicked(this.page + 2);
                                    return false;
                                }.bind(this)
                            }
                        });
                        plusTwo.inject(this.footerRight);
                    }
                    // spacer
//                    var rightSpacer = new Element('span', {'html': '...'});
//                    rightSpacer.inject(this.footerRight);
                }
                if(this.page == this.pages) {
                    var lastPageSpan = new Element('span', {
                        'html': this.pages + "",
                        'class': 'moo-active-page'
                    });
                    lastPageSpan.inject(this.footerRight);
                } else {
                    var lastPageLink = new Element('a', {
                        'html': this.pages + "",
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked("last");
                                return false;
                            }.bind(this)
                        }
                    });
                    lastPageLink.inject(this.footerRight);
                }

                if(this.page < this.pages) {
                    var nextLink = new Element('a', {
                        'html': "<img border=0 src='/public/images/arrownav_right.gif' alt='Prev' />",
                        'href': "#",
                        'events': {
                            'click': function() {
                                this.pageClicked("next");
                                return false;
                            }.bind(this)
                        }
                    });
                    nextLink.inject(this.footerRight);
                }
            }
        }
    },

    pageClicked: function(page) {
        this.showAll = 0;
        if($type(page) === "string") {
            if (page === "all") {
                this.requestData(-1);
                this.showAll = 1;
            }
            else if(page === "next" && this.page < this.pages) {
                this.requestData(this.page + 1);
            }
            else if(page === "prev" && this.page > 1) {
                this.requestData(this.page - 1);
            }
            else if(page === "first" && this.page != 1) {
                this.requestData(1);
            }
            else if(page === "last" && this.page != this.pages) {
                this.requestData(this.pages);
            }
        }
        else {
            if(page > 0 && page <= this.pages) {
                this.requestData(page);
            }
        }
    },

	// only "public" method, (with the constructor huh)...
	// used if, for example, you delete a record and you
	// want to refresh the current active page...
    reloadActivePage: function() {
        this.requestData(this.page);
    }
});

