/*
    Wiskuu.nl version 1.0.0

    Copyright © 2011 Bart Post
    All rights reserved.

    No part of this code may be used, reproduced, transmitted, or stored in any
    retrieval system of any nature, without the written permission of Bart Post.
*/

/*jslint browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */

/*global $, jQuery, window */

/********************************************************************************
cookie function to read and write cookies
********************************************************************************/

(function($) {

    $.fn.cookie = function(name, value, options) {

        var expires, date, i, path, domain, secure, cookieValue, cookies, cookie;

        if (typeof value !== 'undefined') {
            options = options || {};
            if (value === null) {
                value = '';
                options.expires = -1;
            }
            expires = '';
            if (options.expires && (typeof options.expires === 'number' || options.expires.toUTCString)) {
                if (typeof options.expires === 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString();
            }
            path = options.path ? '; path=' + (options.path) : '; path=/';
            domain = options.domain ? '; domain=' + (options.domain) : '';
            secure = options.secure ? '; secure' : '';
            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
        } else {
            cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                cookies = document.cookie.split(';');
                for (i = 0; i < cookies.length; i++) {
                    cookie = jQuery.trim(cookies[i]);
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }

    };

} (jQuery));

/********************************************************************************
query function to read the querystring
********************************************************************************/

(function($) {

    $.fn.query = function(name) {
        var regexS, regex, results;
        name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
        regexS = "[\\?&]" + name + "=([^&#]*)";
        regex = new RegExp(regexS);
        results = regex.exec(window.location.href);
        if (results === null) {
            return "";
        }
        else {
            return decodeURIComponent(results[1].replace(/\+/g, " "));
        }
    };

} (jQuery));

/********************************************************************************
smarttable plugin
********************************************************************************/

(function($) {

    $.fn.removeDuplicates = function(array) {
        var i, seen = {};

        for (i = array.length; i > 0; i--) {
            if (seen[array[i - 1]]) {
                array.splice(i - 1, 1);
            }
            else {
                seen[array[i - 1]] = true;
            }
        }

        return array;
    };

    $.fn.smarttable = function(settings) {
        var config = {
            filter: false,
            hover: false,
            paging: false,
            sort: false,
            zebra: false,

            cssodd: '',
            csseven: 'striped',
            csshover: 'hover'
        };

        if (settings) { $.extend(config, settings); }

        function doHover(table) {
            $('tbody tr', table).hover(function() { $(this).addClass(config.csshover); }, function() { $(this).removeClass(config.csshover); });
        }

        function doZebra(table) {
            /* we swap even and odd here because of 0-based indexing */
            $('tbody tr:not(th,:hidden,.banner):odd', table).removeClass(config.cssodd).addClass(config.csseven);
            $('tbody tr:not(th,:hidden,.banner):even', table).removeClass(config.csseven).addClass(config.cssodd);
        }

        function doSort(table) {
            var sort;
            $('thead th', table).each(function(column) {
                $(this).click(function() {
                    var direction, rows;

                    direction = ($(this).is('.sort-ascending') ? -1 : 1);

                    $('thead th', table).removeClass('sort-ascending').removeClass('sort-descending');

                    if (direction === -1) {
                        $(this).addClass('sort-descending');
                        $.fn.cookie('sort', $('th', table).index(this) + '|sort-ascending', { path: window.location.pathname });
                    }
                    else {
                        $(this).addClass('sort-ascending');
                        $.fn.cookie('sort', $('th', table).index(this) + '|sort-descending', { path: window.location.pathname });
                    }

                    rows = $('tbody tr:not(.boost):not(.banner)', table);

                    $.each(rows, function(index, row) {
                        if ($(row).children('td').eq(column).attr('sort')) {
                            row.sort = $(row).children('td').eq(column).attr('sort');
                        }
                        else {
                            row.sort = $(row).children('td').eq(column).text().toUpperCase();
                        }
                    });

                    rows.sort(function(a, b) {
                        if (a.sort < b.sort) { return -1 * direction; }
                        if (a.sort > b.sort) { return 1 * direction; }
                        return 0;
                    });

                    $.each(rows, function(index, row) {
                        $(table).children('tbody').append(row);
                        row.sort = null;
                    });

                    if (config.zebra) { doZebra(table); }
                });
            });

            /* execute sort based on cookie value */

            sort = ($.fn.cookie('sort') ? $.fn.cookie('sort').split('|') : "0|sort-descending");
            $('thead th', table).eq(sort[0]).addClass(sort[1]);
            $('thead th', table).eq(sort[0]).click();
        }

        function doFilter(table) {

            function populateSelect(column) {
                var keywords, name, $select;

                keywords = [];
                name = $('thead th', table).eq(column).attr('org');
                $select = $('select.filter[id=' + column + ']').click(function(e) { e.stopPropagation(); });

                $.each($('tbody tr', table), function(index, row) {
                    keywords[index] = $(row).children('td:not(:hidden)').eq(column).text().trim();
                });
                $.fn.removeDuplicates(keywords).sort();

                $('option', $select).remove();

                $($select).append('<option value="" selected>' + name + ' ...</option>');
                $.each(keywords, function(i) {
                    $($select).append('<option value="' + (i + 1) + '">' + keywords[i] + '</option>');
                });
            }

            function buildSelect() {
                $('thead th', table).each(function(column) {
                    if ($(this).is('.filter')) {
                        if (!$(this).attr('org')) {
                            $(this).attr('org', $(this).text().trim());
                            $(this).html('<select id="' + column + '" class="filter" style="max-width:200px"></select>');
                            populateSelect(column);
                        }
                        else {
                            populateSelect(column);
                        }
                    }
                });
            }

            buildSelect();

            $('select.filter', table).change(function() {

                $('tbody > tr', table).show().filter(function() {
                    var hide = false, $this = this;
                    $.each($('select.filter', table), function(index, filter) {
                        if ($('option:selected', filter).val()) {
                            hide = hide || $('option:selected', filter).text() !== $('td:not(:hidden)', $this).eq($(filter).attr('id')).text().trim();
                        }
                    });
                    return hide;
                }).hide();

                if (config.zebra) { doZebra(table); }
            });
        }

        this.each(function() {
            if (config.hover || $(this).hasClass('hover')) { doHover(this); }
            if (config.filter || $(this).hasClass('filter')) { doFilter(this); }
            if (config.sort || $(this).hasClass('sort')) { doSort(this); }
            if (config.zebra || $(this).hasClass('zebra')) { doZebra(this); }
        });
        return this;

    };

} (jQuery));

/********************************************************************************
on document load
********************************************************************************/

$(document).ready(function() {

    $('.smarttable').smarttable( { zebra : true } );
});
