"use strict";
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 __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
var react_1 = __importDefault(require("react"));
var prop_types_1 = __importDefault(require("prop-types"));
var Confirm_1 = require("./popups/Confirm");
var DangerousHTML_1 = require("./DangerousHTML");
var index_en_US_1 = __importDefault(require("../../lang/common/index-en_US"));
var Wizard = /** @class */ (function (_super) {
    __extends(Wizard, _super);
    function Wizard(props, context) {
        var _this = _super.call(this, props, context) || this;
        // XXX: startSnapshotRecording
        _this.snapshotRecording = true;
        _this.state = {
            showSnapshotRestoreDialog: !!_this.getSnapshot(),
            currentStepIndex: 0,
            maxVisitedStepIndex: 0,
            errors: {}
        };
        _this.setCurrentStepIndex = function (index) {
            if (index >= _this.getSteps().length) {
                throw new RangeError('Current wizard step index ' +
                    _this.state.currentStepIndex +
                    ' is out of ranges - step not found');
            }
            _this.setState({
                currentStepIndex: index,
                maxVisitedStepIndex: Math.max(_this.state.maxVisitedStepIndex, index)
            });
        };
        _this.resetMaxVisitedStepIndex = function (index) {
            _this.setState({ maxVisitedStepIndex: Number(index) || 0 });
        };
        _this.goNext = function () {
            var nextStepIndex = _this.getEnabledSiblingStepIndex(1);
            if (nextStepIndex !== null) {
                _this.validateCurrentStep(function () {
                    _this.setCurrentStepIndex(nextStepIndex);
                }, nextStepIndex);
            }
            else {
                // eslint-disable-next-line
                console.error('Wizard has not following enabled steps - can not go next');
            }
        };
        _this.goBack = function () {
            var prevStepIndex = _this.getEnabledSiblingStepIndex(-1);
            if (prevStepIndex !== null) {
                _this.validateCurrentStep(function () {
                    _this.setCurrentStepIndex(prevStepIndex);
                }, prevStepIndex);
            }
            else {
                // eslint-disable-next-line
                console.error('Wizard has not previous enabled steps - can not go back');
            }
        };
        // XXX: inconsistency return - null (see getStepIndexById -1)
        _this.getEnabledSiblingStepIndex = function (direction) {
            var targetStep = null;
            var targetStepIndex = _this.state.currentStepIndex + direction;
            var steps = _this.getSteps();
            while (!targetStep) {
                targetStep = steps[targetStepIndex];
                if (targetStep.props.disabled) {
                    targetStepIndex += direction;
                    targetStep = null;
                    if (targetStepIndex > steps.length - 1 || targetStepIndex < 0) {
                        targetStepIndex = null;
                        break;
                    }
                }
            }
            return targetStepIndex;
        };
        _this.goToStep = function (id) {
            // XXX: RangeError within render
            var stepIndex = _this.getStepIndexById(id);
            if (stepIndex === -1) {
                throw new RangeError('Wizard step [' + id + '] is not exists');
            }
            _this.validateCurrentStep(function () {
                _this.setCurrentStepIndex(stepIndex);
            }, stepIndex);
        };
        _this.isFirstStep = function (id) {
            return _this.getStepIndexById(id) === 0;
        };
        _this.isLastStep = function (id) {
            var stepIndex = _this.getStepIndexById(id);
            var lastStepIndex = _this.getSteps().length - 1;
            return stepIndex >= 0 && stepIndex === lastStepIndex;
        };
        _this.getCurrentStepIndex = function () {
            return _this.state.currentStepIndex;
        };
        _this.getMaxVisitedStepIndex = function () {
            return _this.state.maxVisitedStepIndex;
        };
        _this.stepOnLeaveHandlers = {};
        _this.addStepOnLeaveHandler = function (id, func) {
            _this.stepOnLeaveHandlers[id] = func;
        };
        return _this;
    }
    Object.defineProperty(Wizard, "confirmWizardRestore", {
        get: function () {
            return index_en_US_1.default.CONFIRM_WIZARD_RESTORE;
        },
        enumerable: true,
        configurable: true
    });
    Wizard.prototype.getChildContext = function () {
        return { wizard: this };
    };
    Wizard.prototype.componentDidUpdate = function () {
        if (!this.state.showSnapshotRestoreDialog) {
            this.saveSnapshot();
        }
    };
    /**
     * @abstract
     */
    Wizard.prototype.getSnapshotKey = function () {
        return null;
    };
    /**
     * @abstract
     */
    Wizard.prototype.getSnapshotValue = function () {
        return null;
    };
    /**
     * @abstract
     */
    Wizard.prototype.restoreSnapshot = function (snapshot) { };
    Wizard.prototype.saveSnapshot = function () {
        var key = this.getSnapshotKey();
        var value = this.getSnapshotValue();
        if (key && value && this.snapshotRecording) {
            if (window.localStorage) {
                window.localStorage.setItem(key, JSON.stringify(value));
            }
        }
    };
    Wizard.prototype.getSnapshot = function () {
        var key = this.getSnapshotKey();
        return key && window.localStorage
            ? window.localStorage.getItem(this.getSnapshotKey())
            : null;
    };
    Wizard.prototype.getRestoreConfirmationText = function () {
        return react_1.default.createElement(DangerousHTML_1.DangerousHTML, null, Wizard.confirmWizardRestore);
    };
    Wizard.prototype.readSnapshot = function () {
        return JSON.parse(this.getSnapshot());
    };
    Wizard.prototype.resetSnapshot = function (stopRecording) {
        if (stopRecording === void 0) { stopRecording = true; }
        var key = this.getSnapshotKey();
        if (stopRecording) {
            this.stopSnapshotRecording();
        }
        return key && window.localStorage
            ? window.localStorage.removeItem(this.getSnapshotKey())
            : null;
    };
    Wizard.prototype.startSnapshotRecording = function () {
        this.snapshotRecording = true;
    };
    Wizard.prototype.stopSnapshotRecording = function () {
        this.snapshotRecording = false;
    };
    Wizard.prototype.getSteps = function () {
        return [];
    };
    Wizard.prototype.getStepIndexById = function (id) {
        return this.getSteps().findIndex(function (step) { return step.props.id === id; });
    };
    Wizard.prototype.validateCurrentStep = function (onSuccess, targetStepIndex) {
        var _this = this;
        var currentStep = this.getSteps()[this.state.currentStepIndex];
        var isValidationNeeded = targetStepIndex > this.state.currentStepIndex;
        var successHandler = function () {
            var stepOnLeaveHandler = _this.stepOnLeaveHandlers[currentStep.props.id];
            if (stepOnLeaveHandler) {
                stepOnLeaveHandler().then(onSuccess.bind(_this));
            }
            else {
                onSuccess.call(_this);
            }
        };
        if (currentStep.props.validation && isValidationNeeded) {
            this.setState({ errors: {} });
            currentStep.props
                .validation(this.state)
                .then(successHandler)
                .catch(function (errors) {
                _this.setState({ errors: errors });
            });
        }
        else {
            successHandler();
        }
    };
    Wizard.prototype.render = function () {
        var _this = this;
        if (this.state.showSnapshotRestoreDialog) {
            return (react_1.default.createElement(Confirm_1.Confirm, { noAutoClose: true, submitAction: function (e) {
                    var snapshot = _this.readSnapshot();
                    _this.restoreSnapshot(snapshot);
                    _this.setState({ showSnapshotRestoreDialog: false });
                }, cancelAction: function (e) { return _this.setState({ showSnapshotRestoreDialog: false }); } }, this.getRestoreConfirmationText()));
        }
        return this.getSteps()[this.state.currentStepIndex];
    };
    Wizard.childContextTypes = {
        wizard: prop_types_1.default.object
    };
    return Wizard;
}(react_1.default.Component));
exports.Wizard = Wizard;
//# sourceMappingURL=Wizard.js.map