(function($, Backbone) {

    var models = {},
        views = {},
        renderData = function (data) {
            var icons = [],
                categories = [];
            $.each(data, function (category, items) {
                $.each(items, function (content, d) {
                    categories.push(category);
                    icons.push({
                        category: category,
                        caption: content.replace(/_/g, ' '),
                        className: content.replace(/_/g, '-'),
                        content: content,
                        code: d[0].toUpperCase(),
                        is_new: d[1] && true
                    });
                });
            });
            var view = new views.Icons({collection: new models.Icons(icons)});
            view.render();
        };

    models.Icon = Backbone.Model.extend();

    models.Icons = Backbone.Collection.extend({
        model: models.Icon
    });

    views.Icon = Backbone.View.extend({
        tagName: 'div',
        className: 'item-container',
        template: _.template($('#grid-item').html()),
        events : {
            "click" : "showSnackBar"
        },
        initialize: function (options) {
            this.listenTo(this.model, 'hideSnackBar', this.hideSnackBar);
            _.bindAll(this, 'render', 'hideSnackBar');
        },
        render: function () {
            $(this.el).html(this.template(this.model.attributes));
            return this;
        },
        showSnackBar: function() {
            $("body").click();
            this.model.trigger('hideSnackBar');
            $(this.el).addClass("selected");
            var view = new views.snackbarView({model: this.model});
            navigate(this.model.attributes.className);
            view.render();
            return false;
        },
        hideSnackBar: function() {
            $(this.el).removeClass("selected");
            navigate();
        }
    });

    views.snackbarView = Backbone.View.extend({
        container: $('#snackbar'),
        template: _.template($('#snackbar-template').html()),
        initialize: function (options) {
            this.collection = options.collection;
            $("body").on("click focus", $.proxy(this.hide, this));
        },
        render: function () {
            var hidden = !this.container.children(".container:not(:hidden)").length;
            this.container.empty();
            this.container.append(this.template(this.model.attributes));
            if (hidden) {
                this.container.children(".container").hide().slideDown('fast');
            } else {
                this.container.children(".container").stop(0, 0).slideDown('fast');
            }
        },
        hide: function() {
            this.model.trigger('hideSnackBar');
            this.container.children(".container").slideUp('fast');
        }
    });

    views.Icons = Backbone.View.extend({
        container: $('#grid-container'),
        empty_content: $('#empty-grid').html(),
        search_input: $('#search'),
        search_clear: $('#search-panel .clear-icon'),
        initialize: function (options) {
            this.collection = options.collection;
            this.search_input.bind('keyup', $.proxy(this.search, this));
            this.search_clear.bind('click', $.proxy(this.clear_search, this));
            _.bindAll(this, 'render');
        },
        clear_search : function() {
            this.search_input.val('');
            this.search_input.focus();
            this.search();
            return this;
        },
        search: function () {
            var str = this.search_input.val();
            if (str.length > 0) {
                this.search_clear.show();
            } else {
                this.search_clear.hide();
            }
            str = str.replace(/[\-_]+/g, ' ').replace(/\s+/, ' ').trim();
            if (str.length > 0) {
                var models = this.collection.filter(function (item) {
                    return item.get("caption").indexOf(str) > -1
                });
                this.render(models);
            } else {
                this.render();
            }
            $('body, html').animate({scrollTop: this.container.offset().top - 64}, 0);
            return this;
        },
        render: function (searchCollection) {
            var container = this.container,
                category = null,
                grid = $("<div/>", {"class" : "grid"}),
                self = this,
                models = searchCollection || this.collection;
            container.empty();
            models.forEach(function (item) {
                var itemView = new views.Icon({model: item});
                if (category === null) {
                    category = item.get('category');
                }
                if (category !== item.get('category')) {
                    $("<h2/>").html(category.charAt(0).toUpperCase() + category.slice(1)).
                        appendTo(self.container);
                    grid.appendTo(self.container);

                    category = item.get('category');
                    grid = $("<div/>", {"class" : "grid"});
                    grid.append(itemView.render().el);
                } else {
                    grid.append(itemView.render().el);
                }
            });
            if (category !== null) {
                $("<h2/>").html(category.charAt(0).toUpperCase() + category.slice(1)).
                    appendTo(self.container);
                grid.appendTo(self.container);
            } else {
                container.html(self.empty_content);
            }
            return this;
        }
    });

    var Router = Backbone.Router.extend({
        routes: {
            '': 'index',
            ":query": "item",
        },
        index: function() {
            renderData(window.data);
        },

        item: function(query) {
            renderData(window.data);
            setTimeout(function() {
                var item = $(".item-container > .item > .mdi.mdi-" + query.replace(/[^0-9a-zA-Z]/g, '-'))
                    .closest(".item-container");
                if (item.length) {
                    item.trigger("click");
                    $('body, html').animate({scrollTop: item.offset().top - 74}, 0);
                }
            }, 50);
        }
    });

    var navigate = function(hash) {
        var scrollTop = $(window).scrollTop();
        Backbone.history.navigate(hash, false);
        $('body, html').animate({scrollTop: scrollTop}, 0);
    };

    $(document).ready(function () {
        var is_fixed_search = false,
            $win = $(window),
            search_panel = $("#search-panel"),
            header_panel = $("#head-panel");

        $win.on("scroll resize", function () {
            if ($win.scrollTop() > header_panel.outerHeight()) {
                if (!is_fixed_search) {
                    is_fixed_search = true;
                    search_panel.addClass("top-fixed");
                }
            } else {
                if (is_fixed_search) {
                    is_fixed_search = false;
                    search_panel.removeClass("top-fixed");
                }
            }
        });

        $("body").on("focus", "textarea.code", function() {
            var $this = $(this);
            $this.select();
            window.setTimeout(function() {
                $this.select();
            }, 1);
            function mouseUpHandler() {
                $this.off("mouseup", mouseUpHandler);
                return false;
            }
            $this.mouseup(mouseUpHandler);
        });

        $("#snackbar").on("click focus", function(e) {
            e.preventDefault();
            return false;
        });

        new Router;
        Backbone.history.start();

    });
}) (jQuery, Backbone);
