"use strict";
/*---------------------------------------------------------------------------------------------
 * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
 * See LICENSE.md in the project root for license terms and full copyright notice.
 *--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module AccuDraw
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.Calculator = void 0;
require("./Calculator.scss");
const classnames_1 = require("classnames");
const React = require("react");
const appui_abstract_1 = require("@itwin/appui-abstract");
const core_react_1 = require("@itwin/core-react");
const itwinui_react_1 = require("@itwin/itwinui-react");
const CalculatorEngine_1 = require("./CalculatorEngine");
const SquareButton_1 = require("./SquareButton");
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
const backspace_svg_1 = require("./backspace.svg");
/** @alpha */
class Calculator extends React.PureComponent {
    constructor(props) {
        super(props);
        this._mainDiv = React.createRef();
        this._equalsClicked = false;
        this._onValueButtonClick = (keyChar) => {
            const displayValue = this.props.engine.processValue(keyChar);
            this._mainDivFocus();
            this.setState({ displayValue });
        };
        this._onOperatorButtonClick = (operator) => {
            if (operator === CalculatorEngine_1.CalculatorOperator.Clear && this._equalsClicked)
                operator = CalculatorEngine_1.CalculatorOperator.ClearAll;
            const displayValue = this.props.engine.processOperator(operator);
            this._mainDivFocus();
            this.setState({ displayValue });
            if (operator === CalculatorEngine_1.CalculatorOperator.Equals)
                this._equalsClicked = true;
            else if (operator === CalculatorEngine_1.CalculatorOperator.ClearAll)
                this._equalsClicked = false;
        };
        this._handleOk = (_event) => {
            this._ok();
        };
        this._handleCancel = (_event) => {
            this._cancel();
        };
        this._handleKeyDown = (event) => {
            switch (event.key) {
                case "0":
                case "1":
                case "2":
                case "3":
                case "4":
                case "5":
                case "6":
                case "7":
                case "8":
                case "9":
                    this._onValueButtonClick(event.key);
                    break;
                case "a":
                case "A":
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.ClearAll);
                    break;
                case "c":
                case "C":
                case appui_abstract_1.SpecialKey.Clear:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Clear);
                    break;
                case appui_abstract_1.SpecialKey.Escape:
                    this._cancel();
                    break;
                case appui_abstract_1.SpecialKey.Backspace:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Backspace);
                    break;
                case "/":
                case appui_abstract_1.SpecialKey.Divide:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Divide);
                    break;
                case "*":
                case appui_abstract_1.SpecialKey.Multiply:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Multiply);
                    break;
                case "-":
                case appui_abstract_1.SpecialKey.Subtract:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Subtract);
                    break;
                case "+":
                case appui_abstract_1.SpecialKey.Add:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Add);
                    break;
                case ".":
                case appui_abstract_1.SpecialKey.Decimal:
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Decimal);
                    break;
                case "=":
                    this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Equals);
                    break;
                case appui_abstract_1.SpecialKey.Enter:
                    if (!this._equalsClicked)
                        this._onOperatorButtonClick(CalculatorEngine_1.CalculatorOperator.Equals);
                    this._ok();
                    break;
            }
        };
        let displayValue = "0";
        if (this.props.initialValue)
            displayValue = this.props.engine.processValue(this.props.initialValue.toString());
        this.state = {
            displayValue,
        };
    }
    _ok() {
        // istanbul ignore else
        if (this.props.onOk) {
            this.props.onOk(this.props.engine.result);
        }
        this._clearAll();
    }
    _cancel() {
        // istanbul ignore else
        if (this.props.onCancel) {
            this.props.onCancel();
        }
        this._clearAll();
    }
    _clearAll() {
        this.props.engine.clearAll();
        this._equalsClicked = false;
    }
    componentDidMount() {
        this._mainDivFocus();
    }
    _mainDivFocus() {
        if (this._mainDiv.current)
            this._mainDiv.current.focus();
    }
    render() {
        const { className, resultIcon, onOk, onCancel, initialValue, ...props } = this.props;
        const classNames = (0, classnames_1.default)("uifw-calculator", className);
        const topSection = resultIcon ? (React.createElement(core_react_1.IconInput, { containerClassName: "uifw-calculator-top-input", value: this.state.displayValue, readOnly: true, icon: resultIcon })) : (React.createElement(itwinui_react_1.Input, { value: this.state.displayValue, readOnly: true, size: "small" }));
        return (
        // The event handler is only being used to capture bubbled events
        // eslint-disable-next-line jsx-a11y/no-static-element-interactions
        React.createElement("div", { ...props, ref: this._mainDiv, tabIndex: -1, className: classNames, onKeyDown: this._handleKeyDown },
            React.createElement("div", { className: "uifw-calculator-top" }, topSection),
            React.createElement(CalculatorKeyPad, { onValueClick: this._onValueButtonClick, onOperatorClick: this._onOperatorButtonClick }),
            React.createElement("div", { className: "uifw-calculator-bottom-buttons" },
                React.createElement(itwinui_react_1.Button, { className: (0, classnames_1.default)("uifw-calculator-large-button", "uifw-calculator-ok-button"), styleType: "cta", onClick: this._handleOk },
                    React.createElement(core_react_1.Icon, { iconSpec: React.createElement(itwinui_icons_react_1.SvgCheckmark, null) })),
                React.createElement(itwinui_react_1.Button, { className: (0, classnames_1.default)("uifw-calculator-large-button", "uifw-calculator-cancel-button"), onClick: this._handleCancel },
                    React.createElement(core_react_1.Icon, { iconSpec: React.createElement(itwinui_icons_react_1.SvgRemove, null) })))));
    }
}
/** @internal */
Calculator.defaultProps = {
    engine: new CalculatorEngine_1.CalculatorEngine(),
};
exports.Calculator = Calculator;
class CalculatorKeyPad extends React.PureComponent {
    render() {
        const iconSpec = appui_abstract_1.IconSpecUtilities.createWebComponentIconSpec(backspace_svg_1.default);
        return (React.createElement("div", { className: (0, classnames_1.default)("uifw-calculator-button-grid") },
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.ClearAll, onClick: this.props.onOperatorClick }, "AC"),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Clear, onClick: this.props.onOperatorClick }, "C"),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Backspace, onClick: this.props.onOperatorClick },
                React.createElement("div", { className: "uifw-calculator-button-svg" },
                    React.createElement(core_react_1.Icon, { iconSpec: iconSpec }))),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Divide, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "\u00F7"),
            React.createElement(ValueButton, { keyChar: "7", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "8", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "9", onClick: this.props.onValueClick }),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Multiply, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "\u00D7"),
            React.createElement(ValueButton, { keyChar: "4", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "5", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "6", onClick: this.props.onValueClick }),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Subtract, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "\u2212"),
            React.createElement(ValueButton, { keyChar: "1", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "2", onClick: this.props.onValueClick }),
            React.createElement(ValueButton, { keyChar: "3", onClick: this.props.onValueClick }),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Add, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "+"),
            React.createElement(ValueButton, { keyChar: "0", onClick: this.props.onValueClick }),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.NegPos, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "\u00B1"),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Decimal, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "."),
            React.createElement(OperatorButton, { operator: CalculatorEngine_1.CalculatorOperator.Equals, onClick: this.props.onOperatorClick, className: "uifw-calculator-large-font" }, "="),
            React.createElement("span", null)));
    }
}
class ValueButton extends React.PureComponent {
    constructor() {
        super(...arguments);
        this._handleOnClick = (_event) => {
            this.props.onClick(this.props.keyChar);
        };
    }
    render() {
        const { className, keyChar, onClick, ...props } = this.props;
        const itemClassNames = (0, classnames_1.default)("uifw-calculator-item", className);
        return (React.createElement(SquareButton_1.SquareButton, { ...props, className: itemClassNames, onClick: this._handleOnClick }, keyChar));
    }
}
class OperatorButton extends React.PureComponent {
    constructor() {
        super(...arguments);
        this._handleOnClick = (_event) => {
            this.props.onClick(this.props.operator);
        };
    }
    render() {
        const { className, children, operator, onClick, ...props } = this.props;
        const itemClassNames = (0, classnames_1.default)("uifw-calculator-item", className);
        return (React.createElement(SquareButton_1.SquareButton, { ...props, className: itemClassNames, onClick: this._handleOnClick }, children));
    }
}
//# sourceMappingURL=Calculator.js.map