//SCREEN-BOILERPLATE

//this boilerplate builds screens that are gonna be shown in the <div class="content"> tag of our main HTML.
//do not build app components with this boilerplate, only screens (reports)

define([
  // Application variable, always include it to have access to app methods.
  "app",

  //templates-loader: this loads templates async.
  "js/templates-loader",

  "modules/modal",
  
  "Mousetrap",

],

function (app, T, Modal, Mousetrap) {

    //replace all "ViewName" with your view's name.
    var ViewName = { Model: {}, Views: {} }

    ViewName.Model = Backbone.Model.extend({
        defaults: {
            procedure: ''
            , window_size: null
        }
    });

    //the generate id method is called everytime a view is going to be shown by the router and returns and id that
    //is used by the router to store in cache (if it is cacheable) and to know the current shown view.
    //this is useful in case your view is reusable, and displays different data depending on url parameters 
    //(such as a catalog view, or a report that doesnt change in terms of UI but it does change in terms of data)
    //so you can always use the same view on the router but the cache can tell which view is which by using differents ids.
    ViewName.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "trending"; 
        } catch (Error) { }
    }

    ViewName.Views.Main = Backbone.View.extend({
        template: "trending"
        , id: "trending"
        , title: "Trending"
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a refresh method to reset the view without erasing the DOM.
        , isCacheable: false
        , initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            _.bindAll(this); 

            if (this.options.viewParams) {
            }

            var model = new ViewName.Model({
                procedure: "dbo.procedureName"
            });

            this.model = model;

            this.bindEvents();
        },
        exportingTimeoutID: null,

        events: {
        }, 

        render: function (container) {
            var that = this;
            var thatContainer = container;
            this.options.MYREFERENCES = {};
            this.options.container = container; 

            //the screens have a custompath, so it has to be specified in the customPath variable that is
            //then sent to the template loader.
            var customPath = "/app/custom-screens/trending/";

            T.render.call(this, this.template, function (tmp) {

                var jsonParams = {
                    timezone: app.models.user.get("timezoneCode"),
                    connstring: app.ConnectionStrings.app,
                    catalog: app.DatabaseNames.IH,
                };

                if (that.options.viewParams && that.options.viewParams.params) {
                    var url_params = that.options.viewParams.params;
                    var params_dict = {}; 
                    url_params = url_params.split(",");
                    _.each(url_params, function (p) {
                        var splitted = p.split("=");
                        if (splitted.length > 1)
                            params_dict[splitted[0].toString()] = splitted[1].toString(); 
                    });
                    jsonParams = _.extend(jsonParams, params_dict); 
                }

                var urlParams = "?" + $.param(jsonParams);

                //loading the view and appeding it to the views's $el.
                that.$el.html(tmp({ params: urlParams }));

                that.$el.find("#widget-frame").height($(window).height() - 85);
                that.model.set("window_size", $(window).height()); 
                that.$el.find("#widget-frame").on("load", that.frameLoaded);

                that.append(thatContainer, that.$el, false); 

                that.bindViewScopedEvents();

            }, customPath);
        }

        , append: function (container, el, fireEvent) {
            el = (el != null && el != undefined) ? el : this.$el;
            fireEvent = (_.isBoolean(fireEvent)) ? fireEvent : true;

            if (this.options.state == app.view_states.loading
                || this.options.state == app.view_states.shown) {
                //appending view to the main container and set state to shown

                this.options.state = app.view_states.shown;
                container.append(el);

                if (fireEvent) this.options.onappend(this);
            }
            else if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }
            else if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        }
        , frameLoaded: function () {
            this.options.onappend(this);

            //To fix issue in Chrome when excel exportation makes window to be resized and then the view is rendered again
            //losing all changes made in trending view like variables added or scales modifications.
            $(this.$el.find("#widget-frame")[0].contentWindow.document).on('click.ui-icon-excel', this.iframe_excelIcon_click);
        }
        , refresh: function () {
            try {
                this.options.viewParams = arguments[0];
                if (this.options.viewParams.params) {
                    var params = this.options.viewParams.params;
                    var paramsArr = params.split(",");
                    var paramsDict = {}; 

                    for (var i = 0; i < paramsArr.length; i++) {
                        var splitted = paramsArr[i].split("="); 
                        paramsDict[splitted[0].toString()] = splitted[1].toString(); 
                    }

                    var customView = (paramsDict && paramsDict["view"]) ? paramsDict["view"] : null; 

                    var frame = this.$el.find("#widget-frame")[0]; 
                    var contentWindow = (frame.contentWindow || frame.contentDocument);

                    var icc = contentWindow.icc;
                    icc.SetView(customView); 
                }
            } catch (Error) { }
        }

        , iframe_excelIcon_click: function (e) {
            clearTimeout(this.exportingTimeoutID);

            var that = this;

            this.model.set('exporting', true);

            this.exportingTimeoutID = setTimeout(function () {
                that.model.set('exporting', false);
            }, 30 * 1000);
        }

        , windowResized: _.debounce(function () {
            if (this.model.get('exporting') != true) {
                if (this.model.get("window_size") != $(window).height()) {
                    this.$el.find("#widget-frame").height($(window).height() - 85);
                    this.model.set("window_size", $(window).height());
                    this.render(this.options.container);
                }
            }
        }, 800)

        , bindEvents: function () {
            //this function should be in every view that uses listenTo anywhere
            //all the model bindings or view-model binding should be here, to manage
            //the show/hide view easily
        }

        , bindViewScopedEvents: function () {
            $(window).on("resize", this.windowResized); 
        }

        , unbindViewScopedEvents: function () {
            $(window).off("resize", this.windowResized); 
        }

        , close: function () {
            this.options.state = app.view_states.closed;
            this.unbindViewScopedEvents(); 

            this.remove();
            this.unbind();
        }

        , show: function () {
            this.options.state = app.view_states.shown;
            this.bindViewScopedEvents(); 

            this.bindEvents();
            this.$el.show();
        }

        , hide: function () {
            this.options.state = app.view_states.hidden;
            this.unbindViewScopedEvents();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        }

        , preRender: function () {
            app.models.subnavbar.set("dateControl", false);
            app.models.subnavbar.set("notificationBar", false);
            app.models.subnavbar.set("subnavbar", false);
        }

        , reRender: function () {
        }
    });

    // Required, return the module for AMD compliance.
    return ViewName;

});
