"use strict";
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);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const mobx_1 = require("mobx");
const uuid = require("uuid");
const PiLogging_1 = require("../../util/PiLogging");
const LOGGER = new PiLogging_1.PiLogger("Box");
class Box {
    constructor(element, role) {
        this.roleNumber = undefined;
        this.selectable = true;
        this.parent = null;
        this.actualX = -1;
        this.actualY = -1;
        this.actualWidth = -1;
        this.actualHeight = -1;
        this.setFocus = () => __awaiter(this, void 0, void 0, function* () {
            LOGGER.info(this, "setFocus not set for " + this.id + " id " + this.$id);
        });
        this.element = element;
        this.role = role;
        this.$id = uuid.v4();
    }
    get id() {
        if (!!this.element) {
            return this.element.piId() + (this.role === null ? "" : "-" + this.role);
        }
        else {
            return "=" + this.role;
        }
    }
    get root() {
        let result = this;
        while (result.parent) {
            result = result.parent;
        }
        return result;
    }
    get children() {
        return [];
    }
    get firstLeaf() {
        if (this.isLeaf() && this.selectable) {
            return this;
        }
        for (let child of this.children) {
            const leafChild = child.firstLeaf;
            if (!!leafChild) {
                return leafChild;
            }
        }
        return null;
    }
    isLeaf() {
        return this.children.length == 0;
    }
    get lastLeaf() {
        if (this.isLeaf() && this.selectable) {
            return this;
        }
        const childrenReversed = this.children.filter(ch => true).reverse();
        for (let child of childrenReversed) {
            const leafChild = child.lastLeaf;
            if (!!leafChild) {
                return leafChild;
            }
        }
        return null;
    }
    get nextLeafRight() {
        if (!this.parent) {
            return null;
        }
        const thisIndex = this.parent.children.indexOf(this);
        let rightSiblings = this.parent.children.slice(thisIndex + 1, this.parent.children.length);
        for (let sibling of rightSiblings) {
            const siblingChild = sibling.firstLeaf;
            if (!!siblingChild) {
                return siblingChild;
            }
            if (sibling.isLeaf() && sibling.selectable) {
                return sibling;
            }
        }
        return this.parent.nextLeafRight;
    }
    get nextLeafLeft() {
        if (!this.parent) {
            return null;
        }
        const thisIndex = this.parent.children.indexOf(this);
        let leftSiblings = this.parent.children.slice(0, thisIndex).reverse();
        for (let sibling of leftSiblings) {
            const siblingChild = sibling.lastLeaf;
            if (!!siblingChild) {
                return siblingChild;
            }
            if (sibling.isLeaf() && sibling.selectable) {
                return sibling;
            }
        }
        return this.parent.nextLeafLeft;
    }
    toString() {
        return "[[" + this.id + "]]";
    }
    find(id) {
        if (this.id === id) {
            return this;
        }
        for (const b of this.children) {
            const result = b.find(id);
            if (result !== null) {
                return result;
            }
        }
        return null;
    }
    findBox(elementId, role) {
        if (!!this.element && this.element.piId() === elementId) {
            if (role !== null && role !== undefined) {
                if (this.role === role) {
                    return this;
                }
            }
            else {
                return this;
            }
        }
        for (const box of this.children) {
            const result = box.findBox(elementId, role);
            if (result !== null) {
                return result;
            }
        }
        return null;
    }
    setSetFocus(func) {
        this.setFocus = func;
    }
    get firstEditableChild() {
        const editableChildren = this.getEditableChildren();
        if (editableChildren.length > 0) {
            return editableChildren[0];
        }
        else {
            return this;
        }
    }
    getEditableChildren() {
        let result = [];
        this.getEditableChildrenRecursive(result);
        return result;
    }
    getEditableChildrenRecursive(result) {
        LOGGER.info(this, "getEditableChildrenRecursive for " + this.kind);
        if (this.isEditable()) {
            LOGGER.info(this, "Found editable: " + this.role);
            result.push(this);
            return;
        }
        this.children.forEach(c => {
            LOGGER.info(this, "child: " + c.kind);
            c.getEditableChildrenRecursive(result);
        });
    }
    isEditable() {
        return false;
    }
}
__decorate([
    mobx_1.observable,
    __metadata("design:type", String)
], Box.prototype, "role", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Number)
], Box.prototype, "roleNumber", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Object)
], Box.prototype, "element", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", String)
], Box.prototype, "style", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Number)
], Box.prototype, "actualX", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Number)
], Box.prototype, "actualY", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Number)
], Box.prototype, "actualWidth", void 0);
__decorate([
    mobx_1.observable,
    __metadata("design:type", Number)
], Box.prototype, "actualHeight", void 0);
exports.Box = Box;
//# sourceMappingURL=Box.js.map