//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/modal2",
  "backgrid",
  "moment",
  
  'backgrid/moment-cell',
  'backgrid/select-integer-cell',
  'backgrid/duration-cell',
  'js/backgrid-0.3.5/extensions/valid-limit-cell/backgrid-valid-limit-cell',
  'backgrid/grouped-columns',
  'js/typeahead.extended/typeahead.extended'
],

function (app, T, Modal, Backgrid, moment, Furnace) {

    var Screen = { Models: {}, Views: {}, Collections: {} };


    const extractQueryParam = (param) => {
        const searchString = Backbone.history.location.search
        const splitted = searchString.slice(1).split('&')

        let qParams = {}

        for (let i = 0; i < splitted.length ; i++) {
            const p = splitted[i].split('=')
            value = parseInt(p[1])
            qParams[p[0]] = value ? value : p[1]
        }

        return qParams[param]
    }

    Screen.Models.Main = Backbone.Epoxy.Model.extend({
        defaults: {
            ladleId: 1,
            ladles: [],
            isLoading: true,
            hasData: false,
            sortType: null,

            computeds: {
                ladleId$: {
                    deps: ['ladleId'],
                    get: function (value) {
                        return value;
                    },
                    set: function (value) {
                        return value;
                    },
                },
            },
        },

        fetchLadles: function () {
            let that = this;

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.GetLadles',
                null,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table)) {
                                let records = resp.Table;

                                let newItems = _.map(records, function (obj) { return { value: obj.Id, label: obj.Name, }; });
                                that.set("ladles", newItems);
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error("Server response not valid.");
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            )


        },
    });

    //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.
    Screen.generateID = function (viewParams) {
        try {
            //if the viewparams change the view id, then evaluate the viewparams here
            //and return the appropiate id.
            return "ladle-wall";
        } catch (Error) { }
    };

    Screen.Views.Main = Backbone.Epoxy.View.extend({
        template: "ladle-wall",
        id: "ladle-wall",
        title: "Ladle Wall",
        //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,
        events: function () {
            return {
                'click #drainButton': 'drainLadle',
                'click #historyButton': 'historyButtonClick',
            };
        },

        autoRefresh: null,
        bindingSources: null,
        grids: null,
        items: null,
        subviews: null,
        templates: null,
        currentLadle: null,
        currentModal: null,
        listeners: null,

        initialize: function () {
            this.options.state = app.view_states.loading;
            this.options.onappend = (_.isFunction(this.options.onappend)) ? this.options.onappend : function () { };

            var that = this;

            this.autoRefresh = {
                enabled: null
                , toid: null
                , every: 30 * 1000
            };

            this.model = new Screen.Models.Main();

            this.model.fetchLadles();

            const ladles = this.model.get('ladles')

            const ladleParam = extractQueryParam('ladleid')

            const ladleToShow = ladleParam ? ladleParam : 1

            const currentLadle = ladles.filter(el => el.value === ladleToShow).pop()

            this.model.set('currentLadle', currentLadle)


            this.items = new Screen.Collections.Items()

            this.grids = {};

            this.bindingSources = {};

            this.listeners = {};

            this.bindEvents();
        },

        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
            this.listenTo(this.items, 'fetch', this.collection_fetch);

            this.listenTo(this.model, 'change:ladleId', this.ladleId_changed);
            this.listenTo(this.items, 'overrideReady', this.override_ready);
        },
        override_ready: function () {
            var params = this.model.toJSON();
            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    params,
                    {
                    }
                ),
            });
        },

        ladleId_changed: function () {
            var ladles = this.model.get('ladles'),
                ladleId = this.model.get('ladleId');
            var currentLadle = _.findWhere(ladles, { value: parseInt(ladleId) });
            this.model.set({ currentLadle: currentLadle });

            var params = this.model.toJSON();



            app.router.navigate(
                app.router.resolveURL(
                    app.router.currentModule,
                    _.extend(
                        {},
                        params,
                        {
                            ladleId: ladleId,
                        }
                    ),
                    false
                ),
                { trigger: false, }
            );

            this._refresh({
                reset: true,
                params: _.extend(
                    {},
                    params,
                    {
                    }
                ),
            });

        },
        _refresh: function (opt) {
            //console.log('autorefresh: ' + new Date().toString()); 
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }
            this.refreshItemsColl(_.extend(
                {},
                opt,
                {
                    params: {}
                })
            );

            if (this.autoRefresh.enabled == true) {
                var that = this;

                this.autoRefresh.toid = setTimeout(
                    function () { that._refresh(); },
                    this.autoRefresh.every
                );
            }
        },
        refresh: function (viewParams) {
            var fixedParams = _.extend({}, Screen.Models.Main.prototype.defaults, viewParams);

            //If currentModal exists, hide it and erase it.
            if (this.currentModal) {
                this.currentModal.hide();
                this.currentModal = null;
            }

            //Call first refresh.
            var params = this.model.toJSON();

            this._refresh(_.extend(
                {},
                params,
                {
                    reset: true,
                    params: _.extend(
                        {},
                        params,
                        {}
                    ),
                }
            ));
        },
        refreshItemsColl: function (options) {
            try {
                var that = this,
                    modelAttrs = this.model.toJSON(),
                    opt = _.extend({}, { params: {}, refresh: true, }, options);


                if (opt.reset == true) {
                    this.model.set({
                        isLoading: true,
                    });
                }

                //Parameter details:
                // > Parameter 'reset' is used to reload only the first page of records and
                // show the 'Loading' poster.
                // > Parameter 'refresh' is uset to reload all the currently loaded records
                // without showing the 'Loading' poster.
                this.items.fetch({
                    params: {
                        sortType: (modelAttrs.sortType) ? modelAttrs.sortType : null,
                        currentLadle: modelAttrs.currentLadle,
                    },
                    refresh: opt.refresh,
                    reset: opt.reset,
                });
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        openOverrideDialog: function (item, callback) {
            try {

                var that = this

                let template = Handlebars.compile(that.$el.find('#override_heat_counter_dialog').html())

                this.currentModal = new Screen.Views.OverrideHeatCounterModal({
                    model: new Screen.Models.OverrideHeatCounterModal({
                        ladleId: this.model.get('currentLadle').value,
                        ladle: this.model.get('currentLadle').label,
                        counterLabel: item.get('campaignCounter'),
                        counterValue: item.get('campaignCounter'),
                        partName: item.get("typeName"),
                        part: item.get("typeId"),
                        curPartId: item.get('equipmentId')
                    }),
                    template: template,
                    i18n: this.options.i18n[this.template],
                });

                var fn_modal_shown_hidden = function () {
                    try {
                        //Enable button in both events, shown and hidden, just to prevent issues if one of them fails
                        //or it is not executed for some reason.
                        //clickedBtn.attr("disabled", false);
                    }
                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                };

                this.listenToOnce(this.currentModal, 'shown', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'hidden', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'finish', function (modal, output) {
                        try {
                            if (output.result == 'SUCCESS') {
                                console.log("SUCCESS");
                                app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'), { stay: 5 * 1000, });
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    })
                    this.listenTo(this.currentModal, 'saveoverride', function (e) {
                     

                        callback(e);
                });;

                this.currentModal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        drainLadle: function () {
            // call procedure
            this.items.drainLadle({ ladle: this.model })

            this.model.set({ isLoading: true })
            this.items.fetch({
                params: {
                    currentLadle: this.model.get('currentLadle'),
                },
                reset: true
            });
        },

        historyButtonClick: function () {
            var params = this.model.toJSON();
           var end = new moment().format('YYYYMMDD'),
                 start = new moment().subtract(7, 'day').format('YYYYMMDD');

            var url = "!/ladle-history/" + start + "/" + end + "/"+ parseInt(params.ladleId);
            Backbone.history.navigate(url, true);

        },
        openSparePartsDialog: function (model, callback) {
            try {

                var that = this  // screen
                let template = Handlebars.compile(that.$el.find('#spare_part_modal').html())

                this.currentModal = new Screen.Views.SparePartsModal({
                    model: new Screen.Models.SparePartsModal({
                        ladle: that.model.get('currentLadle').label,
                        partName: model.get("typeName"),
                        part: model.get("typeId"),
                        curPartId: model.get('equipmentId')
                    }),
                    ladle: that.model,
                    template: template,
                    i18n: this.options.i18n[this.template],
                });

                var fn_modal_shown_hidden = function () {
                    try {
                        //Enable button in both events, shown and hidden, just to prevent issues if one of them fails
                        //or it is not executed for some reason.
                        //clickedBtn.attr("disabled", false);
                    }
                    catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                };

                this.listenToOnce(this.currentModal, 'shown', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'hidden', fn_modal_shown_hidden)
                    .listenToOnce(this.currentModal, 'finish', function (modal, output) {
                        try {
                            if (output.result == 'SUCCESS') {
                                app.views.topMessages.showMessage(app.translate([that, app], 'SAVED_CHANGES_SUCCESSFUL'), { stay: 5 * 1000, });
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    })
                this.listenTo(this.currentModal, 'savepart', function (e) {
                    callback(e)
                });;

                this.currentModal.show();
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }

        },
        render: function (container, viewParams) {
            var that = this;

            this.viewParams = viewParams;

            var thatContainer = (this.options.container) ? this.options.container : container;
            this.options.container = thatContainer;

            //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/' + this.template + '/';

            T.render.call(
                this,
                this.template,
                function (tmp) {
                    if (!that.options.i18n) that.options.i18n = {};

                    app.getI18NJed(
                        that,
                        that.template,
                        function (i18nJED) {
                            //storing internationalization data
                            that.options.i18n[that.template] = i18nJED;

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

                            that.bindViewScopedEvents();

                            //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")
                            //or this.$("#id")

                            var customRow = Backgrid.Row.extend({
                                initialize: function () {
                                    Backgrid.Row.prototype.initialize.apply(this, arguments);
                                    this.bindEvents();
                                },
                                render: function () {
                                    const row = this;
                                    let model = this.model;
                                    Backgrid.Row.prototype.render.apply(this, arguments);


                                    if (model.hasChanged()) {
                                        this.$el.addClass('changed-row')
                                    }
                                    else {
                                        this.$el.removeClass('changed-row')
                                    }


                                    return this;
                                },
                                actionClick: function (e) {
                                    const row = this;
                                    let model = this.model;

                                    //                                   that.$el.find('#okButton').attr('disabled', null)
                                    if (model.hasChanged())  // The button shows "go back"
                                    {
                                        model.goBack();
                                        row.render();
                                        return;
                                    }

                                    if (model.get('disposable') == 0) {  // the button shows "pick" 
                                        that.openSparePartsDialog(model, function (result) {
                                            model.pickNew(result);
                                            row.render();
                                        });
                                        return;
                                    }
                                    // the button shows "reset"
                                    model.resetCounter()
                                    row.render()
                                },
                                overrideClick: function (e) {
                                    let item = this.model
                                    const row = this


                                    that.openOverrideDialog(item, function (result) {
                                        item.override(result);
                                        row.render();
                                    })
                                    row.render();
                                },
                                events: {
                                    'click .action-button': 'actionClick',
                                    'click .campaign-counter': 'overrideClick',
                                    'change .comment-input': 'saveComment'
                                },

                                saveComment: function (e) {
                                    const comment = this.$el.find('input.comment-input').val(),
                                        model = this.model;
                                    model.setComments(comment);
                                    this.render();
                                },
                                bindEvents: function () {
                                    this.listenTo(this.model, 'change:isLoading', this.model_change_isLoading);
                                },
                                model_changed: function () {

                                },
                                model_change_isLoading: function () {
                                    try {
                                        this.render();
                                    } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                },
                            });

                            // Create grid

                            const buildGrid = () => {
                                var grid = that.grids.items = new Backgrid.Grid({
                                    header: Backgrid.Extension.GroupedHeader.extend({
                                        columnLayout:
                                            [
                                                {
                                                    name: 'typeName',
                                                },
                                                {
                                                    name: 'partName',
                                                },
                                                {
                                                    name: 'campaignCounter',
                                                },
                                                {
                                                    name: 'action'
                                                },
                                                {
                                                    name: 'equipmentId'
                                                },
                                                {
                                                    name: 'comments'
                                                },
                                            ],
                                    }),
                                    className: 'backgrid table', // Css classes for the whole grid
                                    row: customRow, // use this type of rows to render rows
                                    columns: [
                                        {
                                            name: 'typeName',
                                            label: app.translate([that, app], 'part_label'),
                                            editable: false,
                                            sortable: true,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'select-cell align-center-cell part',
                                            }),
                                        },
                                        {
                                            name: 'partName',
                                            label: app.translate([that, app], 'partName_label'),
                                            editable: false,
                                            sortable: false,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'select-cell align-center-cell part',
                                            }),
                                        },
                                        {
                                            name: 'prevCampaignCounter',
                                            label: app.translate([that, app], 'current_label'),
                                            editable: false,
                                            sortable: true,
                                            cell: Backgrid.NumberCell.extend({
                                                decimals: 0,
                                                className: 'numeric-cell align-center-cell campaign-counter',
                                                events: {
                                                    'click': 'clickAction'
                                                },
                                                clickAction: function () {
                                                }
                                            }),
                                        },
                                        {
                                            name: 'campaignCounter',
                                            label: 'Next',
                                            editable: false,
                                            sortable: true,
                                            cell: Backgrid.StringCell.extend({
                                                className: 'select-cell align-center-cell part',
                                                render: function () {
                                                    Backgrid.Cell.prototype.render.apply(this, arguments);
                                                    var value = this.model.get('campaignCounter');
                                                    var alarm = this.model.get('alarm');
                                                    var warning = this.model.get('warning');
                                                    if (value < warning)
                                                        this.$el.removeClass('warning');
                                                    else
                                                        this.$el.addClass('warning');

                                                    if (value < alarm)
                                                        this.$el.removeClass('alarm');
                                                    else
                                                        this.$el.addClass('alarm');

                                                    this.delegateEvents();
                                                    return this;
                                                }
                                            }),

                                        },
                                        {
                                            name: "options",
                                            label: "",
                                            sortable: false,
                                            editable: false,
                                            //renderable: (_.isBoolean(ctx.editable)) ? ctx.editable : false,

                                            headerCell: Backgrid.HeaderCell.extend({
                                                className: "optionstd",
                                            }),
                                            cell: Backgrid.Cell.extend({
                                                template: (function () {
                                                    // template to use for the cell
                                                    // in this case, a button
                                                    let template = `
                                                <div class="row-fluid">
                                                    <button id="actionBtn" class="action-button btn btn-block btn-default">
                                                        <span class="label-action-btn">
                                                            {{actionLabelButton}}
                                                        </span>
                                                    </button>
                                                </div>`;
                                                    return Handlebars.compile(template)
                                                })(),
                                                events: {
                                                    'click .btn-cell-action': 'cellActionClick',
                                                    'click button': 'cellActionClick',

                                                    "click .btn-dropdown-config-option": "configure_dropdown_config_opt_click",
                                                    //"click .btn-dropdown-action-option": "configure_dropdown_action_opt_click",

                                                    "show.bs.dropdown .btn-group": "btnGroup_show",
                                                    "hide.bs.dropdown .btn-group": "btnGroup_hide",
                                                },
                                                initialize: function () {
                                                    Backgrid.Cell.prototype.initialize.apply(this, arguments);
                                                    this.bindEvents();
                                                },
                                                render: function () {
                                                    Backgrid.Cell.prototype.render.apply(this, arguments);

                                                    this.$el.html(this.template({ actionLabelButton: this.model.actionLabel() }));

                                                    this.delegateEvents();
                                                    return this;
                                                },
                                                bindEvents: function () {
                                                    this.listenTo(this.model, 'change:editing change:isLoading', this.checkMode);
                                                },
                                                /////////////////////////////////////////////////////////////////////////////////////
                                                checkMode: function () {
                                                    try {
                                                        this.render();
                                                    } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                                },
                                                /////////////////////////////////////////////////////////////////////////////////////
                                            }),
                                        },
                                        {
                                            name: 'comments',
                                            label: app.translate([that, app], 'name_comment_label'),
                                            editable: false,
                                            sortable: false,
                                            cell:
                                                Backgrid.Cell.extend({
                                                    template: (function () {
                                                        // template to use for the cell
                                                        // in this case, a button
                                                        let template = `
                                                    <div class="row-fluid">
                                                        <input class="comment-input span9" style="margin:0" type="text" value="{{comment}}" />
                                                        <span class="message">
                                                        </span>
                                                    </div>
                                                    `;
                                                        return Handlebars.compile(template)
                                                    })(),
                                                    events: {
                                                        'change input.comment-input': 'saveComment'
                                                    },
                                                    saveComment: function (e) {

                                                        this.$el.find('.message').html('saved!')
                                                        this.$el.find('.message').fadeOut('slow', function () {
                                                            $(this).html('');
                                                            $(this).fadeIn();
                                                        })
                                                    },
                                                    initialize: function () {
                                                        Backgrid.Cell.prototype.initialize.apply(this, arguments);

                                                        ////creating new locked attr on column
                                                        //this.model.set("locked", false);

                                                        //this.locksChanged();

                                                        //_.bindAll(this);

                                                        this.bindEvents();
                                                    },
                                                    render: function () {
                                                        Backgrid.Cell.prototype.render.apply(this, arguments);


                                                        this.$el.html(this.template({ comment: this.model.get('comments') }));

                                                        this.delegateEvents();
                                                        return this;
                                                    },
                                                    bindEvents: function () {
                                                        this.listenTo(this.model, 'change:editing change:isLoading', this.checkMode);
                                                    },
                                                    /////////////////////////////////////////////////////////////////////////////////////
                                                    checkMode: function () {
                                                        try {
                                                            this.render();
                                                        } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                                                    },
                                                    /////////////////////////////////////////////////////////////////////////////////////
                                                }),
                                        },
                                    ],
                                    collection: that.items,
                                    body: Backgrid.Body.extend({
                                        //Override with an empty function to do the sort on the server.
                                        sort: function () { },
                                    }),
                                    header: Backgrid.Header.extend({
                                        initialize: function (options) {
                                            Backgrid.Header.prototype.initialize.apply(this, arguments);

                                            this.listenTo(this.collection, 'backgrid:sort', this.collection_backgrid_sort);
                                        },

                                        collection_backgrid_sort: function (column, direction) {
                                            var sortType = column.get('name').toUpperCase();

                                            switch ((direction + '').toUpperCase()) {
                                                case 'ASCENDING':
                                                    sortType += '-ASC';
                                                    break;
                                                case 'DESCENDING':
                                                    sortType += '-DESC';
                                                    break;
                                                case 'NULL':
                                                    sortType = null;
                                                    break;
                                            }

                                            _.each(this.row.cells, function (obj) {
                                                obj.removeCellDirection();
                                            });

                                            column.set("direction", direction);

                                            that.model.set('sortType', sortType);

                                            var params = that.model.toJSON();

                                            that._refresh(_.extend(
                                                {},
                                                params,
                                                {
                                                    refresh: true,
                                                    params: _.extend(
                                                        {},
                                                        params,
                                                        {
                                                        }
                                                    ),

                                                }
                                            ));
                                        },
                                    }),
                                });
                                return grid
                            }

                            const ladleDetailsFetch = () => {
                                that.model.set({ isLoading: true })
                                that.items.fetch({
                                    params: {
                                        currentLadle: that.model.get('currentLadle'),
                                    },
                                    reset: true
                                });
                            }

                            let renderGrid = (ladle) => {
                                let grid = buildGrid(ladle)
                                that.model.set('currentLadle', ladle)

                                ladleDetailsFetch(ladle)

                                that.$el.find('.items-grid-container').html(grid.render().el);


                                const buttons = new Screen.Views.OperationButtons({
                                    okHandler: function () {
                                        that.items.changeLadle(that.model.get('currentLadle'))
                                        enableSelect(lSelect)
                                        ladleDetailsFetch(that.model.get('currentLadle'))
                                    },
                                    cancelHandler: function () {
                                        that.items.resetLadle()
                                        enableSelect(lSelect)
                                        ladleDetailsFetch(that.model.get('currentLadle'))
                                    }
                                })

                                that.$el.find('.buttons-container').html(buttons.render().el)

                            }

                            //let lSelect = new Screen.Views.LadleSelect({
                            //    items: that.items,
                            //    current: that.model.get('currentLadle'),
                            //    ladles: that.model.get('ladles'),
                            //    handleChange: renderGrid
                            //})


                            //const enableSelect = (select) => {
                            //    select.$el.find('select').attr('disabled', null)
                            //}
                            //that.listenTo(that, 'changeladle', function (e) {
                            //    lSelect.$el.find('select').attr('disabled', e.change ? true : null)
                            //})
                            //that.$el.find('.ladle-select-container').append(lSelect.render().el);

                            //that.$el.find('select').css('color', '#606060')

                            renderGrid(that.model.get('currentLadle'))

                            // Create buttons for save and cancel

                            var fixedParams = _.extend({}, viewParams);

                            if (viewParams.ladleId) {
                                fixedParams.ladleId = (viewParams.ladleId != '-' && viewParams.ladleId != null) ? parseInt(viewParams.ladleId, 10) : null;

                                var ladles = that.model.get('ladles');
                                fixedParams.currentLadle = _.findWhere(ladles, { value: fixedParams.ladleId });

                            }
                            //Call first refresh.
                            that.model.set(fixedParams);

                            var params = that.model.toJSON();

                            that._refresh({
                                reset: true,
                                params: _.extend(
                                    {},
                                    params,
                                    {
                                    }
                                ),
                            });


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

                            //Call first refresh.
                            // that.startAutoRefresh();
                        },
                        true,
                        customPath
                    );
                },
                customPath
            );
        },
        //collection_fetch: function (coll, resp) {
        //    try {
        //        this.model.set({
        //            hasData: (this.items.length > 0),
        //            isLoading: false,
        //        });
        //    }
        //    catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        //},

        collection_fetch: function () {
            try {
                var that = this;
                setTimeout(
                    function () {
                        that.model.set({
                            hasData: (that.items.length > 0),
                            isLoading: false,
                        });
                    },
                    200
                );
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
        append: function (container, el) {
            el = (el != null && el != undefined) ? el : this.$el;

            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);

                this.options.onappend(this);
            }

            if (this.options.state == app.view_states.hidden) {
                //append and remain hidden
                container.append(el);
            }

            if (this.options.state == app.view_states.closed) {
                //return without appending.
                return;
            }
        },
        bindViewScopedEvents: function () {
            //TODO - Put this in events object.
            var that = this;

            this.listeners['beforeunload'] = _.bind(that.window_beforeUnload, that);
            $(window).on('beforeunload', this.listeners['beforeunload']);
        },
        close: function () {
            this.options.state = app.view_states.closed;

            //If currentModal exists, hide it and erase it.
            if (this.currentModal) {
                this.currentModal.hide();
                this.currentModal = null;
            }

            this.stopAutoRefresh();
            this.closeSubviews();
            this.remove();
            this.unbindViewScopedEvents();
            this.unbind();
        },
        closeSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.close();
            });
        },
        hide: function () {
            this.options.state = app.view_states.hidden;

            this.hideSubviews();
            this.stopAutoRefresh();

            this.$el.hide();
            this.unbind();
            this.stopListening();
        },
        hideSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.hide();
            });
        },
        remove: function () {
            this.removeBindings();
            this.$el.remove();
            this.stopListening();
            return this;
        },
        reRender: function () {
            this.startAutoRefresh();
        },
        show: function () {
            this.options.state = app.view_states.shown;

            this.showSubviews();
            this.bindEvents();
            this.$el.show();
        },
        showSubviews: function () {
            _.each(this.subviews, function (sview) {
                sview.show();
            });
        },
        startAutoRefresh: function () {
            try {
                if (this.autoRefresh.enabled !== true) {
                    var that = this;

                    if (this.autoRefresh.toid != null) {
                        clearTimeout(this.autoRefresh.toid);
                        this.autoRefresh.toid = null;
                    }

                    this.autoRefresh.enabled = true;

                    //use a timeout to execute the first refresh to return the handle to the start function caller.
                    //So when the caller finish it will do the first refresh.
                    this.autoRefresh.toid = setTimeout(
                        function () { that._refresh(); },
                        1
                    );
                }
            } catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
        stopAutoRefresh: function () {
            if (this.autoRefresh.toid != null) {
                clearTimeout(this.autoRefresh.toid);
                this.autoRefresh.toid = null;
            }
            this.autoRefresh.enabled = false;
        },
        unbindViewScopedEvents: function () {
            $(window).off('beforeunload', this.listeners['beforeunload']);

            this.stopAutoRefresh();
        },
        window_beforeUnload: function (e) {
            try {
                if (this.currentModal) {
                    this.currentModal.hide();
                }
            }
            catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
        },
    });

    Screen.Views.LadleSelect = Backbone.View.extend({
        template: (function () {
            let templateText = `
                <div class="row-fluid">
                       
                        <select id="ladle-select" style="max-width: 90%;height:40px;font-size:24px">
                            {{#each ladles}}
                            <option value="{{value}}">{{label}}</option>
                            {{/each}}
                        </select>
                       
                </div>
            `
            return Handlebars.compile(templateText)
        })(),
        warningModal: function (continueHandler, cancelHandler) {
            const message = `If you change the current ladle, you might lose unsaved changes...
            Would you like to continue anyway?`
            let modal = new Modal.Views.Main({
                focusOk: false,
                focusSelector: '#btn-cancel',
                title: "Warning",
                message: message,
                buttons_type: "CONTINUE-CANCEL",
            });

            modal.show()

            this.listenToOnce(modal, "continue", function (modal) {
                try {
                    continueHandler()
                }
                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            });

            this.listenToOnce(modal, "cancel", function (modal) {
                try {
                    cancelHandler()
                }
                catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
            });


        },
        events: {
            'change': function (e) {
                const selectedOption = e.target.options[e.target.value]
                var ladle = {
                    value: e.target.value,
//                    label: selectedOption.innerText
                }


                if (this.items.hasChanged()) {  // if the values have changed 
                    this.warningModal(   // ask the user what to do
                        () => { this.handleChange(ladle); },   // user said continue (lose changes)
                        () => {
                            ladle = this.current.value;   // user said cancel (keep on the same ladle)
                            this.$el.find('select').val(this.current.value);
                        }
                        )
                }
                else {
                    this.handleChange(ladle);  // values were not changed so go to the other ladle.
                }

            }
        },
        initialize: function (attrs, options) {
            this.items = attrs.items
            this.ladles = attrs.ladles
            this.handleChange = attrs.handleChange
            this.current = attrs.current
        },
        render: function () {

            this.$el.html(this.template({ ladles: this.ladles, ladle: this.current.label }))

            this.$el.find('select').val(this.current.value)

            return this
        }
    })

    Screen.Views.OperationButtons = Backbone.View.extend({
        template: (function () {
            const templateText = `
            <div class="row-fluid" style="margin: 4em 0 4em 0">
                <span class="span1"></span>
                <button id="okButton" class="span4 btn btn-lock btn-success action-button">Ok</button>
                <span class="span2"></span>
                <button id="cancelButton" class="span4 btn btn-lock action-button">Cancel</button>
            </div>`
            return Handlebars.compile(templateText)
        })(),
        initialize: function (attrs, options) {
            this.okHandler = attrs.okHandler
            this.cancelHandler = attrs.cancelHandler
        },
        events: {
            'click #okButton': 'okClick',
            'click #cancelButton': 'cancelClick'
        },
        okClick: function (e) {
            this.okHandler()
        },
        cancelClick: function (e) {
            this.cancelHandler()
        },
        render: function () {
            this.$el.html(this.template())
            return this
        }
    })

    Screen.Models.Item = Backbone.Epoxy.Model.extend({
        defaults: {


        },
        override: function (parameters) {
            
            var that = this,
                qp = new Core.Database.QueryParameters();

            qp.Add('@LadleID', 'INT', parameters.ladleId)
            qp.Add('@TypeID', 'INT', this.get('typeId') )
            qp.Add('@Value', 'INT', parameters.value)
            qp.Add('@Comments', 'VARCHAR', parameters.comment)

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.OverrideHeatCounters',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            that.trigger('overrideReady');
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            )


        },

        setComments: function (comment) {
            this.set('comments', comment);

        },
        resetLadle: function () {
            const prevComment = this.get('prevComment')
            const prevCampaignCounter = this.get('prevCampaignCounter')
            const prevEquipmentId = this.get('prevEquipmentId')

            prevComment != null ? this.set('comments', prevComment) : null
            prevCampaignCounter ? this.set('campaignCounter', prevCampaignCounter) : null
            prevEquipmentId ? this.set('equipmentId', prevEquipmentId) : null

        },

        pickNew: function (result) {

            // if they're equal, return
            if (result.part == this.get('equipmentId')) {
                return;
            }

            this.set('campaignCounter', 0);
            this.set('equipmentId', result.part);
            this.set('partName', result.partName);
        },

        resetCounter: function () {
            this.set('campaignCounter', 0);
        },

        goBack: function () {

            this.set('campaignCounter', this.get('prevCampaignCounter'));
            this.set('equipmentId', this.get('prevEquipmentId'));
            this.set('comments', this.get('prevComments'));
        },
        actionLabel: function () {

            if (this.hasChanged()) {
                return 'GO BACK'
            }
            else {
                if (this.get('disposable') == 0) {
                    return 'PICK NEW'
                }
                else {
                    return 'RESET'
                }
            }
        },
        hasChanged: function () {
            return (
                this.get('campaignCounter') != this.get('prevCampaignCounter') ||
                this.get('equipmentId') != this.get('prevEquipmentId') ||
                this.get('comments') != this.get('prevComments')
                )
        },
        parse: function (obj) {
            let item = {

                prevPartName: obj.EquipmentName,
                partName: obj.EquipmentName,

                prevEquipmentId: obj.EquipmentId,
                equipmentId: obj.EquipmentId,

                prevCampaignCounter: obj.CampaignCounter,
                campaignCounter: obj.CampaignCounter,

                prevComments: obj.Comments,
                comments: obj.Comments,

                typeId: obj.TypeId,
                typeName: obj.TypeName,
                alarm: obj.Alarm,
                warning: obj.Warning,
                disposable: obj.Disposable,
                resetHandler: obj.Disposable ? this.f1 : this.f2,

            };

            return item
        },
    });

    Screen.Collections.Items = Backbone.Collection.extend({
        model: Screen.Models.Item,
        fetch: function (opt) {

            var that = this,
                qp = new Core.Database.QueryParameters(),
                options = opt ? _.clone(opt) : {};

            let qParams = options.params

            if (!qParams.currentLadle) {
                qParams.currentLadle = { value: 1, label: 'Ladle 1' }
            }

            const ladle = qParams.currentLadle
            qp.Add('@LadleID', 'INT', ladle.value)
            
            
            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.GetCurrentEquipment',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if ((resp) && (resp.Table)) {

                                var records = resp.Table,
                                    newColl;

                                newColl = _.map(records, that.model.prototype.parse);

                                var method = ((options.refresh) || ((options.reset))) ? 'set' : 'add';

                                var editingItems = _.where(that.toJSON(), { isNew: true });
                                [].push.apply(newColl, editingItems);

                                that[method](newColl, { from: 'fetch' })
                                    .trigger('fetch', that, records);

                                that.isFetching = false;
                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: true,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;
        },
        resetLadle: function (ladle) {
            this.models.map(function (model) {
                model.resetLadle()
            })
        },
        hasChanged: function () {
            // It should return true if AT LEAST
            // one element has changed

            return this.models.some((model) => model.hasChanged())
        },
        drainLadle: function (opt) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                ttimestamp = this.transaction_timestamp = new Date().getTime(),
                options = opt ? _.clone(opt) : {};

            qp.Add('@LadleID', 'INT', opt.ladle.get('currentLadle').value)

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.DrainLadle',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            //checking transaction timestamp
                            if (ttimestamp != that.transaction_timestamp)
                                return;

                            if ((resp) && (resp.Table)) {

                            }
                            else {
                                if ((resp) && (resp.Message))
                                    console.error(resp.Message);
                                else
                                    console.error('Server response not valid.');
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: false,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );

            return this;

        },
        changeLadle: function (ladle) {
            const buildParms = function (models) {
                const getItem = function (name) {
                    filtered = models.filter((el) => { return el.get('typeName') == name })
                    return filtered.length == 1 ? filtered[0] : null
                }

                let queryParams = []

                queryParams.push({
                    Name: '@LadleID', Type: 'INT', Value: parseInt(ladle.value)
                })


                const intAttrs = [
                    {
                        modelAttr: 'Ladle Shell',
                        queryAttr: '@LadleShellId',
                        commentAttr: '@LadleShellComment'

                    },
                    {
                        modelAttr: 'Mounting Plate',
                        queryAttr: '@MountingPlateId',
                        commentAttr: '@MountingPlateComment'
                    },
                    {
                        modelAttr: 'Ladle Slide Gate',
                        queryAttr: '@LadleSlideGateId',
                        commentAttr: '@LadleSlideGateComment'
                    },
                ]

                const bitAttrs = [
                    {
                        modelAttr: 'Safety Lining',
                        queryAttr: '@SafetyLiningChange',
                        commentAttr: '@SafetyLiningComment'
                    },
                    {
                        modelAttr: 'Working Lining',
                        queryAttr: '@WorkingLiningChange',
                        commentAttr: '@WorkingLiningComment'
                    },
                    {
                        modelAttr: 'Upper Nozzle',
                        queryAttr: '@UpperNozzleChange',
                        commentAttr: '@UpperNozzleComment'
                    },
                    {
                        modelAttr: 'Plate Assembly',
                        queryAttr: '@PlateAssemblyChange',
                        commentAttr: '@PlateAssemblyComment'
                    },
                    {
                        modelAttr: 'Porous Plug North',
                        queryAttr: '@PorousPlugNorthChange',
                        commentAttr: '@PorousPlugNorthComment',
                    },
                    {
                        modelAttr: 'Porous Plug South',
                        queryAttr: '@PorousPlugSouthChange',
                        commentAttr: '@PorousPlugSouthComment',
                    },
                ]

                intAttrs.map((attr) => {
                    const item = getItem(attr.modelAttr)

                    if (item.hasChanged()) {
                        let params = [
                            { Name: attr.queryAttr, Type: 'INT', Value: item.get('equipmentId'), },
                        ]

                        params.map((param) => {
                            queryParams.push(param)
                        })
                    }

                })

                bitAttrs.map((attr) => {
                    const item = getItem(attr.modelAttr)

                    if (item.hasChanged()) {
                        let params = [
                            { Name: attr.queryAttr, Type: 'BIT', Value: item.get('prevCampaignCounter') == null ? 0 : 1, },
                        ]

                        params.map((param) => {
                            queryParams.push(param)
                        })
                    }
                })

                intAttrs.map((attr) => {
                    const item = getItem(attr.modelAttr)
                    if (item.hasChanged()) {
                        let params = [
                { Name: attr.commentAttr, Type: 'VARCHAR', Value: item.get('comments'), },
                        ]

                        params.map((param) => {
                            queryParams.push(param)
                        })
                    }
                })

                bitAttrs.map((attr) => {
                    const item = getItem(attr.modelAttr)
                    if (item.hasChanged()) {
                        let params = [
                            { Name: attr.commentAttr, Type: 'VARCHAR', Value: item.get('comments'), },
                        ]

                        params.map((param) => {
                            queryParams.push(param)
                        })
                    }
                })
               
                return queryParams
            }

            const queryParams = buildParms(this.models)

            this.save({
                params: queryParams
            })

        },
        save: function (options) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                opt = _.extend({
                    async: true,
                }, options);

            _.each(opt.params, function (qpParams) {
                qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
            });

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.ChangeLadleEquipment',
                qp,
                {
                    onSuccess: function (resp) {
                        try {

                            if ((resp) && (resp.Message))
                                console.error(resp.Message);
                            
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onFailure: function (resp) {
                        console.error(resp);
                    },
                    Secured: true,
                    Async: false,
                },
                app.ConnectionStrings.app
            )
        },

    });

    Screen.Models.SparePartsModal = Backbone.Epoxy.Model.extend({
        defaults: {
            message: null,

            ladle: null,
            part: null,
            partName: null,
            curPartId: null,
            newPartId: null,

            parts: [],

            errorMsg: "",
            processing: false,
        },
        computeds: {
            hasParts: {
                deps: ['parts'],
                get: function (parts) {
                    return parts.length != 0;
                },
            },
        },
        fetchParts: function (options) {
            var that = this,
                qp = new Core.Database.QueryParameters(),
                opt = _.extend({
                    async: false,
                }, options);

            qp.Add('@EquipmentTypeId', 'INT', this.get('part'))

            Core.Json.CallProcedure(
                app.DatabaseNames.MES + '.LAD.GetEquipmentsPerType',
                qp,
                {
                    onSuccess: function (resp) {
                        try {
                            if ((resp) && (resp.Table) && (resp.Table.length > 0)) {
                                that.set('parts', resp.Table)

                            }
                            else {
                                var errorMsg = ((resp) && (resp.Message))
                                    ? resp.Message
                                    : 'SERVER_RESPONSE_NOT_valid';
                                console.error(errorMsg);

                                if (opt.error)
                                    opt.error(that, errorMsg);
                            }
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    onError: function (errorMsg) {
                        try {
                            if (opt.error)
                                opt.error(that, errorMsg);
                        }
                        catch (error) { console.error((error.stack) ? error.stack : new Error(error).stack); }
                    },
                    Async: opt.async,
                    Secured: true,
                },
                app.ConnectionStrings.app
            );
        },
    })

    Screen.Views.SparePartsModal = Modal.Views.SimpleModal.extend({
        className: Modal.Views.SimpleModal.prototype.className + ' spart-parts-modal',

        i18n: null,

        initialize: function (options) {
            _.extend(this, options);

            if (!this.model)
                this.model = new Screen.Models.SparePartsModal();

            this.model.fetchParts();

            this.bindEvents();

            return this;
        },
        events: {
            'click #spareParts button': 'buttonClick'
        },
        buttonClick: function (e) {
            const che = parseInt(e.target.value)
            const pn = e.target.innerText;

            this.trigger('savepart', { part: che, partName: pn })

            this.hide()
        },
        bindEvents: function () {
            Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
        },
        sparePartsTemplate: (function () {
            const template = `
            <div class="row-fluid container">
                <div id="spareParts" class="btn-group-vertical btn-block" style="width: 100%;">
                    {{#each parts}}
                        <button type="button" class ="btn btn-block btn-{{class}}" style="width:80%; padding: 1em 0 1em 0"  value={{EquipmentId}} >
                            {{Name}}
                        </button>
                    {{/each}}
                </div>
            </div>
                `

            return Handlebars.compile(template)
        })(),
        render: function () {
            Modal.Views.SimpleModal.prototype.render.apply(this, arguments);

            const parts = this.model.get('parts')
            
            this.$el.find('.parts-container').html(this.sparePartsTemplate({ parts: parts }))

            return this
        },

        show: function () {
            if (!this.isRendered) {
                this.render();
            }
            else {
                this.$el.modal({
                    keyboard: false,
                    backdrop: 'static',
                });
            }

            return this;
        },
        hide: function () {
            //if (this.innerModal)
            //    this.innerModal.hide();

            var result = Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
            return result;
        },

        acceptBtn_click: function (e) {
            try {
                // this.save();
            }
            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
        },
    })

    Screen.Views.DrainButton = Backbone.View.extend({
        initialize: function (options) {

        },
        template: (function () {
            const template = `
                <div class="row-fluid">
                    <button class="btn btn-primary" style="width: 9em;height: 4em;" id="drainButton">Drain</button>
                </div>
            `
            return Handlebars.compile(template)
        })(),
        events: {
            'click button': 'buttonClick'
        },
        render: function () {
            this.$el.html(this.template())

            return this
        },
        buttonClick: function(e)
        {
            alert('not implemented');
        }
    })

    Screen.Models.OverrideHeatCounterModal = Backbone.Epoxy.Model.extend({
        defaults: {
        },
    })

    Screen.Views.OverrideHeatCounterModal = Modal.Views.SimpleModal.extend({
        className: Modal.Views.SimpleModal.prototype.className + ' override-heat-counter-modal',

        i18n: null,

        initialize: function (options) {
            _.extend(this, options);

            if (!this.model)
                this.model = new Screen.Models.OverrideHeatCounterModal();

            this.bindEvents();

            return this;
        },
        events: {
            'click #overrideOkBtn': 'okClick',
            'click #overrideCancelBtn': 'cancelClick'
        },
        okClick: function (e) {

            // Get comment and set it on model
            const comment = this.$el.find('#commentTxt').val()
          
            // Get new value
            const value = parseInt(this.$el.find('#nextValueInput').val())
            

            // Raise event to catch in grid and save all    
            this.trigger('saveoverride', { comment:comment, value:value , ladleId:this.model.get('ladleId') })

            // Hide modal
            this.hide()



        },
        cancelClick: function(e)
        {
            // Hide modal
            this.hide()

        },
        bindEvents: function () {
            Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
        },
       
       innerTemplate: (function () {
            const text = `
            {{part}}
            `
            return Handlebars.compile(text)

        })(), 
        render: function () {
            Modal.Views.SimpleModal.prototype.render.apply(this, arguments);

            this.$el.find('.override-container').append(this.innerTemplate({ part: 'hol' }))

            return this
        },
        show: function () {
            if (!this.isRendered) {
                this.render();
            }
            else {
                this.$el.modal({
                    keyboard: false,
                    backdrop: 'static',
                });
            }

            return this;
        },
        hide: function () {
            //if (this.innerModal)
            //    this.innerModal.hide();

            var result = Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
            return result;
        },

       
    })



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

});
