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

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

	initialize: function(el, options) {
		this.setOptions(options);
//		this.el =  $(el);
        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[0]['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 on the problem.");
				} 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);
	}
});

