/**
 * @Company Fastpivot 2008
 * @Author Michael Morris
 * @Date 4/14/2007
 * @Dependencies: Prototype JS DOM Library 
 *  

This work is licensed under Creative Commons GNU GPL License
http://creativecommons.org/licenses/GPL/2.0/
and based on code by Russel Lindsay www.weetbixthecat.com
Copyright Kostik Naumov www.piterpen.net
(c) 20070108
*/

Array.prototype._sortPrep = function ( field ) {
	if (!this.maximum) {
		this.maximum = this[0][field];
		var i = this.length;
		while(i--) {
			if (this.maximum < this[i][field]) {this.maximum = this[i][field];}
		}
	}
	if (this.maximum) {
		var fill = new Array();
		var length = this.maximum.toString().length;
		var i = length; var zs = "";
		while (i--) {
			fill.push(zs); zs += "0";
		}
		for (var i=0; i < this.length; i++ )
			this[i][field] = (this[i][field].toString().length < length ? fill[length - this[i][field].toString().length] : "") + this[i][field];
	}
}


Array.prototype._sortIntAsc = function(field) {
	this._sortPrep(field);
	var saveO = Object.prototype.toString;
	var saveA = Array.prototype.toString;
	Object.prototype.toString = function(){ return this[field] };
	Array.prototype.toString = function(){ return this[field] };
	this.sort();
	Array.prototype.toString = saveA;
	Object.prototype.toString = saveO;
}

Array.prototype._sortIntDesc = function(field) {
	this._sortPrep(field);
	var saveO = Object.prototype.toString;
	var saveA = Array.prototype.toString;
	Object.prototype.toString = function(){ return this[field] };
	Array.prototype.toString = function(){ return this[field] };
	this.sort();
	this.reverse();
	Array.prototype.toString = saveA;
	Object.prototype.toString = saveO;
}

Array.prototype.sortAsc = function(field) {
	var saveO = Object.prototype.toString;
	var saveA = Array.prototype.toString;
	Object.prototype.toString = function(){ return this[field] };
	Array.prototype.toString = function(){ return this[field] };
	this.sort();
	Array.prototype.toString = saveA;
	Object.prototype.toString = saveO;
}

Array.prototype.sortDesc = function(field) {
	var saveO = Object.prototype.toString;
	var saveA = Array.prototype.toString;
	Object.prototype.toString = function(){ return this[field] };
	Array.prototype.toString = function(){ return this[field] };
	this.sort();
	this.reverse();
	Array.prototype.toString = saveA;
	Object.prototype.toString = saveO;
}


Array.prototype._parseInt = function(field) {
	for (var i=0; i < this.length; i++ ) {
		this[i][field] = this[i][field]*1;
	}
}

Array.prototype.sortIntAsc = function(field) {
	this._sortIntAsc(field);
	this._parseInt(field);
}

Array.prototype.sortIntDesc = function(field) {
	this._sortIntDesc(field);
	this._parseInt(field);
}


/* End Array prototyping for sorting */

/* Begin addMethods for extending Element object */
Element.addMethods({
    collectText: function(element) {
        if (element.empty()) {
            return null;
        }
        
        return element.innerHTML.strip().stripTags();
    }
});
/* End addMethods for extending Element object */

var PropertyFilter = $H();
PropertyFilter.set('priceBold', '[\\$,\\.]');

var PropertyFactory = {
    getSortableProperties: function(e) {
        props = e.immediateDescendants();
        var obj = {};
        props.each(
            function(e) {
                var name = e.readAttribute('class');
                var val = e.collectText();
                
                if (name != "" && val != "") {
                    if (filter = PropertyFilter.get(name))
                        val = val.gsub(filter, '');                    
                    this.setProperty(obj, name, val);
                }
            }
        , this);
        
        return obj;
    },
    setProperty: function(obj, name, val) {
        if (name == null)
            return;
            
        name = name.gsub('-','');
               
        eval("obj." + name + "=\"" + val + "\";");
    }
}


var Items = Class.create({
  items: [],
  initialize: function() {
    items = $$('.section-item');
    items.each(function(e) {
        var item = PropertyFactory.getSortableProperties(e);
        item.element = e;
        this.items.push(item);
    }, this);
  },
  getItems: function() {
    return this.items;
  },
  register: function(item) {
    this.items.push(item)
  }
});

var Sorter = Class.create({
    initialize: function(items, paginator) {
        this.items = items;
        this.paginator = paginator;
        this.options = arguments[2] || {};
    },
    sort: function(field) {
        if (field != null) {
            var options = arguments[1] || {}
            
            if (!options.type) options.type = this.options.defaultType || 'string';
            if (!options.orderby) options.orderby = this.options.defaultOrder || 'asc';
            
            if (options.type == 'string') {
                this.sortBy(field, options.orderby);
            }
            
            if (options.type == 'int') {
                this.sortIntBy(field, options.orderby);
            }
            
        }
        
        this.paginator.paginate(this.items);   
    },
    sortBy: function(field, orderby) {
        if (orderby == 'desc') {
            this.items.getItems().sortDesc(field);
        } else {
            this.items.getItems().sortAsc(field);
        }
    },
    
    sortIntBy: function(field, orderby) {
        if (orderby == 'desc') {
            this.items.getItems().sortIntDesc(field);
        } else {
            this.items.getItems().sortIntAsc(field);
        }
    }
});

