(function ($) {

    // Application namespace and initialization
    window.app = {
        'initialize': function () {
            for (piece in app) {
                if (piece !== 'initialize') {
                    var ret = app[piece]();
                    if (ret) {
                        app[piece] = ret;
                        app[piece].initialize();
                    };
                }
            }
        }
    };


    app.exploreBox = function () {
        var $instance = $('#explore:not([data-expand="no"])'),
            plugin = app.exploreBox;
        if (!$instance.length) return false;
        return {
            'initialize': function () {
                var plugin = app.exploreBox;
                plugin.closeBox();
                $instance.addClass('active');
                $instance.mouseenter(plugin.openBox).mouseleave(plugin.closeBox);
                //$instance.hover(function () { $instance.removeClass('closed').addClass('open'); }, function () { $instance.removeClass('open').addClass('closed'); });
                $instance.find('label').each(function (index, element) {
                    var $e = $(element);
                    $('<option />', {
                        'selected': true,
                        'text': $e.text()
                    }).prependTo($e.siblings('select'));
                });
                $instance.find('select').change(plugin.submitForm);
                $instance.show();
            },
            'submitForm': function (evt) {
                //$(this).closest('form').submit();
            },
            'closeBox': function (evt) {
                $instance.addClass('closed').removeClass('open');
                $(".selector").mouseleave(function (event) { event.stopPropagation(); });
                $(".selectorTopic").mouseleave(function (event) { event.stopPropagation(); });
                //evt.stopPropagation();
                //$instance.data('isOpen', false);
            },
            'openBox': function (evt) {
                $instance.removeClass('closed').addClass('open');
                $(".selector").mouseleave(function (event) { event.stopPropagation(); });
                $(".selectorTopic").mouseleave(function (event) { event.stopPropagation(); });
                //evt.stopPropagation();
                //$instance.data('isOpen', true);
            },
            '$instance': $instance
        };

    };


    // The year selection quasi-dropdown box thing that appears on the country page
    app.yearDropdown = function () {
        var $instance = $('#year-select');
        if (!$instance.length) return false;
        return {
            'initialize': function () {
                this.$instance
                    .makeAbsolute()
                    .addClass('closed')
                    .mouseenter(this.open)
                    .mouseleave(this.close);
                var $active = this.$instance.find('li.active');
                $active.prependTo($active.closest('ol'));
            },
            '$instance': $instance,
            'open': function (evt) {
                var plugin = app.yearDropdown;
                if (!plugin.isOpen) {
                    plugin.$instance.removeClass('closed').addClass('open');
                    plugin.isOpen = true;
                }
            },
            'close': function (evt) {
                var plugin = app.yearDropdown;
                if (plugin.isOpen) {
                    plugin.$instance.addClass('closed').removeClass('open');
                    plugin.isOpen = false;
                }
            },
            'isOpen': false
        }
    };



    app.topicData = function () {
        var $instance = $('#topic-data > table'),
            num = 6;
        if (!$instance.length) return false;
        return {
            'initialize': function () {
                var plugin = app.topicData,
                    slices = [],
                    $regionFilter = $('#region-filter select');
                $instance.dataTable({
                    'bPaginate': false,
                    'bLengthChange': false,
                    'bFilter': false,
                    'bInfo': false,
                    'bAutoWidth': false,
                    'aoColumns': [
                        { 'sSortDataType': 'dom-economy' },
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        null,
                        null
                    ]
                });
                plugin.columnSetList = plugin.columnSetList().appendTo('#columnsets');

                $instance.find('[data-region]').each(function (index, element) {
                    var slice = $(element).attr('data-region');
                    if ($.inArray(slice, slices) == -1) {
                        slices.push(slice)
                    }
                });

                $.each(slices, function (index, element) {
                    $('<option />', {
                        'text': element,
                        'value': element
                    }).appendTo($regionFilter);
                });
                $regionFilter.change(plugin.filterByRegion);

                plugin.showColumnSet(0);
            },
            'filterByRegion': function (evt) {
                var $tr = $instance.find('tbody tr').show(),
                    val = $(this).val();
                if (!!val) {
                    $tr.filter(':not([data-region="' + val + '"])').hide();
                }
            },
            'columnSets': (function () {
                var $indicators = $instance.find('col.indicator'),
                    slices = Math.ceil($indicators.length / 6),
                    sets = [];
                for (var i = 0; i < slices; i++) {
                    var start = i * num + 1,
                        end = (i + 1 == slices) ? $indicators.length : start + num - 1,
                        cols = [];
                    for (var j = start; j <= end; j++) {
                        cols.push($('tr > :nth-child(' + (j + 1) + ')'));
                    }
                    sets.push(cols);
                }
                return sets;
            })(),
            'columnSetList': function () {
                var plugin = app.topicData,
                    list = $('<ul />', {
                        'id': 'column-sets'
                    });
                $.each(plugin.columnSets, function (index, object) {
                    plugin.columnSetLink(index).appendTo(list);
                });
                return list;
            },
            'columnSetLink': function (n) {
                var plugin = app.topicData,
                    indicators = $('col.indicator').length,
                    item = $('<li />'),
                    start = num * n + 1,
                    end = (start + 5 > indicators) ? indicators : start + 5,
                    link = $('<a />', {
                        'href': '#',
                        'text': start + '-' + end,
                        'click': function (evt) {
                            evt.preventDefault();
                            app.topicData.showColumnSet(n);
                        },
                        'data-columnset': n,
                        'class': 'columnset'
                    }).appendTo(item);
                return item;
            },
            'showColumnSet': function (n) {
                $.each(this.columnSets, function (setIndex, set) {
                    $.each(set, function (index, elem) {
                        if (n == setIndex) $(elem).show();
                        else $(elem).hide();
                    });
                });
                $('.columnset').removeClass('active').filter('[data-columnset="' + n + '"]').addClass('active');
            }
        };

    };

    // Encapsulates the various functionality of the large custom query table
    app.cq = function () {
        var $instance = $('#custom-query');
        if (!$instance.length) return false;
        return {
            'initialize': function () {
                var plugin = app.cq;
                plugin.showHideError();
                $instance.find('.table-wrapper > table').each(function (index, element) {
                    /*
                    var oTable = $(element).dataTable({
                    "sScrollX": "944px",
                    "bScrollCollapse": true,
                    "bPaginate": false,
                    "bFilter": false,
                    "bInfo": false,
                    "bAutoWidth": false,
                    "bSort": false
                    });
                    */
                    var rowCountries = [],
                        $rows = $(element).find('tr[data-type]');
                    $thEconomy = $(element).find('th.economy div').eq(0);

                    $('<a />').attr('href', '#')
                             .addClass('expand-collapse')
                             .html('Expand all<span></span>')
                             .appendTo($thEconomy);

                    $rows.each(function (idx) {
                        var $tr = $(this),
                            $tdFirst = $tr.find('td.economy'),
                            $tdFirstDiv = $tdFirst.find('div').eq(0),
                            $breakdown = $tdFirst.find('.breakdown');

                        var $breakdownLen = $breakdown.length;

                        if ($breakdownLen != 0) {
                            $('<a />').attr('href', '#')
                                      .addClass('ir expand-toggle')
                                      .text('open')
                                      .appendTo($tdFirstDiv);
                            $tr.addClass('hasSlice');
                        }

                        $tr.addClass('closed');
                        if ($tr.attr('data-type') == 'country' && $tr.hasClass('hasSlice')) {
                            rowCountries.push($tr);
                        }
                    });

                    $(rowCountries).each(function (idx) {
                        var $tr = $(this);
                        if (idx == 0) {
                            $tr.addClass('open').removeClass('closed');
                        }
                    });

                    plugin.showHideCuts();
                    plugin.showAllCuts($rows, element);
                });
            },

            'showHideError': function () {
                var $showErrorToggle = $("#showerrors:checked");
                var $stdErrs = $("span.stderr");

                $showErrorToggle.click(function () {
                    var $elem = $(this);
                    if ($(this).is(":checked")) {
                        $stdErrs.removeClass('stderr-hidden');
                    }
                    else {
                        $stdErrs.addClass('stderr-hidden');
                    }
                });
            },

            'showHideCuts': function () {
                var $expandToggle = $(".expand-toggle");

                $expandToggle.click(function (e) {
                    e.preventDefault();
                    var $elem = $(this),
                        $parent = $elem.parents('tr'),
                        $breakdown = $parent.find('.breakdown'),
                        visible = 0;

                    if ($breakdown.length == 0) return;

                    if ($parent.hasClass('open')) {
                        visible = 1;
                    }

                    if (visible == 0) {
                        $parent.addClass('open').removeClass('closed');
                        $elem.text('close');
                        visible = 1;
                    }
                    else {
                        $parent.addClass('closed').removeClass('open');
                        $elem.text('open');
                        visible = 0;
                    }
                });
            },

            'showAllCuts': function (rows, element) {
                var $rows = rows,
                    $toggleAll = $(".expand-collapse"),
                    $table = $(element),
                    allOpen = 0;

                $toggleAll.click(function (e) {
                    e.preventDefault();
                    var $a = $(this);

                    if (allOpen == 0) {
                        $rows.each(function () {
                            var $tr = $(this);
                            if ($tr.hasClass('hasSlice')) {
                                $tr.addClass('open').removeClass('closed');
                            }
                        });
                        //$table.addClass('all-open');
                        $a.addClass('expanded-all').html('Collapse All <span></span>');
                        allOpen = 1;
                    }
                    else {
                        $rows.each(function () {
                            var $tr = $(this);
                            if ($tr.hasClass('hasSlice')) {
                                $tr.addClass('closed').removeClass('open');
                            }
                        });
                        //$table.removeClass( 'all-open' );
                        $a.removeClass('expanded-all').html('Expand All <span></span>');
                        allOpen = 0;
                    }
                });
            }
        }
    };

    $(function () {
        app.initialize();
        /*$('#homepage #modules > *').equalizeHeights();*/
        $('#homepage #modules .row').each(function (index, element) {
            $(element).children().equalizeHeights();
        });
        $('[placeholder]').placeholder();

        if ($.browser.mozilla) {
            var version = $.browser.version.split('.');
            if (version[0] <= 1 &&
               version[1] <= 9 &&
               version[2] <= 1 &&
               version[3] <= 20) {
                $('body').addClass('ff35');
            }
        }
    });

})(jQuery);
