var DataSortSimple = new Class({
    initialize: function(col, order) {
        this.col = col;
        this.order = order;
    },

    sorter: function() {
        return function(a, b) {
            var av, bv;
            if (window.ie) {
                av = $A(a.cells)[this.col].innerHTML;
                bv = $A(b.cells)[this.col].innerHTML;
            } else {
                av = a.cells[this.col].getText();
                bv = b.cells[this.col].getText();
            }
            return this.sort(av, bv);
        }.bind(this);
    },

    sort: function(a, b) {
        if (a > b)
            return 1 * this.order;
        if (a < b)
            return -1 * this.order;
        return 0;
    }
});

var DataSortNumber = DataSortSimple.extend({
    sort: function(a, b) { return (a-b) * this.order; }
});

var DataSortCurrency = DataSortSimple.extend({
    sort: function(a, b) {
        //                             $ euro  cent  pound curren yen (unicode)
        var currencies = new RegExp(/^[\$\u202a\u00a2\u00a3\u00a4\u00a5]?\s*/);
        a = a.replace(currencies, '');
        b = b.replace(currencies, '');
        return (a-b) * this.order;
    }
});

var DataGrid = new Class({
    VERSION: {
        authors: 'Wijnand "tehmaze" Modderman',
        contact: 'mootools@tehmaze.REMOVETHIS.com',
        website: 'http://tehmaze.com',
        version: '0.1',
        license: 'LGPL (http://www.gnu.org/licenses/lgpl.txt)'
    },

    options: {
        sorters: [],
        sorterDefault: DataSortSimple,
        sortedEvent: function() {},
        orderClass: 'x-grid-order',
        padClass: 'x-grid-pad'
    },

    initialize: function(el, options) {
        this.el = $(el);
        this.setOptions(options);
        this.scanHeader();
    },

    scanHeader: function() {
        var header = this.el.getElement('thead');
        if (!$chk(header)) {
            alert('No <thead> found, can not operate properly');
            return;
        }
        // scan all headings and bind click events to toggle sorting
        this.headings = new Array();
        this.headings.extend(header.getElements('td'));
        this.headings.extend(header.getElements('th'));
        this.headings.each(function(item, col) {
            var that = this;
            item.order = 1;
            item.setStyle('cursor', 'pointer');
            item.addEvent('click', function() {
                that.sortBy(col, item);
            });
            item.adopt(new Element('span', { 'class': this.options.padClass }).setText('\u00a0'));
        }, this);
        // if the supplied sorters are not matching the heading count, extend them
        // with our default sorter
        if (this.options.sorters.length < this.headings.length) {
            for (var i = this.options.sorters.length; i < this.headings.length; i++) {
                this.options.sorters[i] = this.options.sorterDefault;
            }
        }
    },

    sortBy: function(col, item) {
        var body = this.el.getElement('tbody');
        var rows = $A(body.rows);
        //var sorter = new this.options.sorterDefault(col, item.order);
        var sorter = new this.options.sorters[col](col, item.order);
        rows.sort(sorter.sorter());
        body.adopt(rows); // replace them in the right order
        // remove previous order by item (if present)
        var order = this.el.getElement('.' + this.options.orderClass);
        if ($defined(order)) order.replaceWith(
            new Element('span', { 'class': this.options.padClass }).setText('\u00a0'));
        // remove padding
        order = this.headings[col].getElement('.' + this.options.padClass);
        if ($defined(order)) order.remove();
        order = new Element('span', { 'class': this.options.orderClass });
        if (item.order == 1)
            order.setText('\u2193');
        else
            order.setText('\u2191');
        this.headings[col].adopt(order);
        // reverse item order
        item.order *= -1;
        this.options.sortedEvent.bind(this)();
    }
});

DataGrid.implement(new Options);
