var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "../../core/AtomBridge", "../../core/BindableProperty", "./AtomControl"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var AtomBridge_1 = require("../../core/AtomBridge");
    var BindableProperty_1 = require("../../core/BindableProperty");
    var AtomControl_1 = require("./AtomControl");
    /**
     * GridView columns or rows can accept comma separated strings with
     * absolute pixel value, percent value and star (*).
     *
     * For example, 20% of total width for first column, 200 pixel for last column
     * and rest of the space is for middle = "20%, *, 200"
     *
     * You can have only one star specification.
     * @example
     *  <AtomGridView
     *     rows="50,*"
     *     columns="20%, 5, *, 200">
     *
     *      <!-- Header spans for three columns in first row -->
     *      <header row="0" column="0:3"></header>
     *
     *      <!-- menu is on first column -->
     *      <menu row="1" column="0"></menu>
     *
     *      <!-- Grid splitter splits 1st and 3rd column and itself lies in 2nd column -->
     *      <AtomGridSplitter row="1" column="1" direction="vertical" />
     *
     *      <!-- Section fills remaining area -->
     *      <section row="1" column="2"></section>
     *
     *      <!-- Help sits on last column -->
     *      <Help row="1" column="3"></Help>
     *  </AtomGridView>
     */
    var AtomGridView = /** @class */ (function (_super) {
        __extends(AtomGridView, _super);
        function AtomGridView() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.attempt = 0;
            _this.availableRect = null;
            _this.childrenReady = false;
            return _this;
        }
        AtomGridView.getCellInfo = function (e) {
            var row = 0;
            var column = 0;
            var rowSpan = 1;
            var colSpan = 1;
            var cell = e.cell;
            if (cell) {
                // tslint:disable-next-line:no-console
                console.warn("Attribute `cell` is obsolete, please use row and column attributes separately");
                var tokens = cell.split(",")
                    .map(function (s) { return s.trim().split(":").map(function (st) { return parseInt(st.trim(), 10); }); });
                column = tokens[0][0];
                row = tokens[1][0];
                colSpan = tokens[0][1] || 1;
                rowSpan = tokens[1][1] || 1;
            }
            else {
                var c = ((e.row) || "0");
                var tokens = c.split(":").map(function (st) { return parseInt(st.trim(), 10); });
                row = tokens[0];
                rowSpan = tokens[1] || 1;
                c = ((e.column) || "0");
                tokens = c.split(":").map(function (st) { return parseInt(st.trim(), 10); });
                column = tokens[0];
                colSpan = tokens[1] || 1;
            }
            return {
                row: row,
                rowSpan: rowSpan,
                column: column,
                colSpan: colSpan,
            };
        };
        AtomGridView.prototype.append = function (e) {
            var ee = e instanceof AtomControl_1.AtomControl ? e.element : e;
            ee._logicalParent = this.element;
            this.children = this.children || [];
            this.children.push(e instanceof AtomControl_1.AtomControl ? e.element : e);
            return this;
        };
        AtomGridView.prototype.onUpdateUI = function () {
            var _this = this;
            this.attempt++;
            // this.removeAllChildren(this.element);
            var child = this.element.firstElementChild;
            while (child) {
                var c = child;
                child = child.nextElementSibling;
                c.remove();
            }
            var width = this.element.offsetWidth ||
                this.element.clientWidth ||
                parseFloat(this.element.style.width) ||
                0;
            var height = this.element.offsetHeight ||
                this.element.clientHeight ||
                parseFloat(this.element.style.height) ||
                0;
            if (!(width && height)) {
                if (this.childrenReady) {
                    // this is the time parent is hidden
                    setTimeout(function () {
                        _this.invalidate();
                    }, 5000);
                    return;
                }
                if (this.attempt > 100) {
                    // tslint:disable-next-line:no-console
                    console.error("AtomDockPanel (" + width + ", " + height + ") must both have non zero width and height");
                    return;
                }
                // AtomDispatcher.instance.callLater(() => this.invalidate());
                setTimeout(function () {
                    _this.invalidate();
                }, 100);
                return;
            }
            if (!this.children) {
                return;
            }
            this.attempt = 0;
            this.availableRect = { width: width, height: height, x: 0, y: 0 };
            this.columnSizes = (this.columns || "*").split(",")
                .map(function (s) { return _this.toSize(s.trim(), _this.availableRect.width); });
            this.rowSizes = (this.rows || "*").split(",")
                .map(function (s) { return _this.toSize(s.trim(), _this.availableRect.height); });
            this.assignOffsets(this.columnSizes, this.availableRect.width);
            this.assignOffsets(this.rowSizes, this.availableRect.height);
            for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
                var iterator = _a[_i];
                var host = document.createElement("section");
                host.appendChild(iterator);
                this.element.appendChild(host);
            }
            _super.prototype.onUpdateUI.call(this);
            this.updateSize();
            this.childrenReady = true;
        };
        AtomGridView.prototype.resize = function (item, index, delta) {
            var a = item === "column" ? this.columnSizes : this.rowSizes;
            var prev = a[index - 1];
            var next = a[index + 1];
            if ((!prev) || (!next)) {
                throw new Error("Grid Splitter cannot be start or end element in GridView");
            }
            var current = a[index];
            prev.size += delta;
            current.offset += delta;
            next.offset += delta;
            next.size -= delta;
            this.updateSize();
        };
        AtomGridView.prototype.onPropertyChanged = function (name) {
            switch (name) {
                case "rows":
                case "columns":
                    if (this.childrenReady) {
                        this.invalidate();
                    }
                    break;
            }
        };
        AtomGridView.prototype.onUpdateSize = function () {
            if (!this.children) {
                return;
            }
            for (var _i = 0, _a = this.children; _i < _a.length; _i++) {
                var iterator = _a[_i];
                this.updateStyle(iterator);
            }
        };
        AtomGridView.prototype.preCreate = function () {
            var _this = this;
            var style = this.element.style;
            style.position = "absolute";
            style.left = style.right = style.top = style.bottom = "0";
            style.overflow = "hidden";
            this.bindEvent(window, "resize", function () {
                _this.updateSize();
            });
            this.bindEvent(document.body, "resize", function () {
                _this.updateSize();
            });
        };
        AtomGridView.prototype.updateStyle = function (e) {
            var _a = AtomGridView.getCellInfo(e), colSpan = _a.colSpan, column = _a.column, row = _a.row, rowSpan = _a.rowSpan;
            var host = e.parentElement;
            if (!host) {
                return;
            }
            host.style.position = "absolute";
            host.style.overflow = "hidden";
            host.style.padding = "0";
            host.style.margin = "0";
            var rowStart = this.rowSizes[row].offset;
            var rowSize = 0;
            for (var i = row; i < row + rowSpan; i++) {
                rowSize += this.rowSizes[i].size;
            }
            host.style.top = rowStart + "px";
            host.style.height = rowSize + "px";
            var colStart = this.columnSizes[column].offset;
            var colSize = 0;
            for (var i = column; i < column + colSpan; i++) {
                colSize += this.columnSizes[i].size;
            }
            host.style.left = colStart + "px";
            host.style.width = colSize + "px";
            AtomBridge_1.AtomBridge.instance.visitDescendents(host, function (el, ac) {
                if (ac) {
                    ac.invalidate();
                    return false;
                }
                return true;
            });
        };
        AtomGridView.prototype.toSize = function (s, total) {
            if (!s || s === "*") {
                return { offset: -1, size: NaN };
            }
            var n = 0;
            if (s.endsWith("%")) {
                s = s.substr(0, s.length - 1);
                n = parseFloat(s);
                return { offset: -1, size: total * n / 100 };
            }
            return { offset: -1, size: parseFloat(s) };
        };
        AtomGridView.prototype.assignOffsets = function (a, end) {
            var start = 0;
            var fill = null;
            for (var _i = 0, a_1 = a; _i < a_1.length; _i++) {
                var item = a_1[_i];
                item.offset = start;
                if (isNaN(item.size)) {
                    fill = item;
                    break;
                }
                start += item.size;
            }
            if (!fill) {
                return;
            }
            var lastStart = start;
            start = end;
            var r = a.map(function (x) { return x; }).reverse();
            for (var _a = 0, r_1 = r; _a < r_1.length; _a++) {
                var item = r_1[_a];
                if (isNaN(item.size)) {
                    if (fill !== item) {
                        throw new Error("Multiple * cannot be defined");
                    }
                    break;
                }
                start -= item.size;
                item.offset = start;
            }
            fill.offset = lastStart;
            fill.size = start - lastStart;
        };
        __decorate([
            BindableProperty_1.BindableProperty,
            __metadata("design:type", String)
        ], AtomGridView.prototype, "columns", void 0);
        __decorate([
            BindableProperty_1.BindableProperty,
            __metadata("design:type", String)
        ], AtomGridView.prototype, "rows", void 0);
        return AtomGridView;
    }(AtomControl_1.AtomControl));
    exports.AtomGridView = AtomGridView;
});
//# sourceMappingURL=AtomGridView.js.map