"use strict";
/* Copyright 2015 Bloomberg Finance L.P.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GridHeatMapModel = exports.AxisMode = void 0;
const _ = __importStar(require("underscore"));
const MarkModel_1 = require("./MarkModel");
const serialize = __importStar(require("./serialize"));
var AxisMode;
(function (AxisMode) {
    AxisMode[AxisMode["Middle"] = 0] = "Middle";
    AxisMode[AxisMode["Boundaries"] = 1] = "Boundaries";
    AxisMode[AxisMode["ExpandOne"] = 2] = "ExpandOne";
    AxisMode[AxisMode["ExpandTwo"] = 3] = "ExpandTwo";
})(AxisMode = exports.AxisMode || (exports.AxisMode = {}));
class GridHeatMapModel extends MarkModel_1.MarkModel {
    defaults() {
        return Object.assign(Object.assign({}, MarkModel_1.MarkModel.prototype.defaults()), { _model_name: 'GridHeatMapModel', _view_name: 'GridHeatMap', row: null, column: null, color: null, scales_metadata: {
                row: { orientation: 'vertical', dimension: 'y' },
                column: { orientation: 'horizontal', dimension: 'x' },
                color: { dimension: 'color' },
            }, row_align: 'start', column_align: 'start', null_color: 'black', stroke: 'black', opacity: 1.0, anchor_style: {}, display_format: null, font_style: {} });
    }
    initialize(attributes, options) {
        super.initialize(attributes, options);
        this.on_some_change(['row', 'column', 'color'], this.update_data, this);
        this.on_some_change(['preserve_domain'], this.update_domains, this);
        this.update_data();
        this.update_domains();
    }
    update_data() {
        this.dirty = true;
        // Handling data updates
        const numCols = this.colors[0].length;
        const flatColors = [].concat.apply([], this.colors.map((x) => Array.prototype.slice.call(x, 0)));
        this.mark_data = flatColors.map((data, index) => {
            const rowNum = Math.floor(index / numCols);
            const colNum = index % numCols;
            return {
                rowNum: rowNum,
                row: this.rows[rowNum],
                column: this.columns[colNum],
                columnNum: colNum,
                color: data,
                cellNum: index,
            };
        });
        this.identifyModes();
        this.update_domains();
        this.dirty = false;
        this.trigger('data_updated');
    }
    update_domains() {
        if (!this.mark_data) {
            return;
        }
        const scales = this.get('scales');
        const y_scale = scales.row, x_scale = scales.column;
        const color_scale = scales.color;
        if (!this.get('preserve_domain').row) {
            y_scale.compute_and_set_domain(this.rows, this.model_id + '_row');
        }
        else {
            y_scale.del_domain([], this.model_id + '_row');
        }
        if (!this.get('preserve_domain').column) {
            x_scale.compute_and_set_domain(this.columns, this.model_id + '_column');
        }
        else {
            x_scale.del_domain([], this.model_id + '_column');
        }
        if (color_scale !== null && color_scale !== undefined) {
            if (!this.get('preserve_domain').color) {
                color_scale.compute_and_set_domain(this.mark_data.map((elem) => elem.color), this.model_id + '_color');
            }
            else {
                color_scale.del_domain([], this.model_id + '_color');
            }
        }
    }
    get_data_dict(data, index) {
        return data;
    }
    get colors() {
        if (this.get('color')) {
            return this.get('color');
        }
        return [[]];
    }
    get rows() {
        if (this.get('row')) {
            return Array.from(this.get('row'));
        }
        return _.range(this.colors.length);
    }
    get columns() {
        if (this.get('column')) {
            return Array.from(this.get('column'));
        }
        return _.range(this.colors[0].length);
    }
    identifyModes() {
        //based on the data, identify the mode in which the heatmap should
        //be plotted.
        const scales = this.get('scales');
        const rowScale = scales.row;
        const columnScale = scales.column;
        const nRows = this.colors.length;
        const nColumns = this.colors[0].length;
        this.modes = { column: AxisMode.Middle, row: AxisMode.Middle };
        if (rowScale.type === 'ordinal') {
            this.modes.row = AxisMode.Middle;
        }
        else {
            if (nRows === this.rows.length - 1) {
                this.modes.row = AxisMode.Boundaries;
            }
            else if (nRows === this.rows.length) {
                this.modes.row = AxisMode.ExpandOne;
            }
            else if (nRows === this.rows.length + 1) {
                this.modes.row = AxisMode.ExpandTwo;
            }
        }
        if (columnScale.type === 'ordinal') {
            this.modes.column = AxisMode.Middle;
        }
        else {
            if (nColumns === this.columns.length - 1) {
                this.modes.column = AxisMode.Boundaries;
            }
            else if (nColumns === this.columns.length) {
                this.modes.column = AxisMode.ExpandOne;
            }
            else if (nColumns === this.columns.length + 1) {
                this.modes.column = AxisMode.ExpandTwo;
            }
        }
    }
}
exports.GridHeatMapModel = GridHeatMapModel;
GridHeatMapModel.serializers = Object.assign(Object.assign({}, MarkModel_1.MarkModel.serializers), { row: serialize.array_or_json_serializer, column: serialize.array_or_json_serializer, color: serialize.array_or_json_serializer });
//# sourceMappingURL=GridHeatMapModel.js.map