/// <reference path="http://localhost/IndustrialDashboard/Scripts/IndustrialDashboard-debug.js" />
define([
  // Application.
  "app",

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

],

function (app, T) {

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

    //you can create more than one model, default model is called Model.
    NavBarClock.Model = Backbone.Model.extend({
        defaults: {
            date:null
            , hours: null
            , minutes: null
            , seconds: null
            , string_hours: ""
            , string_minutes: ""
            , string_seconds: ""
            , addTimeout: null
            , fetchTimeout: null
            , syncEvery: (1000 * 60) * 30
        }
        , initialize: function () {
            _.bindAll(this);
            this.listenTo(app.models.user, "change", this.syncWithServer); 
        }
        , fetch: function (success, async) {
            
            ////overriding fetch method
            ////according to our needs.

            var that = this;
            async = (async != null && async != undefined) ? async : true; 

            var QP = new Core.Database.QueryParameters(); 
            if (app.models.user.get("timezoneIsAutomatic")) {
                QP.Add("TimeZone", "CHAR", app.models.user.get("timezoneCode")); 
            }

            Core.Json.CallProcedure("FRONTEND.SyncTimeWithServer", QP, {

                onSuccess: function (data) {
                    try {
                        if (data && !data.Message) {
                            if (Core.Object.Exist(data, "Table")) {
                                data = data.Table[0]; 
                                var date = data.TimeStamp; 
                                var now = Core.DateTime.Parse(date);
                                
                                that.set("date", now, {silent:true});
                                that.setFromDate(); 
                                success(); 
                                return that;

                            }
                        }
                    } catch (Error) { }
                }
                , onFailure: function () {
                    try{
                    } catch (Error) { }
                }
                , Async: async
            }, app.ConnectionStrings.app); 

        }
        , format: function (value) {
            if (value < 10)
                value = "0" + value;

            return value; 
        }
        , syncWithServer: function (options) {
            var opt = {
                async: true
            }; 

            opt = _.extend(opt, options); 

            //console.log("synced with server");
            //if (this.get("date")) console.log("time before sync: " + this.get("date").toString());

            if (this.attributes.addTimeout) clearTimeout(this.attributes.addTimeout);

            this.fetch(this.fetchComplete, opt.async);

            if (this.attributes.fetchTimeout) clearTimeout(this.attributes.fetchTimeout);

            this.attributes.fetchTimeout = setTimeout(this.syncWithServer, this.get("syncEvery"), this);
        }
        , addSecond: function () {
            if (this.attributes.addTimeout) clearTimeout(this.attributes.addTimeout); 
            this.attributes.addTimeout = setTimeout(this.addSecond, 60000);

            var date = this.get("date");
            date = new Date(date.getTime() + 60000);
            this.set("date", date, { silent: true });
            this.setFromDate();
        }
        , setFromDate: function () {

            var date = this.get("date");
            var jsonObj = {};
            //Core.Object.Extend(this.attributes, jsonObj);
            _.extend(jsonObj, this.attributes); 
            jsonObj.hours = date.getHours();
            jsonObj.minutes = date.getMinutes();
            jsonObj.seconds = date.getSeconds();
            jsonObj.string_hours = this.format(jsonObj.hours);
            jsonObj.string_minutes = this.format(jsonObj.minutes);
            jsonObj.string_seconds = this.format(jsonObj.seconds);

            //change method is fired.
            this.set(this.parse(jsonObj), {});

        }
        , fetchComplete: function () {
            //if (this.get("date")) console.log("time after sync: " + this.get("date").toString());
            var timeOutSeconds = (60 - this.get("date").getSeconds()) * 1000;
            if (this.attributes.addTimeout) clearTimeout(this.attributes.addTimeout);
            this.attributes.addTimeout = setTimeout(this.addSecond, timeOutSeconds);
        }
        , startAutoFetch: function () {
            this.syncWithServer();
        }
    });

    //you can create more than one view, default view is called Main.
    NavBarClock.Views.Main = Backbone.View.extend({
        template: "navbar-clock/navbar-clock"
        , id: ""
        , 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?

        , isCacheable: false
        , initialize: function () {
            this.listenTo(this.model, "change", this.render); 
        },
        // 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;
            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(that.model.toJSON()));
                    that.$el.find('.tooltip-this').tooltip();
                    //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")

                    //:end

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

                });
            });
        }
        , close: function () {
            this.remove();
            this.unbind();
        }
        , show: function () {
            this.$el.show();
        }
        , hide: function () {
            this.$el.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 NavBarClock;

});