var Defaults = {
    paginationContainer: 'contentsArea',
    defaultField: 'name',
    itemsPerRow: 4,
    itemsPerPage: 12,
    hasRowDivider: true
};

var Page = Class.create({
    element: null,
    items: null,
    initialize: function(items) {
        this.element = new Element('div',{'class': 'paginated-content'});
        
        items.eachSlice(Defaults.itemsPerRow, 
            function(row) {
                var e = new Element('div');
                row.each(
                    function(item, i) {
                        /* reset last style */
                        item.element.removeClassName('last');
                        /* Flag the last item in the row for possible styling purposes */
                        if (i == (Defaults.itemsPerRow-1)) {
                            item.element.addClassName('last');
                        }
                        
                        e.appendChild(item.element);
                    }
                );
                
                e.appendChild(new Element('div', {'class': 'clear'}));
                
                if (Defaults.hasRowDivider) {
                    e.appendChild(new Element('div', {'class': 'horizontalDivider'}).update(Defaults.rowDividerHTML));
                }
                
                this.appendChild(e);
                
                 
            }
        , this);
    },
    appendChild: function(c) {
        this.element.appendChild(c);
    }
});

/** A collection of pages
 *  Perhaps use to cache sorted pages later
 * */

var PageCollection = Class.create();
Object.extend(PageCollection.prototype, {
    pages: [],
    index: 0,
    initialize: function(pages) {
        if (pages)
            this.pages = $A(page);
        else
           this.pages = $A();    
    },
    nextPage: function() {
        if (++this.index >= this.pages.length)
            this.index = 0;
            
        return this.pages[this.index];
    },
    previousPage: function() {
        // no -- operator
        this.index -= 1;
        if (this.index < 0)
            this.index = this.pages.length - 1;
            
        return this.pages[this.index];
    },
    currentPage: function() {
        return this.pages[this.index];
    },
    addPage: function(page) {
        if (page)
            this.pages.push(page);
    },
    getPage: function(i) {
        return this.pages[i];
    },
    reset: function() {
        this.index = 0;
    },
    getPages: function() {
        return this.pages;
    }
});


var Paginator = Class.create({
    pages: [],
    container: null,
    initialize: function() {
        this.container = $(Defaults.paginationContainer);
    },
    setItemsPerRow: function(i) {
        if (i <= 0)
            return;
        
        this.itemsPerRow = i;
    },
    setItemsPerPage: function() {
        if (i <= 0)
            return;
            
        this.itemsPerPage = i;
    },
    paginate: function(ItemsCollection) {
        
        this.pages = new PageCollection();
        if (!ItemsCollection)
            return;

        ItemsCollection.getItems().eachSlice(Defaults.itemsPerPage, 
            function(itemsForPage) {
                this.pages.addPage(new Page(itemsForPage));
            }, this);
            
        this.container.update('');            
        this.pages.getPages().each(
            function(page, i) {
                if(i != 0)
                    page.element.hide();
                this.container.appendChild(page.element);
            
            }, this);
//        this.writePagePosition();
        this.writePageNumberControls();
        this.writeNavigationControls();
    },
/*
    writePagePosition: function() {
        containers = $$('.pagePosition');
        if (!containers)
            return;
        containers.each(
            function(container) {
				var numPages = this.pages.getPages();
				container.update('Page X of ' + numPages + 'X');
            }
        , this);
    },
*/
    writePageNumberControls: function() {
        containers = $$('.pageNumbers');
        if (!containers)
            return;
        containers.each(
            function(container) {
                container.update('Page');
                this.pages.getPages().each(
                    function(page, index) {
                        container.appendChild(new Element('a', {'href': 'javascript: paginator.showPage(' + index + ')'}).update(index+1));
						container.appendChild(new Element('span').update('|'));
                    }
                );
                container.appendChild(new Element('a', {'href': 'javascript: paginator.showAll();'}).update('View All'));
            }
        , this);
    },
    writeNavigationControls: function() {
        containers = $$('.pageNavigation');
        if (!containers)
            return;
        containers.each(
            function(container) {
                container.update('&lt;&lt; ');
                container.appendChild(new Element('a', {'class': 'prevNav','href': 'javascript: paginator.prevPage()'}).update('previous'));
                container.appendChild(new Element('a', {'class': 'nextNav','href': 'javascript: paginator.nextPage()'}).update('next'));
                container.innerHTML += ' &gt;&gt;';
            }
        , this);
    },
    showPage: function(page) {
        this.pages.getPages().each(
            function(page) {
                page.element.hide();
            }
        );

        this.pages.getPage(page).element.show();       
    },
    showAll: function() {
        this.pages.getPages().each(
            function(page) {
                page.element.show();
            }
        );
    },
    nextPage: function() {
        this.pages.currentPage().element.hide();
        this.pages.nextPage().element.show();
    },
    prevPage: function() {
        this.pages.currentPage().element.hide();
        this.pages.previousPage().element.show();
    }
    

});

var paginator = null;
var sorter = null;


Event.observe(document, "dom:loaded",
    function() { 
        paginator = new Paginator(); 
        sorter = new Sorter(new Items(), paginator);
        sorter.sort(Defaults.defaultField);
    }
);

