var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Settings;
(function (Settings) {
    var Gadget;
    (function (Gadget) {
        // Settings.Gadget.SettingGroup.Series
        Gadget.SettingGroup = $.extend(Gadget.SettingGroup, {
            Series: "5ba40ea6-daf8-11df-8852-4ef3dfd72085"
        });
        /**
         * Setting for the maximum number of series supported by a gadget type.
         */
        Gadget.MaximumNumberOfSeries = { id: Gadget.SettingGroup.Series, name: "MaximumNumberOfSeries" };
        /**
         * Indicates if the specified item represents a data series setting.
         * @param settingOrName A setting name or a setting object with group and name.
         */
        function IsDataSeriesSetting(settingOrName) {
            if (settingOrName) {
                var settingName = _.isString(settingOrName) ? settingOrName : settingOrName.Name;
                if (_.isString(settingName)) {
                    if (settingName.indexOf("DataSeries") > 0) {
                        return true;
                    }
                }
            }
            return false;
        }
        Gadget.IsDataSeriesSetting = IsDataSeriesSetting;
        ;
    })(Gadget = Settings.Gadget || (Settings.Gadget = {}));
})(Settings || (Settings = {}));
var Dashboards;
(function (Dashboards) {
    var SetupControl;
    (function (SetupControl) {
        /**
         * Gadget data series setup control.
         */
        var DataSeries = (function (_super) {
            __extends(DataSeries, _super);
            function DataSeries() {
                _super.call(this, Settings.Gadget.SettingGroup.Series);
                this.seriesOptions = [];
                this.selectedSeries = null;
                this.$template = $('<div/>');
                this.$dataSeriesTable = null;
                this.$dataSeriesTableEmpty = null;
                this.$rowEntryTemplate = null;
                this.maximumNumberOfSeries = 100;
                this.title = i18n.loc.s('Gadgets', 'DataSeriesControl_Title');
            }
            DataSeries.CreateInstance = function () {
                var instance = new DataSeries();
                return instance;
            };
            /* SetupControl Implementation
            ******************************************************************************/
            /** Prepares the control inputs and data for saving. */
            DataSeries.prototype.beforeCommit = function () {
                // Need to get the data series ready for saving.
                // Take all the non-data series settings as is.
                var settings = _.filter(this.settings, function (setting) { return (!Settings.Gadget.IsDataSeriesSetting(setting)); });
                // Update internal Ids
                this.updateSeriesOptionIds();
                // Add data series based on the series options we have
                _.each(this.seriesOptions, function (option) {
                    if (option.setting.Value.length > 0) {
                        settings.push(option.setting);
                    }
                    ;
                });
                this.settings = settings;
            };
            /* Draws the control into its container. */
            DataSeries.prototype.draw = function () {
                var _this = this;
                this.$container.empty();
                TemplateUtil.LocAndLoad(DataSeries.SetupControlTemplateUri, new Core.CallBack(function (template) {
                    _this.$template.html(template);
                    _this.$container.append(_this.$template.find('.dataSeries_SetupControl'));
                    _this.$dataSeriesTable = _this.$container.find('.gadgetOptionDataSeriesTable');
                    _this.$dataSeriesTableEmpty = _this.$container.find('.gadgetOptionDataSeriesTableEmpty');
                    _this.$rowEntryTemplate = _this.$template.find('.dataSeriesRowEntryTemplate');
                    _this.render();
                }, this));
            };
            /** Indicates if the control contains a configured setting(s). */
            DataSeries.prototype.isConfigured = function () {
                return this.seriesOptions.length > 0;
            };
            /** Indicates if the setting is known to and managed by this control. */
            DataSeries.prototype.isManagedSetting = function (name) {
                var managed = false;
                // Pattern-based names
                if (Settings.Gadget.IsDataSeriesSetting(name)) {
                    managed = true;
                }
                else {
                    // Fixed names
                    switch (name) {
                        case Settings.Gadget.MaximumNumberOfSeries.name:
                            managed = true;
                            break;
                    }
                }
                return managed;
            };
            /* Private methods
            ******************************************************************************/
            DataSeries.prototype.render = function () {
                var _this = this;
                _.each(this.settings, function (setting) {
                    var seriesOption = new DataSeries.SeriesOption(setting);
                    if (seriesOption.isValid()) {
                        _this.seriesOptions.push(seriesOption);
                    }
                    ;
                });
                var maxSeriesCount = this.setting(Settings.Gadget.MaximumNumberOfSeries.name);
                if (maxSeriesCount === '0' || _.isNull(maxSeriesCount))
                    maxSeriesCount = '100';
                this.maximumNumberOfSeries = parseInt(maxSeriesCount);
                this.bindEventHandlers();
                if (this.isSmallRenderWindow()) {
                    this.$dataSeriesTable.addClass('gadgetOptionDataSeriesTableSmall');
                    this.$dataSeriesTableEmpty.addClass('gadgetOptionDataSeriesTableSmallEmpty');
                }
                this.rebuildDataSeriesList();
            };
            // Bind all static event handlers.  Should only ever be called once.
            DataSeries.prototype.bindEventHandlers = function () {
                var _this = this;
                // Hook up resize handler for Data Series dialog
                // Edit Data Series click 
                this.$container.find('.buttonEditSeries').click(function () {
                    _this.selectedSeries = _this.seriesOptions[_this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItemSelected).data('seriesoption')];
                    SetupControl.DataSeriesEditDialog.ShowDialog(_this.seriesOptions, _this.allSettings, new Core.CallBackPayload(_this.seriesDialogClosed, _this), _this.selectedSeries);
                });
                // Delete Data Series Click
                this.$container.find('.buttonRemoveSeries').click(function () {
                    var selSeries = _this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItemSelected);
                    if (!selSeries || !selSeries[0])
                        return;
                    selSeries = $(selSeries[0]);
                    var selectedIdx = selSeries.data('seriesoption');
                    _this.seriesOptions.splice(selectedIdx, 1); // remove DataSeries
                    if (_this.seriesOptions[selectedIdx]) {
                        // Select the "next" item, the one that now takes the old place
                        _this.selectedSeries = _this.seriesOptions[selectedIdx];
                    }
                    else if (_this.seriesOptions[selectedIdx - 1]) {
                        // Select the "previous" item, as we deleted the last item
                        _this.selectedSeries = _this.seriesOptions[selectedIdx - 1];
                    }
                    else {
                        // Odd...  Simply reset the selected series so that the first item 
                        // will be selected on the rebuild (if it exists)
                        _this.selectedSeries = null;
                    }
                    _this.rebuildDataSeriesList();
                    _this.setupSeriesListButtonState();
                });
                // Add Data Series Click
                this.$container.find('.buttonAddNewSeries').click(function () {
                    // create a new series option object
                    var newSeries = new DataSeries.SeriesOption({
                        Name: "PrimaryDataSeries" + (_this.seriesOptions.length + 1),
                        Value: '{"customUnits":false, "customTitle": false}'
                    });
                    SetupControl.DataSeriesEditDialog.ShowDialog(_this.seriesOptions, _this.allSettings, new Core.CallBackPayload(_this.seriesDialogClosed, _this), newSeries);
                });
                // Data Series Move Up
                this.$container.find('.buttonMoveSeriesUp').click(function () {
                    _this.swapSeries('buttonMoveSeriesUp', -1);
                });
                // Data Series Move Down
                this.$container.find('.buttonMoveSeriesDown').click(function () {
                    _this.swapSeries('buttonMoveSeriesDown', 1);
                });
            };
            DataSeries.prototype.swapSeries = function (buttonMoveSeries, idxDelta) {
                if (this.$container.find('.' + buttonMoveSeries).hasClass(Dashboards.Views.Application.ClassDisabledFakeButton))
                    return;
                var selSeries = this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItemSelected);
                if (!selSeries || !selSeries[0])
                    return;
                selSeries = $(selSeries[0]);
                var selectedIdx = selSeries.data('seriesoption');
                if (selectedIdx != undefined) {
                    this.selectedSeries = this.seriesOptions[selectedIdx];
                    this.seriesOptions.splice(selectedIdx, 1); // remove DataSeries
                    this.seriesOptions.splice(selectedIdx + idxDelta, 0, this.selectedSeries); // re-add DataSeries
                    this.rebuildDataSeriesList();
                }
            };
            DataSeries.prototype.seriesDialogClosed = function (valid, updatedSeries) {
                if (valid.success) {
                    var existingIndex = _.findIndex(this.seriesOptions, function (seriesOption) {
                        return seriesOption.uniqueId === updatedSeries.uniqueId;
                    });
                    if (existingIndex < 0) {
                        // add to the local list.
                        this.seriesOptions.push(updatedSeries);
                    }
                    else {
                        this.seriesOptions[existingIndex] = updatedSeries;
                    }
                    // Update the internal Settings
                    updatedSeries.updateSettingsValue();
                    this.selectedSeries = updatedSeries;
                    this.rebuildDataSeriesList();
                }
            };
            DataSeries.prototype.rebuildDataSeriesList = function () {
                var _this = this;
                this.$dataSeriesTable.empty();
                if (!this.seriesOptions || this.seriesOptions.length === 0) {
                    this.$dataSeriesTable.hide();
                    this.$dataSeriesTableEmpty.show();
                }
                else {
                    this.$dataSeriesTable.show();
                    this.$dataSeriesTableEmpty.hide();
                    // Update internal Ids
                    this.updateSeriesOptionIds();
                    _.each(this.seriesOptions, function (seriesOption, idx) {
                        // Title Cell
                        var seriesDisplay = seriesOption.title;
                        if (seriesOption.units && seriesOption.units.length > 0) {
                            seriesDisplay = seriesDisplay + " (" + seriesOption.units + ")";
                        }
                        var $entryTemplate = _this.$rowEntryTemplate.clone();
                        var $populatedRowEntry = $(TemplateUtil.ApplyLocalModel('dataSeriesRowEntryTemplate', $entryTemplate.html(), {
                            color: seriesOption.color,
                            title: seriesDisplay
                        }));
                        $populatedRowEntry.data('seriesoption', idx);
                        if (!_this.selectedSeries) {
                            _this.selectedSeries = seriesOption;
                        }
                        if (seriesOption.uniqueId === _this.selectedSeries.uniqueId) {
                            $populatedRowEntry.addClass(Dashboards.Views.Application.ClassCustomListItemSelected);
                        }
                        $populatedRowEntry.click(function () {
                            _this.dataSeriesItemSelect($populatedRowEntry);
                        });
                        $populatedRowEntry.dblclick(function () {
                            var series = _this.seriesOptions[$($populatedRowEntry).data('seriesoption')];
                            SetupControl.DataSeriesEditDialog.ShowDialog(_this.seriesOptions, _this.allSettings, new Core.CallBackPayload(_this.seriesDialogClosed, _this), series);
                        });
                        _this.$dataSeriesTable.append($populatedRowEntry);
                    });
                    var $selectedEntry = this.$dataSeriesTable.find('.' + Dashboards.Views.Application.ClassCustomListItemSelected);
                    if ($selectedEntry && $selectedEntry.length > 0) {
                        // Ensure selected is visible
                        this.$dataSeriesTable.scrollTop(0);
                        var listTop = this.$dataSeriesTable.position().top;
                        var selectionTop = $selectedEntry.position().top;
                        this.$dataSeriesTable.scrollTop(selectionTop - listTop - 30);
                    }
                }
                this.setupSeriesListButtonState();
            };
            // Clicked on series in Series list
            DataSeries.prototype.dataSeriesItemSelect = function ($clickedItem) {
                this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItemSelected).removeClass(Dashboards.Views.Application.ClassCustomListItemSelected);
                $clickedItem.addClass(Dashboards.Views.Application.ClassCustomListItemSelected);
                this.selectedSeries = $clickedItem.data('seriesoption');
                this.setupSeriesListButtonState();
            };
            DataSeries.prototype.setupSeriesListButtonState = function () {
                var _this = this;
                // Only can add if not exceed max series
                if (this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItem).length >= this.maximumNumberOfSeries) {
                    this.$container.find('.buttonAddNewSeries').prop('disabled', 'disabled');
                }
                else {
                    this.$container.find('.buttonAddNewSeries').prop('disabled', '');
                }
                if (this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItemSelected).length < 1) {
                    // No Selection, disable buttons
                    this.$container.find('.buttonRemoveSeries').prop('disabled', 'disabled');
                    this.$container.find('.buttonEditSeries').prop('disabled', 'disabled');
                    this.$container.find('.buttonMoveSeriesUp').addClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                    this.$container.find('.buttonMoveSeriesDown').addClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                }
                else {
                    // Selection
                    this.$container.find('.buttonRemoveSeries').prop('disabled', '');
                    this.$container.find('.buttonEditSeries').prop('disabled', '');
                    this.$container.find('.buttonMoveSeriesUp').addClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                    this.$container.find('.buttonMoveSeriesDown').addClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                    // More than 1 item.  Disable move up/down, then test for valid cases to enable
                    if (this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItem).length > 1) {
                        _.each(this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItem), function (row, idx) {
                            if ($(row).hasClass(Dashboards.Views.Application.ClassCustomListItemSelected)) {
                                if (idx > 0) {
                                    // Allow move up
                                    _this.$container.find('.buttonMoveSeriesUp').removeClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                                }
                                if (idx < _this.$container.find('.gadgetOptionDataSeriesTable .' + Dashboards.Views.Application.ClassCustomListItem).length - 1) {
                                    // Allow move down
                                    _this.$container.find('.buttonMoveSeriesDown').removeClass(Dashboards.Views.Application.ClassDisabledFakeButton);
                                }
                            }
                        });
                    }
                }
            };
            DataSeries.prototype.updateSeriesOptionIds = function () {
                var _this = this;
                var prefixes = ["PrimaryDataSeries", "SecondaryDataSeries"];
                _.each(prefixes, function (prefix) {
                    var number = Number(1);
                    _.each(_this.seriesOptions, function (seriesOption) {
                        if (seriesOption.uniqueId.indexOf(prefix) === 0) {
                            seriesOption.uniqueId = prefix + number;
                            seriesOption.setting.Name = seriesOption.uniqueId;
                            number++;
                        }
                    });
                });
            };
            DataSeries.SetupControlTemplateUri = 'Content/Gadgets/_baseSetupControls/DataSeriesSetupControlTemplate.html';
            return DataSeries;
        }(Dashboards.Models.SetupControl));
        SetupControl.DataSeries = DataSeries;
    })(SetupControl = Dashboards.SetupControl || (Dashboards.SetupControl = {}));
})(Dashboards || (Dashboards = {}));
// Register the Setup Control
Dashboards.Controllers.SetupControl.Register({
    create: Dashboards.SetupControl.DataSeries.CreateInstance,
    id: Settings.Gadget.SettingGroup.Series
});
var Dashboards;
(function (Dashboards) {
    var SetupControl;
    (function (SetupControl) {
        var DataSeries;
        (function (DataSeries) {
            /**
             * Class that converts a gadget data series setting to/from the options
             * object used by the data series editor dialog.
             */
            var SeriesOption = (function () {
                function SeriesOption(setting) {
                    /** A unique identifier for the series. */
                    this.uniqueId = '';
                    /** Series source ID. */
                    this.SourceId = '';
                    /** Series measurement ID. */
                    this.MeasurementId = '';
                    /** Series color. */
                    this.color = '';
                    /** Series axis. */
                    this.axis = '';
                    /** Series type. */
                    this.seriesType = '';
                    /** Series title. */
                    this.title = '';
                    /** Custom title. */
                    this.customTitle = false;
                    /** Series units. */
                    this.units = '';
                    /** Series custom units. */
                    this.customUnits = false;
                    /** Series line width. */
                    this.lineWidth = 3;
                    /** Number of decimals to display for the series values. */
                    this.numberOfDecimals = '';
                    /** Series multiplier. */
                    this.multiplier = 1;
                    /** Series device name. */
                    this.DeviceName = '';
                    /** Series topic name. */
                    this.TopicName = '';
                    if (this.isValidSetting(setting)) {
                        this.setting = setting;
                        this.uniqueId = setting.Name;
                        var value = JSON.parse(setting.Value);
                        this.SourceId = value.DeviceId;
                        this.MeasurementId = value.TopicId;
                        this.color = value.Color;
                        this.axis = setting.Name.indexOf("PrimaryDataSeries") === 0 ? "left" : "right";
                        this.seriesType = value.seriesType;
                        this.title = value.Name;
                        // If this is an upgraded gadget, then it will not have this flag.  We set it to custom.
                        var customTitle = _.isUndefined(value.customTitle) ? true : value.customTitle;
                        this.customTitle = customTitle;
                        // If this is an upgraded gadget, then it will not have this flag.  We set it to custom.
                        this.units = _.isUndefined(value.customUnits) ? '' : value.UnitName;
                        var customUnits = _.isUndefined(value.customUnits) ? true : value.customUnits;
                        this.customUnits = customUnits;
                        this.lineWidth = value.LineWidth ? value.LineWidth : 3;
                        this.numberOfDecimals = "1";
                        this.multiplier = value.Multiplier;
                        // These aren't fed into the selector; they are present
                        // for quickly showing information about the series 
                        // without incurring a call to the provider service tier.
                        this.DeviceName = value.DeviceName;
                        this.TopicName = value.TopicName;
                    }
                }
                /** Indicates if the series option is valid. */
                SeriesOption.prototype.isValid = function () {
                    return this.setting !== undefined;
                };
                /** Indicates if the setting is valid. */
                SeriesOption.prototype.isValidSetting = function (s) {
                    // Must be a data series and must have a value
                    if (!Settings.Gadget.IsDataSeriesSetting(s))
                        return false;
                    if (!s.Value || s.Value.length <= 0)
                        return false;
                    // Probably a data series setting ....
                    return true;
                };
                /**
                 * Updates the gadget series setting object with the values
                 * set on the option object.
                 */
                SeriesOption.prototype.updateSettingsValue = function () {
                    var pso = {
                        DeviceId: this.SourceId,
                        TopicId: this.MeasurementId,
                        Color: this.color,
                        LineWidth: this.lineWidth,
                        seriesType: this.seriesType,
                        UnitName: this.units,
                        customUnits: this.customUnits,
                        Name: this.title,
                        customTitle: this.customTitle,
                        Multiplier: this.multiplier,
                        DeviceName: this.DeviceName,
                        TopicName: this.TopicName
                    };
                    this.setting.Value = JSON.stringify(pso);
                    // the data series are assigned sequential number later
                    this.setting.Name = this.axis === "right" ? "SecondaryDataSeries99" : "PrimaryDataSeries99";
                    this.uniqueId = this.setting.Name;
                };
                return SeriesOption;
            }());
            DataSeries.SeriesOption = SeriesOption;
        })(DataSeries = SetupControl.DataSeries || (SetupControl.DataSeries = {}));
    })(SetupControl = Dashboards.SetupControl || (Dashboards.SetupControl = {}));
})(Dashboards || (Dashboards = {}));
//# sourceMappingURL=DataSeriesSetupControl.js.map