"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 classNames = require("classnames");
const mobx_react_1 = require("mobx-react");
const React = require("react");
const PiLogging_1 = require("../../../util/PiLogging");
const AliasBox_1 = require("../../boxes/AliasBox");
const TextBox_1 = require("../../boxes/TextBox");
const BehaviorUtils_1 = require("../../../util/BehaviorUtils");
const Keys = require("../../../util/Keys");
const Keys_1 = require("../../../util/Keys");
const PiLogging_2 = require("../../../util/PiLogging");
const PiUtils_1 = require("../../../util/PiUtils");
const Styles_1 = require("../styles/Styles");
const LOGGER = new PiLogging_1.PiLogger("TextComponent").mute();
let TextComponent = class TextComponent extends React.Component {
    constructor(props) {
        super(props);
        this.originalValue = "";
        this.isEditing = false;
        this.caretPosition = 0;
        this.element = null;
        this.setElement = (element) => {
            this.element = element;
        };
        this.onFocus = () => {
            LOGGER.info(this, "onFocus: " + this.props.box.role + " : " + this.props.box.element.piId());
        };
        this.onClick = () => {
            PiLogging_2.EVENT_LOG.info(this, "changeShowNavigator: " + this.props.box.getText());
            this.startEditing();
            this.props.box.caretPosition = this.getCaretPosition();
        };
        this.onBlur = () => {
            PiLogging_2.EVENT_LOG.info(this, "onBlur: " + this.props.box.getText());
        };
        this.onPaste = (e) => {
            PiLogging_2.EVENT_LOG.info(this, "onPaste: disabled pasting in text");
            e.stopPropagation();
            e.preventDefault();
            return false;
        };
        this.onInput = () => __awaiter(this, void 0, void 0, function* () {
            const innerTextNotNull = this.element.innerText !== null ? this.element.innerText : "";
            PiLogging_2.EVENT_LOG.info(this, "onInput innerText [" + innerTextNotNull + "]");
            const box = this.props.box;
            box.caretPosition = this.getCaretPosition();
            this.caretPosition = box.caretPosition;
            this.props.editor.selectedPosition = BehaviorUtils_1.PiCaret.IndexPosition(box.caretPosition);
            box.setText(innerTextNotNull);
            if (box.deleteWhenEmpty && box.getText().length === 0) {
                PiLogging_2.EVENT_LOG.info(this, "delete empty text");
                this.props.editor.deleteBox(box);
            }
            LOGGER.info(this, "END END");
            yield this.props.editor.selectElement(box.element, box.role, this.props.editor.selectedPosition);
        });
        this.onKeyDown = (e) => __awaiter(this, void 0, void 0, function* () {
            PiLogging_2.EVENT_LOG.info(this, "onKeyDown: key " + e.key + " keyCode " + e.keyCode + " charCode " + e.charCode + " isMeta?: " + Keys_1.isMetaKey(e));
            let handled = false;
            const caretPosition = this.getCaretPosition();
            if (e.keyCode === Keys.DELETE) {
                if (this.element.innerText === "") {
                    if (this.props.box.deleteWhenEmptyAndErase) {
                        yield this.props.editor.deleteBox(this.props.editor.selectedBox);
                        e.stopPropagation();
                        return;
                    }
                }
                e.stopPropagation();
                return;
            }
            if (e.keyCode === Keys.BACKSPACE) {
                if (this.element.innerText === "") {
                    if (this.props.box.deleteWhenEmptyAndErase) {
                        yield this.props.editor.deleteBox(this.props.editor.selectedBox);
                        e.stopPropagation();
                        return;
                    }
                }
            }
            if (!this.shouldPropagate(e)) {
                e.stopPropagation();
            }
            if (this.shouldIgnore(e)) {
                e.preventDefault();
            }
            else {
                handled = true;
            }
            const proKey = Keys_1.reactToKey(e);
            if (!handled && !Keys_1.isMetaKey(e)) {
                const isKeyboardShortcutForThis = yield PiUtils_1.PiUtils.handleKeyboardShortcut(proKey, this.props.box, this.props.editor);
                if (!isKeyboardShortcutForThis) {
                    PiLogging_2.EVENT_LOG.info(this, "Key not handled for element " + this.props.box.element);
                    const box = this.props.box;
                    const insertionIndex = this.getCaretPosition();
                    if (insertionIndex >= box.getText().length) {
                        this.props.editor.selectNextLeaf();
                        PiLogging_2.EVENT_LOG.info(this, "KeyDownAction NEXT LEAF IS " + this.props.editor.selectedBox.role);
                        if (AliasBox_1.isAliasBox(this.props.editor.selectedBox)) {
                            this.props.editor.selectedBox.triggerKeyDownEvent(proKey);
                        }
                        e.preventDefault();
                        e.stopPropagation();
                    }
                }
            }
        });
        this.onKeyPress = (e) => __awaiter(this, void 0, void 0, function* () {
            PiLogging_2.EVENT_LOG.info(this, "onKeyPress: " + e.key + "  " + this.props.box.actualWidth);
            const box = this.props.box;
            const insertionIndex = this.getCaretPosition();
            switch (this.props.box.keyPressAction(box.getText(), e.key, insertionIndex)) {
                case TextBox_1.KeyPressAction.OK:
                    PiLogging_2.EVENT_LOG.info(this, "KeyPressAction.OK");
                    box.caretPosition = this.getCaretPosition() + 1;
                    e.stopPropagation();
                    break;
                case TextBox_1.KeyPressAction.NOT_OK:
                    PiLogging_2.EVENT_LOG.info(this, "KeyPressAction.NOT_OK");
                    e.preventDefault();
                    e.stopPropagation();
                    break;
                case TextBox_1.KeyPressAction.GOTO_NEXT:
                    PiLogging_2.EVENT_LOG.info(this, "KeyPressAction.GOTO_NEXT");
                    this.props.editor.selectNextLeaf();
                    PiLogging_2.EVENT_LOG.info(this, "NEXT LEAF IS " + this.props.editor.selectedBox.role);
                    if (AliasBox_1.isAliasBox(this.props.editor.selectedBox)) {
                        this.props.editor.selectedBox.triggerKeyPressEvent(e.key);
                    }
                    e.preventDefault();
                    e.stopPropagation();
                    break;
            }
        });
        this.setFocus = () => {
            LOGGER.info(this, "TextComponent set focus " + this.props.box.role);
            this.startEditing();
        };
        this.subscribeToBoxEvents = (box) => {
            box.setCaret = this.setCaret;
            box.setFocus = this.setFocus;
        };
        this.setCaret = (caret) => {
            switch (caret.position) {
                case BehaviorUtils_1.PiCaretPosition.RIGHT_MOST:
                    LOGGER.info(this, "setCaretPosition RIGHT");
                    this.setCaretToMostRight();
                    break;
                case BehaviorUtils_1.PiCaretPosition.LEFT_MOST:
                    LOGGER.info(this, "setCaretPosition LEFT");
                    this.setCaretToMostLeft();
                    break;
                case BehaviorUtils_1.PiCaretPosition.INDEX:
                    LOGGER.info(this, "setCaretPosition INDEX");
                    this.setCaretPosition(caret.index);
                    break;
                case BehaviorUtils_1.PiCaretPosition.UNSPECIFIED:
                    LOGGER.info(this, "setCaretPosition UNSPECIFIED");
                    break;
                default:
                    LOGGER.info(this, "setCaretPosition ERROR");
                    break;
            }
            this.element.focus();
        };
        this.setCaretToMostLeft = () => {
            this.startEditing();
            this.setCaretPosition(0);
        };
        this.setCaretToMostRight = () => {
            this.startEditing();
            LOGGER.info(this, "setCaretPosition RIGHT: " + this.props.box.getText().length);
            this.setCaretPosition(this.props.box.getText().length);
        };
        this.shouldPropagate = (e) => {
            if (Keys_1.isMetaKey(e)) {
                if (e.keyCode === Keys.ARROW_UP || e.keyCode === Keys.ARROW_DOWN || e.keyCode === Keys.TAB) {
                    return true;
                }
            }
            if (e.keyCode === Keys.ENTER || e.keyCode === Keys.DELETE || e.keyCode === Keys.TAB) {
                return true;
            }
            if (e.keyCode === Keys.ARROW_UP || e.keyCode === Keys.ARROW_DOWN) {
                return true;
            }
            const caretPosition = this.getCaretPosition();
            if (e.keyCode === Keys.ARROW_LEFT || e.keyCode === Keys.BACKSPACE) {
                return caretPosition <= 0;
            }
            else if (e.keyCode === Keys.ARROW_RIGHT || e.keyCode === Keys.DELETE) {
                return caretPosition >= this.element.innerText.length;
            }
            else {
                return false;
            }
        };
        this.shouldIgnore = (e) => {
            if (e.altKey) {
                return true;
            }
            if (e.keyCode === Keys.ENTER || e.keyCode === Keys.TAB) {
                return true;
            }
            return false;
        };
        this.startEditing = () => {
            if (this.isEditing) {
                return;
            }
            this.isEditing = true;
            this.originalValue = this.props.box.getText();
            if (this.element) {
                this.element.focus();
            }
        };
        this.stopEditing = (aborted) => {
            this.isEditing = false;
            this.props.box.caretPosition = -1;
            if (aborted) {
                this.props.box.setText(this.originalValue);
            }
            this.clearSelection();
        };
        this.getCaretPosition = () => {
            return window.getSelection().focusOffset;
        };
        this.setCaretPosition = (position) => {
            if (position === -1) {
                return;
            }
            if (!this.element.innerText) {
                return;
            }
            try {
                if (position > this.element.innerText.length) {
                    console.log("ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR ERROR; ");
                    console.log("TExtComponent.setCaretPosition >length: " + position + " > " + this.element.innerText.length);
                }
                this.clearSelection();
                const range = document.createRange();
                if (this.element.childNodes[0]) {
                    range.setStart(this.element.childNodes[0], position);
                }
                else {
                    range.setStart(this.element, position);
                }
                range.collapse(true);
                window.getSelection().addRange(range);
                this.caretPosition = position;
                this.props.box.caretPosition = position;
            }
            catch (e) {
                console.log("TextComponent.setCaretPosition ERROR: " + e.toString());
            }
        };
        this.clearSelection = () => {
            window.getSelection().removeAllRanges();
        };
        this.subscribeToBoxEvents(props.box);
    }
    componentWillReceiveProps(nextProps) {
        this.subscribeToBoxEvents(nextProps.box);
    }
    componentDidMount() {
        LOGGER.info(this, "componentDidMount");
        this.element.setAttribute("contentEditable", "true");
        this.setCaretPosition(this.props.box.caretPosition);
        LOGGER.info(this, "componentDidMount caret: " + this.props.box.caretPosition);
        this.checkSelected();
    }
    componentDidUpdate() {
        LOGGER.info(this, "componentDidUpdate to [" + this.props.box.getText() + "]");
        LOGGER.info(this, "      caret [" + this.props.box.caretPosition + "]");
        this.props.box.update();
        LOGGER.info(this, "      caret [" + this.props.box.caretPosition + "]");
        this.setCaretPosition(this.props.box.caretPosition);
        this.checkSelected();
    }
    checkSelected() {
        const selectedBox = this.props.editor.selectedBox;
        const isSelected = !!this.props.box && !!selectedBox ? this.props.box.id === selectedBox.id : false;
        if (isSelected) {
            LOGGER.info(this, "!!!!!!!!!!!!!!!!!!!!!!!!!! SELECTED position " + this.caretPosition);
            this.element.focus();
            this.setCaretPosition(this.caretPosition);
        }
        else {
        }
    }
    render() {
        PiLogging_2.RENDER_LOG.info(this, "Text");
        const box = this.props.box;
        const styleClasses = classNames(Styles_1.STYLES.text, box.style);
        return (React.createElement("div", { id: this.props.box.id, className: styleClasses, ref: this.setElement, tabIndex: 0, onFocus: this.onFocus, onInput: this.onInput, onKeyDown: this.onKeyDown, onKeyPress: this.onKeyPress, onClick: this.onClick, onBlur: this.onBlur, "data-placeholdertext": box.placeHolder, spellCheck: false, onPaste: this.onPaste }, this.props.box.getText()));
    }
    newText(text, index, char) {
        return text.substring(0, index) + char + text.substring(index, text.length);
    }
};
TextComponent = __decorate([
    mobx_react_1.observer,
    __metadata("design:paramtypes", [Object])
], TextComponent);
exports.TextComponent = TextComponent;
//# sourceMappingURL=TextComponent.js.map