//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',
    'chart',
    'moment',
    'chartjs-date-fns-adapter',
    'chartjs-plugin-annotation',
    'js/d3v4/d3.v4',
    'backgrid/moment-cell',
    'backgrid/grouped-columns',

    "js/jquery.floatThead/jquery.floatThead",
],
    function (app, T, Modal, Backgrid, ChartJS, moment, ChartJsDateFnsAdapter, ChartJSAnnotation, d3) {

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

        Screen.Models.Main = Backbone.Epoxy.Model.extend({
            defaults: {
                start: new moment().add(-7, 'days').format('YYYY-MM-DD'),
                end: new moment().add(8, 'days').format('YYYY-MM-DD'),
                areaName: 'AEP',
                hasData: false,
                isLoading: false,

                pjmWatch: null,
                pjmWarn: null,
                aepWatch: null,
                aepWarn: null,
            },
            computeds: {
                start$: {
                    deps: ['start'],
                    get: function (value) {
                        return value;
                    },
                    set: function (value) {
                        return { start: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                    },
                },
                end$: {
                    deps: ['end'],
                    get: function (value) {
                        return value;
                    },
                    set: function (value) {
                        return { end: (value) ? new moment(value, app.translate(app, 'MM/DD/YYYY')).format('YYYY-MM-DD') : value, };
                    },
                },
            },
        });


        Screen.Views.Main = Backbone.Epoxy.View.extend({
            template: 'power-consumed-forecast',
            id: 'power-consumed-forecast',
            title: 'Consumed Power Forecast',
            events: function () {
                return {
                    'click #refreshBtn': this.refreshBtn_click,
                    'click #settingsBtn': this.configBtn_click,
                    'click #btnSaveForecast': this.btnSave_click,
                    'click #btnSaveHourly': this.btnSave_click,
                };
            },
            bindings: 'data-bind',
            bindingSources: null,
            grids: null,
            itemsColl: null,
            subviews: null,
            templates: null,
            currentModal: null,
            viewParams: null,
            pjmChart: null,
            aepChart: null,
            sdiChart: null,
            priceChart: null,

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

                var that = this;

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

                this.grids = {};

                this.itemsColl = new Screen.Collections.Items();

                this.bindingSources = {};

                this.subviews = {};
                this.autoRefresh = {
                    enabled: null
                    , toid: null
                    , every: 5 * 1000
                };
                this.templates = {
                    settingsModal: null,
                };

                this.bindEvents();
            },
            bindEvents: function () {
                this.listenTo(this.itemsColl, 'fetch', this.processes_ready);

            },
            _refresh: function (opt) {
                this.itemsColl.reset();

                this.model.set({
                    hasData: false,
                    isLoading: true,
                });

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

                this.refreshProcesses(opt);

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

                    this.autoRefresh.toid = setTimeout(
                        function () { that._refresh(); },
                        this.autoRefresh.every
                    );
                }
            },
            refresh: function () {
                if (this.currentModal) {
                    this.currentModal.hide();
                    this.currentModal = null;
                }
                var params = this.model.toJSON();
                this._refresh({
                    reset: true,
                    params: _.extend(
                        {},
                        params,
                        {}
                    ),
                });
            },
            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();

                                //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')

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



                                //Set model with view params here to prevent changes on the model when the view bindings are applied.
                                var fixedParams = _.extend({}, viewParams);
                                if (fixedParams.start)
                                    fixedParams.start = new moment(fixedParams.start, 'YYYYMMDD').format('YYYY-MM-DD');
                                if (fixedParams.end)
                                    fixedParams.end = new moment(fixedParams.end, 'YYYYMMDD').format('YYYY-MM-DD');

                                that.model.set(fixedParams);

                                that.templates.settingsModal = Handlebars.compile(that.$el.find('#power_load_monitoring_settings_modal_template').html());

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

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


                            },
                            true,
                            customPath
                        );
                    },
                    customPath
                );
            },
            buildChart: function (all) {

                if (this.pjmChart)
                    this.pjmChart.destroy();
                if (this.aepChart)
                    this.aepChart.destroy();
                if (this.sdiChart)
                    this.sdiChart.destroy();
                if (this.priceChart)
                    this.priceChart.destroy();

                var ctxPJM = document.getElementById("myChartPJM").getContext("2d");
                var ctxAEP = document.getElementById("myChartAEP").getContext("2d");
                var ctxSDI = document.getElementById("myChartSDI").getContext("2d");
                var ctxPrice = document.getElementById("myChartPrice").getContext("2d");

                document.getElementById("myChartPJM").addEventListener('mousemove', e => {
                    const chart = Chart.getChart('myChartPJM');
                    this.updateGraphicToolTip(chart, e, e.target);
                });
                document.getElementById("myChartAEP").addEventListener('mousemove', e => {
                    const chart = Chart.getChart('myChartAEP');
                    this.updateGraphicToolTip(chart, e, e.target);
                });
                document.getElementById("myChartSDI").addEventListener('mousemove', e => {
                    const chart = Chart.getChart('myChartSDI');
                    this.updateGraphicToolTip(chart, e, e.target);
                });
                // document.getElementById("myChartPrice").addEventListener('mousemove', e => { 
                //     const chart = Chart.getChart('myChartPrice');
                //     this.updateGraphicToolTip(chart, e, e.target);
                // });


                const colors = {
                    green: { fill: '#e0eadf', stroke: '#5eb84d', },
                    lightBlue: { stroke: '#6fccdd', fill: '#9dd2ea', },
                    darkBlue: { fill: '#92bed2', stroke: '#3282bf', },
                    purple: { fill: '#8fa8c8', stroke: '#75539e', },
                    red: { stroke: '#c4274c', fill: '#de7d7d', },
                    gray: { stroke: '#999', fill: '#ccc', },
                    black: { stroke: '#000', fill: '#000', },
                    yellow: { stroke: '#f3d32b', fill: '#FFEE7E', },
                };



                // variables for the charts
                const today = new Date();
                const pjmDataSet = all.Table;
                const aepDataSet = all.Table1;
                const sdiDataSet = all.Table2;
                const priceDataSet = all.Table3;
                const eventDataSet = all.Table4;


                const todayAnnotation = {
                    type: 'line',
                    scaleID: 'x',
                    value: today,
                    borderColor: '#000',
                    borderWidth: 2,
                };
                const watchAnnotation = {
                    type: 'line',
                    scaleID: 'y',
                    borderColor: colors.yellow.stroke,
                    borderDash: [6, 6],
                    borderDashOffset: 0,
                    borderWidth: 2,
                    label: {
                        display: true,
                        position: 'start',
                        backgroundColor: colors.yellow.fill,
                        borderColor: colors.yellow.stroke,
                        borderRadius: 5,
                        borderWidth: 1,
                        color: colors.black.stroke,
                        font: {
                            size: 10
                        },
                        content: (ctx) => 'Watch',
                        rotation: 'auto'
                    },
                };
                const warnAnnotation = {
                    type: 'line',
                    scaleID: 'y',
                    borderColor: colors.red.stroke,
                    borderDash: [6, 6],
                    borderDashOffset: 0,
                    borderWidth: 2,
                    label: {
                        display: true,
                        position: 'end',
                        backgroundColor: colors.red.fill,
                        borderColor: colors.red.stroke,
                        borderRadius: 5,
                        borderWidth: 1,
                        font: {
                            size: 10
                        },
                        content: (ctx) => 'Warn',
                        rotation: 'auto'
                    },
                };
                var gXScales = {
                    type: 'time',
                    min: new moment(this.model.get('start')).format('YYYY-MM-DD'),
                    max: new moment(this.model.get('end')).format('YYYY-MM-DD'),
                    title: { display: false, text: 'Date' },
                    ticks: {
                        autoSkip: false,
                        maxRotation: 0,
                        major: { enabled: true },
                        font: function (context) {
                            if (context.tick && context.tick.major) {
                                return {
                                    weight: 'bold',
                                };
                            }
                        }
                    }
                };
                // Event Values
                let pjmWarn = 0, pjmWatch = 0, aepWarn = 0, aepWatch = 0;
                _.each(eventDataSet, function (obj) {
                    if (obj.Code === 'PJM') {
                        pjmWatch = obj.Watch;
                        pjmWarn = obj.Warn;
                    } else if (obj.Code === 'AEP') {
                        aepWatch = obj.Watch;
                        aepWarn = obj.Warn;
                    }
                });
                //PJM Setup
                const pjmMw = [];
                const pjmDates = [];
                const pjmLabels = [];
                _.each(pjmDataSet, function (obj) {
                    pjmDates.push({
                        'date': new moment(obj.StartDateTime).toDate(),
                        'value': obj.StartDateTime
                    });
                    pjmLabels.push(new moment(obj.StartDateTime).toDate());
                });
                let pjmTime = {};
                for (let i = 0; i < pjmDates.length; i++) {
                    pjmTime = _.where(pjmDataSet, { StartDateTime: pjmDates[i].value });
                    if (pjmTime && pjmTime[0] && pjmTime[0].Mw) pjmMw.push(Math.round(pjmTime[0].Mw / 1000, 2));
                    else pjmMw.push(null);
                }
                const pjmData = {
                    labels: pjmLabels,
                    datasets: [
                        {
                            label: "PJM Power",
                            fill: false,
                            backgroundColor: colors.green.fill,
                            pointBackgroundColor: colors.green.stroke,
                            borderColor: colors.green.stroke,
                            pointHighlightStroke: colors.green.stroke,
                            borderWidth: 1,
                            pointStyle: 'circle',
                            pointRadius: 2,
                            data: pjmMw,
                        }
                    ]
                };
                this.pjmChart = new Chart(ctxPJM, {
                    type: 'line',
                    data: pjmData,
                    options: {
                        spanGaps: 1000 * 60 * 60, // 1 hour
                        responsive: true,
                        plugins: {
                            title: {
                                display: true,
                                padding: {
                                    top: -10,
                                    bottom: 0
                                }
                            },
                            tooltip: { mode: 'index' },
                            annotation: {
                                annotations: {
                                    lineToday: todayAnnotation,
                                    lineWatch: { ...watchAnnotation, value: pjmWatch, label: { ...watchAnnotation.label, content: 'Watch: ' + pjmWatch.toFixed(0) } },
                                    lineWarn: { ...warnAnnotation, value: pjmWarn, label: { ...warnAnnotation.label, content: 'Warn: ' + pjmWarn.toFixed(0) } },
                                }
                            }
                        },
                        interaction: { mode: 'nearest', axis: 'x', intersect: false },
                        scales: {
                            x: gXScales,
                            y: { stacked: false, title: { display: true, text: 'GW' }, min: 50 }
                        },
                        animation: { duration: 750, },
                    }
                });


                //AEP Setup
                const aepMw = [];
                const aepDates = [];
                const aepLabels = [];
                _.each(aepDataSet, function (obj) {
                    aepDates.push({
                        'date': new moment(obj.StartDateTime).toDate(),
                        'value': obj.StartDateTime
                    });
                    aepLabels.push(new moment(obj.StartDateTime).toDate());
                });
                let aepTime = {};
                for (let i = 0; i < aepDates.length; i++) {
                    aepTime = _.where(aepDataSet, { StartDateTime: aepDates[i].value });
                    if (aepTime && aepTime[0] && aepTime[0].Mw) aepMw.push(aepTime[0].Mw / 1000.0);  //Math.round(aepTime[0].Mw / 1000, 2)
                    else aepMw.push(null);
                }
                const aepData = {
                    labels: aepLabels,
                    datasets: [
                        {
                            label: "AEP Power",
                            fill: false,
                            backgroundColor: colors.lightBlue.fill,
                            pointBackgroundColor: colors.lightBlue.stroke,
                            borderColor: colors.lightBlue.stroke,
                            pointHighlightStroke: colors.lightBlue.stroke,
                            borderWidth: 1,
                            pointStyle: 'circle',
                            pointRadius: 2,
                            data: aepMw,
                        }
                    ]
                };
                this.aepChart = new Chart(ctxAEP, {
                    type: 'line',
                    data: aepData,
                    options: {
                        spanGaps: 1000 * 60 * 60, // 1 hour
                        responsive: true,
                        plugins: {
                            title: {
                                display: true,
                                padding: {
                                    top: -10,
                                    bottom: 0
                                }
                            },
                            tooltip: { mode: 'index' },
                            annotation: {
                                annotations: {
                                    lineToday: todayAnnotation,
                                    lineWatch: { ...watchAnnotation, value: aepWatch, label: { ...watchAnnotation.label, content: 'Watch: ' + aepWatch.toFixed(0) }, },
                                    lineWarn: { ...warnAnnotation, value: aepWarn, label: { ...warnAnnotation.label, content: 'Warn: ' + aepWarn.toFixed(0) } },
                                }
                            }
                        },
                        interaction: { mode: 'nearest', axis: 'x', intersect: false },
                        scales: {
                            x: gXScales,
                            y: { stacked: false, title: { display: true, text: 'GW' }, min: 10, max: 25 }
                        },
                        animation: { duration: 750, },
                    }
                });

                //SDI Setup
                const sdiMw = [];
                const sdiDates = [];
                const sdiLabels = [];
                _.each(sdiDataSet, function (obj) {
                    sdiDates.push({
                        'date': new moment(obj.StartDateTime).toDate(),
                        'value': obj.StartDateTime
                    });
                    sdiLabels.push(new moment(obj.StartDateTime).toDate());
                });
                let sdiTime = {};
                for (let i = 0; i < sdiDates.length; i++) {
                    sdiTime = _.where(sdiDataSet, { StartDateTime: sdiDates[i].value });
                    if (sdiTime && sdiTime[0] && sdiTime[0].Mw) sdiMw.push(Math.round(sdiTime[0].Mw / 1, 2));
                    else sdiMw.push(null);
                }
                const sdiData = {
                    labels: sdiLabels,
                    datasets: [
                        {
                            label: "SDI Consumption",
                            fill: false,
                            backgroundColor: colors.purple.fill,
                            pointBackgroundColor: colors.purple.stroke,
                            borderColor: colors.purple.stroke,
                            pointHighlightStroke: colors.purple.stroke,
                            borderWidth: 1,
                            pointStyle: 'circle',
                            pointRadius: 2,
                            data: sdiMw,
                        }
                    ]
                };
                this.sdiChart = new Chart(ctxSDI, {
                    type: 'line',
                    data: sdiData,
                    options: {
                        spanGaps: 1000 * 60 * 60, // 1 hour
                        responsive: true,
                        plugins: {
                            title: {
                                display: true,
                                padding: {
                                    top: -10,
                                    bottom: 0
                                }
                            },
                            tooltip: { mode: 'index' },
                            annotation: {
                                annotations: {
                                    lineToday: todayAnnotation,
                                }
                            }
                        },
                        interaction: { mode: 'nearest', axis: 'x', intersect: false },
                        scales: {
                            x: gXScales,
                            y: { stacked: false, title: { display: true, text: 'MW' }, min: 10, max: 250 }
                        },
                        animation: { duration: 750, },
                    }
                });
                //Price Setup
                const priceMw = [];
                const priceDates = [];
                const priceLabels = [];
                _.each(priceDataSet, function (obj) {
                    priceDates.push({
                        'date': new moment(obj.StartDateTime).toDate(),
                        'value': obj.StartDateTime
                    });
                    priceLabels.push(new moment(obj.StartDateTime).toDate());
                });
                let priceTime = {};
                for (let i = 0; i < priceDates.length; i++) {
                    priceTime = _.where(priceDataSet, { StartDateTime: priceDates[i].value });
                    if (priceTime && priceTime[0] && priceTime[0].Price) priceMw.push(Math.round(priceTime[0].Price / 1, 2));
                    else priceMw.push(null);
                }
                const priceData = {
                    labels: priceLabels,
                    datasets: [
                        {
                            label: "SDI Price (MWh)",
                            fill: false,
                            backgroundColor: colors.gray.fill,
                            pointBackgroundColor: colors.gray.stroke,
                            borderColor: colors.gray.stroke,
                            pointHighlightStroke: colors.gray.stroke,
                            borderWidth: 1,
                            pointStyle: 'circle',
                            pointRadius: 2,
                            data: priceMw,
                        }
                    ]
                };

                var minMaxResult = priceData.datasets[0].data.reduce(function (acc, current) {
                    return {
                        min: Math.min(acc.min, current),
                        max: Math.max(acc.max, current),
                    };
                }, { min: Infinity, max: -Infinity });

                this.priceChart = new Chart(ctxPrice, {
                    type: 'line',
                    data: priceData,
                    options: {
                        spanGaps: 1000 * 60 * 60, // 1 hour
                        responsive: true,
                        plugins: {
                            title: {
                                display: true,
                                padding: {
                                    top: -10,
                                    bottom: 0
                                }
                            },
                            tooltip: { mode: 'index' },
                            annotation: {
                                annotations: {
                                    lineToday: todayAnnotation,
                                }
                            }
                        },
                        interaction: { mode: 'nearest', axis: 'x', intersect: false },
                        scales: {
                            x: gXScales,
                            y: { stacked: false, title: { display: true, text: '$' }, min: minMaxResult.min <= 5 ? 0 : minMaxResult.min , max: minMaxResult.max + 5 }
                        },
                        animation: { duration: 750, },
                    }
                });
            },
            updateGraphicToolTip: function (chart, event, canvas) {
                const mouseX = event.clientX - canvas.getBoundingClientRect().left;
                const xAxis = chart.scales.x;
                const xValue = xAxis.getValueForPixel(mouseX);



                var annotationCursor =
                {
                    lineCursor: {
                        type: 'line',
                        mode: 'vertical',
                        scaleID: 'x',
                        value: xValue,
                        borderColor: '#999',
                        borderWidth: 2,
                        borderDash: [2, 2]
                    }
                };
                this.pjmChart.config.options.plugins.annotation.annotations = { ...this.pjmChart.config.options.plugins.annotation.annotations, ...annotationCursor };
                this.aepChart.config.options.plugins.annotation.annotations = { ...this.aepChart.config.options.plugins.annotation.annotations, ...annotationCursor };
                this.sdiChart.config.options.plugins.annotation.annotations = { ...this.sdiChart.config.options.plugins.annotation.annotations, ...annotationCursor };
                this.pjmChart.update();
                this.aepChart.update();
                this.sdiChart.update();
            },
            processes_ready: function (all) {
                try {
                    var that = this;
                    setTimeout(
                        function () {
                            if (all.Table4 && all.Table4.length > 0) {
                                var settingsDataSet = all.Table4;
                                _.each(settingsDataSet, function (obj) {
                                    if (obj.Code === 'PJM') {
                                        that.model.set('pjmWatch', obj.Watch);
                                        that.model.set('pjmWarn', obj.Warn);
                                    } else if (obj.Code === 'AEP') {
                                        that.model.set('aepWatch', obj.Watch);
                                        that.model.set('aepWarn', obj.Warn);
                                    }
                                });
                            }
                            that.model.set({
                                hasData: (that.itemsColl.length > 0),
                                isLoading: false,
                            });
                            that.buildChart(all);
                        },
                        100
                    );
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
            refreshProcesses: function (options) {
                var that = this,
                    attrs = this.model.toJSON(),
                    opt = _.extend({}, options, { params: {}, });

                if ((opt.refresh == true) || (opt.reset == true))
                    this.model.set('isLoading', true);


                this.itemsColl.fetch({
                    start: attrs.start,
                    end: attrs.end,
                    areaName: attrs.areaName,
                    refresh: true,
                });
            },
            openSettings: function () {
                var that = this, attrs = that.model.toJSON();
                this.currentModal = new Screen.Views.SettingsModal({
                    model: new Screen.Models.SettingsModal({
                        pjmWarn: attrs.pjmWarn,
                        pjmWatch: attrs.pjmWatch,
                        aepWarn: attrs.aepWarn,
                        aepWatch: attrs.aepWatch,
                    }),
                    template: this.templates.settingsModal,
                    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, });
                                this.refresh();
                            }
                        }
                        catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                    });;

                this.currentModal.show();
            },
            configBtn_click: function (e) {
                this.openSettings();
            },
            refreshBtn_click: function (e) {
                try {
                    var params = this.model.toJSON();


                    if (this.$el.find('#stacked_chart'))
                        this.$el.find('#stacked_chart').html('');
                    app.router.navigate(
                        app.router.resolveURL(
                            app.router.currentModule,
                            _.extend(
                                {},
                                params,
                                {
                                    start: new moment(params.start, 'YYYY-MM-DD').format('YYYYMMDD'),
                                    end: new moment(params.end, 'YYYY-MM-DD').format('YYYYMMDD'),
                                }
                            ),
                            false
                        ),
                        { trigger: false, }
                    );

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

                    window.scrollTo(0, 0);
                }
                catch (Error) { console.error(Error.stack); }
            },
            //Common functions
            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 () {
                var that = this;
            },
            unbindViewScopedEvents: function () {

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

                this.closeSubviews();
                this.remove();
                this.unbindViewScopedEvents();
                this.unbind();
            },
            closeSubviews: function () {
                _.each(this.subviews, function (sview) {
                    sview.close();
                });
            },
            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();
                });
            },
            hide: function () {
                this.options.state = app.view_states.hidden;

                this.hideSubviews();

                this.$el.hide();
                this.unbind();
                this.stopListening();
            },
            hideSubviews: function () {
                _.each(this.subviews, function (sview) {
                    sview.hide();
                });
            },
            preRender: function () {
                app.models.subnavbar.set("subnavbar", false);
            },
            reRender: function (viewParams) {
                try {
                    this.refresh(viewParams);
                } catch (Error) { }
            },
        });

        Screen.Collections.Items = Backbone.Collection.extend({
            isFetching: false,
            fixedParameters: [],
            fetch: function (params) {
                var that = this,
                    qp = new Core.Database.QueryParameters(),
                    options = params ? _.clone(params) : {};
                if (options.refresh) {
                    this.fixedParameters = [
                        { Name: '@StartDate', Type: 'DATE', Value: params.start, },
                        { Name: '@EndDate', Type: 'DATE', Value: params.end, },
                        { Name: '@TimeZoneCode', Type: 'CHAR', Value: app.models.user.get('timezoneCode'), },
                    ];
                }
                this.isFetching = true;
                _.each(this.fixedParameters, function (qpParams) {
                    qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                });

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

                                if ((resp) && (resp.Table1)) {
                                    //var newColl = _.map(resp.Table, that.model.prototype.parse);
                                    newColl = resp.Table1;
                                    var method = (options.refresh) ? 'set' : 'add';

                                    that[method](newColl);
                                    that.trigger('fetch', resp);



                                    that.isFetching = false;


                                }
                                else {
                                    if ((resp) && (resp.Message)) {
                                        console.error(new Error(resp.Message).stack);
                                        app.views.topMessages.showMessage('CALL TO DATABASE FAILED', { stay: 5000, });
                                    }
                                    else {
                                        app.views.topMessages.showMessage('SERVER RESPONSE NOT VALID', { stay: 5000, });
                                        console.error(new Error('SERVER_RESPONSE_NOT_VALID').stack);
                                    }
                                }
                            }
                            catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                        },
                        onFailure: function (resp) {
                            console.error(resp);
                        },
                        Secured: true,
                        Async: true,
                    },
                    app.ConnectionStrings.app
                );
                return this;
            }
        });
        Screen.Models.SettingsModal = Backbone.Epoxy.Model.extend({
            defaults: {
                processing: false,
                aepWarn: null,
                aepWatch: null,
                pjmWarn: null,
                pjmWatch: null,
            },
            computeds: {

            },
            save: function (options) {
                var that = this;
                var qp = new Core.Database.QueryParameters();
                var opt = _.extend({ async: true, }, options);
                _.each(opt.params, function (qpParams) {
                    qp.Add(qpParams.Name, qpParams.Type, qpParams.Value);
                });
                Core.Json.CallProcedure(
                    app.DatabaseNames.MES + '.PWR.UpsertEventConfig',
                    qp,
                    {
                        onSuccess: function (resp) {
                            try {

                                if ((resp) && (resp.Table) && (resp.Table.length > 0) && (resp.Table[0]) && (resp.Table[0].ID)) {
                                    if (opt.success)
                                        opt.success(that, resp.Table[0]);
                                }
                                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.SettingsModal = Modal.Views.SimpleModal.extend({
            className: Modal.Views.SimpleModal.prototype.className + ' settings-modal',
            i18n: null,
            initialize: function (options) {
                _.extend(this, options);
                if (!this.model)
                    this.model = new Screen.Models.ChangePositionModal();
                this.bindEvents();
                return this;
            },
            events: function () {
                return {
                    'click #settingsSaveBtn': this.saveBtn_click,
                };
            },
            bindEvents: function () {
                Modal.Views.SimpleModal.prototype.bindEvents.apply(this, arguments);
            },
            save: function () {
                var that = this, attrs = that.model.toJSON();
                if (attrs.processing == false) {
                    this.model.set('processing', true);
                    try {
                        this.model.save({
                            params: [
                                { Name: '@pjmWatch', Type: 'FLOAT', Value: attrs.pjmWatch, },
                                { Name: '@pjmWarn', Type: 'FLOAT', Value: attrs.pjmWarn },
                                { Name: '@aepWatch', Type: 'FLOAT', Value: attrs.aepWatch, },
                                { Name: '@aepWarn', Type: 'FLOAT', Value: attrs.aepWarn, },
                            ],
                            success: function (model, resp) {
                                try {
                                    that.model.set('processing', false);
                                    that.finish({ result: 'SUCCESS', data: resp });
                                    that.hide();
                                }
                                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                            },
                            error: function (model, errorMsg) {
                                try {
                                    app.views.topMessages.showMessage(app.translate([{ options: { i18n: { 1: that.i18n, }, }, template: 1, }, app], errorMsg), { stay: 5 * 1000, });
                                }
                                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
                                finally {
                                    that.model.set('processing', false);
                                }
                            },
                        });
                    }
                    catch (e) {
                        this.model.set('processing', false);
                        throw e;
                    }
                }
            },
            show: function () {
                if (!this.isRendered) {
                    this.render();
                }
                else {
                    this.$el.modal({
                        keyboard: false,
                        backdrop: 'static',
                    });
                }
                return this;
            },
            hide: function () {
                var result = Modal.Views.SimpleModal.prototype.hide.apply(this, arguments);
                return result;
            },
            saveBtn_click: function (e) {
                try {
                    this.save();
                }
                catch (e) { console.error((e.stack) ? e.stack : new Error(e).stack); }
            },
        });
        // Required, return the module for AMD compliance.
        return Screen;
    });