/// <reference path="http://localhost/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />

define([
  // Application.
  "app",

  //templates-loader
  "js/templates-loader"

],

function (app, T) {

    //replace all Modal for the name of your view.
    var Modal = { Model: {}, Views: {} }

    //you can create more than one model, default model is called Model.
    Modal.Model = Backbone.Model.extend({
        defaults: {}
    });

    //you can create more than one view, default view is called Main.
    Modal.Views.Main = Backbone.View.extend({
        template: "modal/simple-modal"
        , id: "modal"
        , title: ""
        //default not cacheable, change this if you want the view to be cacheable
        // if the view is set as cacheable should also have a reRender method to reset the view without erasing the DOM.
        //refreshing only the data, maybe?
        , className: "modal hide fade"
        , isCacheable: false
        , initialize: function (options) {
            this.options = _.extend({
                title: null,
                focusOk: true,
                okCloses: true,
                allowCancel: true,
                escape: true,
                animate: false,
                content: null,
                message: null,
                buttons_type: "CONTINUE-CANCEL",
                custom_buttons: [], 
                _isRendered: false,
                _isRendering: false, 
                modalOptions: {},
                templateOptions: {}, 
            }, options);

            _.bindAll(this); 
        },

        events: {
            'click .close': function (event) {
                event.preventDefault();

                this.trigger('cancel');

                if (this.options.content && this.options.content.trigger) {
                    this.options.content.trigger('cancel', this);
                }
            },
            'click #btn-cancel': function(event) {
                event.preventDefault();

                this.trigger('cancel');

                if (this.options.content && this.options.content.trigger) {
                    this.options.content.trigger('cancel', this);
                }
            },
            'click #btn-continue': function(event) {
                event.preventDefault();

                this.trigger('continue');

                if (this.options.content && this.options.content.trigger) {
                    this.options.content.trigger('continue', this);
                }

                if (this.options.okCloses) {
                    this.hide();
                }
            },
            'click .modal-custom-btn': function (event) {
                event.preventDefault();
                this.trigger("customButtonClicked", { e: event, buttonid: $(event.currentTarget).data("buttonid"), modal: this });
            }, 
        }, 
        // global view variable (seen in this scope, public to the view, and SHARED BETWEEN OTHER INSTANCES OF THE SAME VIEW)
        // containing all the variables for this view

        //properties that you wanna scope as private variables for each instance of a view should not be placed here
        //the only way i found to maintain the variables between instances of the same view, is either using models,
        // (each view will have its own model so data is not shared between them), or in case you don't want to use a model
        // you can use the Backbone.View.options object, and doing something like
        // this.options.attributes = {}
        // and storing every single variable inside attributes.

        //render the view when it's not cached (first time or view is not cacheable); 
        //arguments [0] container, [1] viewParams from URL
        render: function (container, viewParams) {
            var that = this;
            that.options._isRendering = true; 
            var thatContainer = container;
            T.render.call(this, this.template, function (tmp) {
                //getInternationalizationData
                if (!that.options.i18n) that.options.i18n = {};
                app.getI18NJed(that, that.template, function (i18nJED) {
                    //storing internationalization data
                    that.options.i18n[that.template] = i18nJED;

                    //start: before the view is visible, but the template was already loaded (not instanced nor appended)
                    var tmpOptions = _.extend({
                        modalID: that.id
                        , header_title: that.options.title
                        , message: (that.options.message) ? that.options.message : false
                        , buttons_type: that.options.buttons_type
                        , allowCancel: that.options.allowCancel
                        , buttons: (that.options.buttons_type == "CUSTOM-BUTTONS") ? that.options.custom_buttons : []
                    }, that.options.templateOptions); 
                    //end:

                    //loading the view and appeding it to the views's $el.
                    that.$el.html(tmp(tmpOptions));

                    if (that.options.content) {
                        that.$(".modal-body").html(that.options.content); 
                    }

                    //start: the view was already loaded an is on a div element, but not appended to the main container
                    //here you can perform anything you want DOM related, by getting the dom element via that.$el.find("#id")
                    that.options._isRendering = false; 
                    that.options._isRendered = true; 
                    //:end

                    //appending view to the main container
                    //thatContainer.append(that.$el);

                });
            });
        }
        , close: function () {
            this.remove();
            this.unbind();
        }
        , show: function (cb) {
            
            if (!this.options._isRendered) {
                this.render();
                setTimeout(this.show, 100, cb);
                return; 
            }

            var self = this,
            $el = this.$el;

            //creating modal
            $el.modal(_.extend({
                keyboard: this.options.allowCancel,
                backdrop: this.options.allowCancel ? true : 'static'
            }, this.options.modalOptions));

            //Focus OK button
            $el.one('shown', function () {
                if (self.options.focusOk) {
                    $el.find('#btn-continue').focus();
                }
                else if (self.options.focusSelector) {
                    $el.find(self.options.focusSelector).focus();
                }

                if (self.options.content && self.options.content.trigger) {
                    self.options.content.trigger('shown', self);
                }

                self.trigger('shown');
            });

            $backdrop = $('.modal-backdrop'); 

            //if allows cancel, then attaching to cancel events
            if (this.options.allowCancel) {
                $backdrop.one('click', function () {
                    if (self.options.content && self.options.content.trigger) {
                        self.options.content.trigger('cancel', self);
                    }

                    self.trigger('cancel');
                });

                $(document).one('keyup.dismiss.modal', function (e) {
                    e.which == 27 && self.trigger('cancel');

                    if (self.options.content && self.options.content.trigger) {
                        e.which == 27 && self.options.content.trigger('shown', self);
                    }
                });
            }

            this.on('cancel', function () {
                self.hide();
            });

            if (cb) {
                self.on('continue', cb);
            }

            return this;

        }
        , hide: function () {
            
            var self = this,
            $el = this.$el;

            $el.one('hidden', function onHidden(e) {
                // Ignore events propagated from interior objects, like bootstrap tooltips
                if (e.target !== e.currentTarget) {
                    return $el.one('hidden', onHidden);
                }

                if (self.options.content && self.options.content.trigger) {
                    self.options.content.trigger('hidden', self);
                }

                self.trigger('hidden');

                self.close();
            });

            $el.modal('hide');

        }
        , reRender: function (viewParams) {
            //reRender is called when the route changes, the view routed is not the current view (see refresh for this case)
            //and the view is cached.
            //if the view is not cached, the render method will be executed instead of reRender
            //if you want render to be the only method executed then set "isCacheable" to false; 

            //here you could also call the refresh method if you are using stuff from the URL.
        }
        , refresh: function (viewParams) {
            //refresh is called when the route changes but the view that the route instances is the same
            //one that is already being shown. 
            //here you can do some stuff like working with parameters.
            //suggestion. the render method should only contain those methods that "draw" stuff. those which refresh elements
            //based on the URL parameters should be here. Then you can call from the render method to the refresh method.
            
            //IMPORTANT: if your view is listening to models and some parts of the view are changing according to the model, then
            //do not repeat that behaviour here. (This would only happen if the model also rewrites parameters on the URL and fires
            //a routing when going back in the history or manually); 

        }
    });

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

});
