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

define([
  // Application.
  "app",

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

  "Mousetrap", 

  //"js/bootstrap-datepicker/js/bootstrap-datepicker",
  "js/bootstrap-timepicker/js/bootstrap-timepicker", 

  "js/bootstrap-select/bootstrap-select"

],

function (app, T, Mousetrap) {

    var DateTimeScopeControl = { Model: {}, Views: {} }

    DateTimeScopeControl.Model = Backbone.Model.extend({
        defaults: {
            datetime: Core.DateTime.ToString(new Date(), "yyyy-mm-dd HH:MM:ss")
            , interval: 60*60 //seconds
            , start: ""
            , end: ""
        }
        , initialize: function () {
            _.bindAll(this);

            this.listenTo(this, "change:datetime change:interval", this.update_startend); 

            this.update_startend(); 
        }
        , update_startend: function () {
            this.set("start", this.get("datetime"));
            var startDate = Core.DateTime.Parse(this.get("start"));
            var endDate = new Date(startDate.getTime() + 1000 * parseInt(this.get("interval"), 10));
            this.set("end", Core.DateTime.ToString(endDate, "yyyy-mm-dd HH:MM:ss"));
            //logging
            //_.each(this.attributes, function (value, key) {
            //    console.log(key + ": " + value); 
            //}); 
        }
        , getTime: function () {
            return Core.DateTime.ToString(Core.DateTime.Parse(this.get("datetime")), "HH:MM:ss"); 
        }
        , setTime: function (time) {
            this.set("datetime", Core.DateTime.ToString(Core.DateTime.Parse(this.get("datetime")), "yyyy-mm-dd") + " " + time); 
        }
        , setDate: function (date) {
            this.set("datetime", date + " " + Core.DateTime.ToString(Core.DateTime.Parse(this.get("datetime")), "HH:MM:ss"));
        }
        , getDate: function () {
            return Core.DateTime.ToString(Core.DateTime.Parse(this.get("datetime")), "yyyy-mm-dd");
        }
    });

    DateTimeScopeControl.Views.Main = Backbone.View.extend({
        template: "dateTimeScopeControl/dateTimeScopeControl"
        , id: "global-datetimescope-control"
        , 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 refresh method to reset the view without erasing the DOM.
        //refreshing only the data, maybe?
        , isCacheable: false
        , initialize: function () {
            this.options.MYREFERENCES = {
                seekStep: 0
                , seekTimeout: null
                , timepicker: {
                    isFocused: false
                }
            };

            _.bindAll(this); 

            this.listenTo(this.model, "change:datetime", this.dateModelChanged);
            this.listenTo(this.model, "change:datetime", this.timeModelChanged);
            this.listenTo(this.model, "change:interval", this.intervalModelChanged);

            this.bindEvents(); 
        }, 
        // 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.

        events: {
            "click #datetimescope_calendar-icon-clickeable": "showCalendar"
            , "focus #datetimescope_datePicker1": "showCalendarFocus"
            , "blur #datetimescope_datePicker1": "calendarChanged"
            , "keydown #datetimescope_datePicker1": "calendar_onKeyDown"
            //, "click #datetimescope_time-icon-clickeable": "setFocusTime"
            , "focus #datetimescope_timePicker1": "timepicker_focus"
            , "blur #datetimescope_timePicker1": "timepicker_blur"
            , "keydown #datetimescope_timePicker1": "timepicker_onKeyDown"
            , "change #datetimescope_intervalPicker1": "intervalpicker_onChange"
            , "click #datetimescope_btn_back": "back_click"
            , "click #datetimescope_btn_forward": "forward_click"
        }, 

        render: function (container) {
            var that = this;
            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)

                    //end:

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

                    //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.MYREFERENCES.datePicker1 = that.$el.find("#datetimescope_datePicker1").datepicker(
                        _.extend({
                            showOn: "focus"
                            , beforeShow: function () { that.calendarBeforeShow.call(that); }
                            , onSelect: function () { that.calendarChanged.call(that); }
                            , showOtherMonths: true
                            , selectOtherMonths: true
                            , dateFormat: 'yy-mm-dd'
                        }, that.options.datepicker_options || {})
                    );

                    that.options.MYREFERENCES.datePicker1.datepicker("setDate", Core.DateTime.Parse(that.model.get("datetime")));

                    $(".ui-datepicker").wrap('<div class="jqueryUIcontrols" />');

                    var defaultOptions = {
                        template: 'dropdown'
                        , minuteStep: 1
                        , secondStep: 1
                        , showSeconds: true
                        , defaultTime: false
                        , showMeridian: false
                    };

                    that.options.MYREFERENCES.timePicker1 = that.$("#datetimescope_timePicker1").timepicker(defaultOptions);

                    that.options.MYREFERENCES.timePicker1.timepicker("setTime", that.model.getTime()); 

                    that.options.MYREFERENCES.intervalPicker1 = that.$("#datetimescope_intervalPicker1").selectpicker({});

                    that.options.MYREFERENCES.intervalPicker1.selectpicker("val", that.model.get("interval")); 

                    that.options.MYREFERENCES.timePicker1.timepicker().on("changeTime.timepicker", that.timepicker_ev_changeTime); 

                    //:end

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

                }, false);
            });
        }
        , dateModelChanged: function () {
            if (this.options.MYREFERENCES.datePicker1) {
                if (Core.DateTime.ToString(this.options.MYREFERENCES.datePicker1.datepicker("getDate"), "yyyy-mm-dd") != this.model.getDate())
                    this.options.MYREFERENCES.datePicker1.datepicker("setDate", Core.DateTime.Parse(this.model.get("datetime")));
            }
        }
        , timeModelChanged: function () {
            if (this.options.MYREFERENCES.timePicker1) {
                if (this.options.MYREFERENCES.timePicker1.data("timepicker").getFormattedTime("24") != this.model.getTime()) {
                    this.options.MYREFERENCES.timePicker1.timepicker("setTime", this.model.getTime()); 
                }
            }
        }
        , intervalModelChanged: function () {
            if (this.options.MYREFERENCES.intervalPicker1) {
                if (this.options.MYREFERENCES.intervalPicker1.selectpicker("val") != this.model.get("interval")) {
                    this.options.MYREFERENCES.intervalPicker1.selectpicker("val", this.model.get("interval")); 
                }
            }
        }
        , calendarChanged: function () {
            var dateSelected = Core.DateTime.ToString(this.options.MYREFERENCES.datePicker1.datepicker("getDate"), "yyyy-mm-dd");
            this.model.setDate(dateSelected);
        }
        , timepicker_focus: function () {
            this.options.MYREFERENCES.timepicker.isFocused = true;
        }
        , timepicker_ev_changeTime: function () {
            var isFocused = this.options.MYREFERENCES.timepicker.isFocused;
            if (!isFocused) {
                var timeSelected = this.options.MYREFERENCES.timePicker1.data("timepicker").getFormattedTime("24");
                this.model.setTime(timeSelected);
            }
        }
        , timepicker_blur: function (params) {
            //var timeSelected = this.options.MYREFERENCES.timePicker1.data("timepicker").getFormattedTime("24");
            //this.model.setTime(timeSelected);
            this.options.MYREFERENCES.timepicker.isFocused = false; 
        }
        , timepicker_onKeyDown: function (event) {
            if (event.which) {
                switch (event.which) {
                    //enter key
                    case 13:
                        this.options.MYREFERENCES.timePicker1.blur(); 
                        break;
                    //escape key
                    case 27:
                        this.timeModelChanged();
                        this.options.MYREFERENCES.timePicker1.blur();
                        break; 
                }; 
            }
        }
        , calendar_onKeyDown: function (event) {
            if (event.which) {
                switch (event.which) {
                    //enter key
                    case 13:
                        this.options.MYREFERENCES.datePicker1.blur();
                        break;
                        //escape key
                    case 27:
                        this.dateModelChanged();
                        this.options.MYREFERENCES.datePicker1.blur();
                        break;
                };
            }
        }
        , setFocusTime: function () {
            try {
                this.$("#datetimescope_timePicker1").focus(); 
            } catch (Error) { }
        }
        , calendarBeforeShow: function () {
            try {                
            } catch (Error) { }
        }
        , showCalendar: function () {
            if (this.options.MYREFERENCES.datePicker1.datepicker("widget").is(":visible"))
                this.options.MYREFERENCES.datePicker1.datepicker("hide");
            else
                this.options.MYREFERENCES.datePicker1.datepicker("show"); 
        }
        , showCalendarFocus: function () {
            //$("#calendar-icon-clickeable").click();
        }
        , back_click: function () {
            this.seekStep("B"); 
        }
        , forward_click: function () {
            this.seekStep("F"); 
        }
        , seekStep: function (direction) {
            if (this.options.MYREFERENCES.seekTimeout != null) {
                clearTimeout(this.options.MYREFERENCES.seekTimeout);
                this.options.MYREFERENCES.seekTimeout = null;
            }

            if (direction == "F") {
                this.options.MYREFERENCES.seekStep += 1;
            } else if (direction == "B") {
                this.options.MYREFERENCES.seekStep -= 1;
            }

            var that = this;
            this.options.MYREFERENCES.seekTimeout = setTimeout(function () {
                var st = that.options.MYREFERENCES.seekStep;
                that.options.MYREFERENCES.seekStep = 0;
                
                var current = that.model.get("datetime");
                var currentDate = Core.DateTime.Parse(current);
                var currentInterval = that.model.get("interval");

                var newDate = new Date(currentDate.getTime() + st * (currentInterval * 1000));
                that.model.set("datetime", Core.DateTime.ToString(newDate, "yyyy-mm-dd HH:MM:ss"));
            }, 200); 
        }
        , intervalpicker_onChange: function () {
            var interval = this.options.MYREFERENCES.intervalPicker1.selectpicker("val");
            this.model.set("interval", parseInt(interval, 10)); 
        }
        , _setSectionsLayout: function () {
            app.models.subnavbar.set("sections", "6-6"); 
        }

        , bindEvents: function () {
            Mousetrap.bind("ctrl+right", this.forward_click);
            Mousetrap.bind("ctrl+left", this.back_click); 
        }

        , unbindEvents: function () {
            Mousetrap.unbind(["ctrl+right", "ctrl+left"]);
        }

        , close: function () {
            this.remove();
            this.unbindEvents(); 
            this.unbind();
        }
        , show: function () {
            this._setSectionsLayout();
            this.bindEvents(); 
            this.$el.show();
        }
        , hide: function () {
            this.unbindEvents();
            this.$el.hide();
        }
    });

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

});
