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 __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
import { Component, Inject, Output } from '@angular/core';
import { LOCALIZATION } from '../../localization';
import { DataTypeService } from '../../utils/data-type/data-type.service';
import { FractionDigitService } from '../../utils/fraction-digit.service';
import { NumericalOperationService } from '../../utils/numerical-operation.service';
import { isNil } from 'lodash';
import { BsModalRef } from 'ngx-bootstrap/modal';
let WriteValueModalComponent = class WriteValueModalComponent {
    constructor(localization, dataTypeService, fractionDigitService, numericalOperationService, bsModalRef) {
        this.localization = localization;
        this.dataTypeService = dataTypeService;
        this.fractionDigitService = fractionDigitService;
        this.numericalOperationService = numericalOperationService;
        this.bsModalRef = bsModalRef;
        this.writeValueRangeText = '';
        this.isSubmitting = false;
    }
    get invalidErrorText() {
        return this.localization.loadFailed;
    }
    ngOnInit() {
        this.initData(this.args);
        this.validate();
    }
    initData(option) {
        this.variableName = option.variableName;
        this.dataType = option.dataType;
        this.fBoxDataType = option.fBoxDataType;
        this.integerDigits = option.integerDigits ? option.integerDigits : 0;
        this.fractionDigits = option.fractionDigits ? option.fractionDigits : 0;
        this.valueType = this.dataTypeService.getValueType(option.version, option.dataType);
        this.pattern = this.dataTypeService.getValuePattern(option.version, option.dataType);
        this.numericalOperation = option.numericalOperation;
        this.enableNumericalOperation = this.numericalOperation.enableNumericalOperation ?
            this.numericalOperation.enableNumericalOperation : false;
        this.value = '';
        if (this.args.enableDataParsed) {
            this.setValueRangeAccordToDataParsed(option);
        }
        else {
            this.writeMaxValue = this.dataTypeService.getMaxValue(option.version, this.dataType, this.fBoxDataType);
            this.writeMinValue = this.dataTypeService.getMinValue(option.version, this.dataType, this.fBoxDataType);
        }
        this.writeValueRangeText = this.getWriteValueRangeText();
    }
    setValueRangeAccordToDataParsed(option) {
        if (this.dataTypeService.isFloat(option.version, this.dataType) || this.enableNumericalOperation) {
            this.maxValueLimit = this.dataTypeService.getMaxValue(option.version, this.dataType, this.fBoxDataType);
            this.minValueLimit = this.dataTypeService.getMinValue(option.version, this.dataType, this.fBoxDataType);
            this.numericalLowerLimit = this.numericalOperation.numericalLowerLimit;
            this.numericalUpperLimit = this.numericalOperation.numericalUpperLimit;
        }
        else {
            this.maxValueLimit = +this.fractionDigitService.movePoint(this.dataTypeService.getMaxValue(option.version, this.dataType, this.fBoxDataType), -this.fractionDigits);
            this.minValueLimit = +this.fractionDigitService.movePoint(this.dataTypeService.getMinValue(option.version, this.dataType, this.fBoxDataType), -this.fractionDigits);
            this.numericalLowerLimit = +this.fractionDigitService.movePoint(this.numericalOperation.numericalLowerLimit, -this.fractionDigits);
            this.numericalUpperLimit = +this.fractionDigitService.movePoint(this.numericalOperation.numericalUpperLimit, -this.fractionDigits);
        }
        const minValue = this.numericalOperationService.getWriteMinValue(this.minValueLimit, this.numericalOperation);
        const maxValue = this.numericalOperationService.getWriteMaxValue(this.maxValueLimit, this.numericalOperation);
        const lowerLimitValue = this.numericalOperationService.getWriteMinValue(this.numericalLowerLimit, this.numericalOperation);
        const upperLimitValue = this.numericalOperationService.getWriteMaxValue(this.numericalUpperLimit, this.numericalOperation);
        const realMinValue = minValue < maxValue ? minValue : maxValue;
        const realMaxValue = minValue < maxValue ? maxValue : minValue;
        const realLowerLimitValue = lowerLimitValue < upperLimitValue ? lowerLimitValue : upperLimitValue;
        const realUpperLimitValue = lowerLimitValue < upperLimitValue ? upperLimitValue : lowerLimitValue;
        this.writeMinValue = realMinValue > realLowerLimitValue ? realMinValue : realLowerLimitValue;
        this.writeMaxValue = realMaxValue < realUpperLimitValue ? realMaxValue : realUpperLimitValue;
    }
    getWriteValueRangeText() {
        let minValue = '';
        let maxValue = '';
        if (this.dataTypeService.isHexOrBinaryType(this.args.version, this.dataType)) {
            minValue = this.writeMinValue.toString(16);
            maxValue = this.writeMaxValue.toString(16);
        }
        else {
            if (this.args.enableDataParsed && this.fractionDigits > 0) {
                minValue = this.writeMinValue.toFixed(this.fractionDigits).toString();
                maxValue = this.writeMaxValue.toFixed(this.fractionDigits).toString();
            }
            else {
                minValue = this.writeMinValue.toString();
                maxValue = this.writeMaxValue.toString();
            }
        }
        return minValue + '~' + maxValue;
    }
    save() {
        this.isSubmitting = true;
        let value = this.value;
        const showValue = this.value;
        if (this.args.enableDataParsed) {
            if (this.enableNumericalOperation) {
                value = this.numericalOperationService.getWriteValue(this.args.version, this.value, this.numericalOperation, this.dataType, this.fractionDigits);
            }
            else {
                value = this.formatWriteValue();
            }
        }
        // 处理系统变量"当前语种ID"
        if (this.variableName === '当前语种ID') {
            this.handleCurrentLanguageIdSave(value);
            return;
        }
        if (!this.args.releasedVariableService) {
            this.onClosed({
                value: value,
                showValue: showValue,
                enableNumericalOperation: false,
                isNumericalOperation: this.isNumericalOperation,
                variableRwType: 6
            });
            return;
        }
        this.args.releasedVariableService.getVariableWithValueTransform(this.variableName).subscribe(result => {
            const valueTransform = JSON.parse(result.valueTransform);
            if ((valueTransform === null || valueTransform === void 0 ? void 0 : valueTransform.Type) !== 0) {
                this.isNumericalOperation = true;
            }
            this.onClosed({
                value: value,
                showValue: showValue,
                enableNumericalOperation: this.enableNumericalOperation,
                isNumericalOperation: this.isNumericalOperation,
                variableRwType: result.variableRwType
            });
        });
    }
    /**
     * 处理"当前语种ID"系统变量的保存
     */
    handleCurrentLanguageIdSave(value) {
        if (!this.args.guiContext || !this.args.guiContext.updateCurrentLanguageId) {
            this.showValidationErrorInfo(this.localization.loadFailed);
            this.isSubmitting = false;
            return;
        }
        // 转换为数字类型
        const languageId = value === '' || value == null ? null : Number(value);
        // 调用 GuiContext 的语种切换方法
        this.args.guiContext.updateCurrentLanguageId(languageId).then(() => {
            // 语种切换成功，调用 onClosed 回调，让数字显示元件也能更新
            this.onClosed({
                value: value,
                showValue: value,
                enableNumericalOperation: false,
                isNumericalOperation: false,
                variableRwType: 6
            });
        }).catch(() => {
            this.showValidationErrorInfo(this.localization.loadFailed);
            this.isSubmitting = false;
        });
    }
    close() {
        this.bsModalRef.hide();
    }
    validate(event = null) {
        if (event && event.keyCode === 13 && !this.validationError) {
            this.save();
            return;
        }
        // 校验数值必填
        if (null == this.value || '' === this.value.trim()) {
            return this.showValidationErrorInfo(this.localization.numericalValueRequired);
        }
        // 校验格式
        if (!new RegExp(this.pattern).test(this.value)) {
            return this.showValidationErrorInfo(this.localization.invalidNumericalValue);
        }
        // 校验小数点位数
        if (!this.enableNumericalOperation && this.dataTypeService.isSupportFractionDigit(this.args.version, this.dataType)
            && this.getFractionDigits(this.value) > this.fractionDigits) {
            return this.showValidationErrorInfo(`${this.localization.fractionDigitsMustLessThan}${this.fractionDigits}`);
        }
        // 校验负号
        if (isNil(this.args.version) || (!isNil(this.args.version) && this.args.version < 5)) {
            if (!this.enableNumericalOperation && !this.dataTypeService.isSignedType(this.args.version, this.dataType) && this.value.startsWith('-')) {
                return this.showValidationErrorInfo(this.localization.canNotBeNegative);
            }
        }
        if (this.dataTypeService.isBinaryType(this.args.version, this.dataType) || this.dataTypeService.isHexType(this.args.version, this.dataType)) {
            // 校验数值最大长度
            const valueMaxLength = this.dataTypeService.getValueMaxLength(this.args.version, this.dataType, this.fBoxDataType);
            const maxLength = this.integerDigits ? Math.min(this.integerDigits, valueMaxLength) : valueMaxLength;
            if (this.value.length > maxLength) {
                return this.showValidationErrorInfo(this.localization.numericalValueTooLong);
            }
        }
        let transportValue;
        if (this.dataTypeService.isHexOrBinaryType(this.args.version, this.dataType)) {
            transportValue = this.dataTypeService.formatToDecimal(this.args.version, this.value, this.dataType);
        }
        else {
            transportValue = Number(this.value);
        }
        if (Number(transportValue) > this.writeMaxValue || Number(transportValue) < this.writeMinValue) {
            return this.showValidationErrorInfo(this.localization.valueOutOfRange);
        }
        // 没有错误则隐藏错误框
        this.hideValidationErrorInfo();
    }
    showValidationErrorInfo(errorText) {
        this.validationError = true;
        this.validationErrorText = errorText;
    }
    hideValidationErrorInfo() {
        this.validationError = false;
        this.validationErrorText = '';
    }
    getFractionDigits(number) {
        if (number && number.indexOf('.') > 0) {
            return number.split('.')[1].length;
        }
        return 0;
    }
    /**
     * 格式化写入的值
     * 因为有小数点的数值类型，会被按照小数点位数移位，所以需要在修改前右移小数点位数
     */
    formatWriteValue() {
        if (this.dataTypeService.isSupportFractionDigit(this.args.version, this.dataType) &&
            !this.dataTypeService.isFloat(this.args.version, this.dataType) && this.fractionDigits) {
            return this.fractionDigitService.movePoint(this.value, this.fractionDigits);
        }
        if (this.dataTypeService.isSupportNumericalOperation(this.args.version, this.dataType)) {
            this.value = Number(this.value).toString();
        }
        return this.value;
    }
};
__decorate([
    Output(),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [])
], WriteValueModalComponent.prototype, "invalidErrorText", null);
WriteValueModalComponent = __decorate([
    Component({
        selector: 'writeValueModal',
        template: "<form #writeValueForm=\"ngForm\" novalidate (ngSubmit)=\"save()\" bs-modal-drag> <div class=\"modal-header\"> <h4 class=\"modal-title\"> <span>{{localization.setting}}</span> <span>{{variableName}}</span> </h4> <button type=\"button\" class=\"close pull-right\" aria-label=\"Close\" (click)=\"close()\"> <span aria-hidden=\"true\">&times;</span> </button> </div> <div class=\"modal-body\"> <span class=\"write-value-range\">{{localization.writeValueRange}}：</span> <div class=\"write-value-range\"> {{writeValueRangeText}} <span *ngIf=\"valueType\">({{valueType}})</span> </div> <input type=\"text\" name=\"valueInput\" autoFocus class=\"form-control write-value\" [(ngModel)]=\"value\" (keyup)=\"validate($event)\" autocomplete=\"off\"> <span class=\"help-block text-danger\" [hidden]=\"!validationError\">{{validationErrorText}}</span> </div> <div class=\"modal-footer\"> <button type=\"submit\" class=\"btn md-skip btn-primary btn-block\" [disabled]=\"validationError || isSubmitting\"> <ng-container *ngIf=\"!isSubmitting\">{{localization.submit}}</ng-container> <ng-container *ngIf=\"isSubmitting\">{{localization.submitting}}</ng-container> </button> </div> </form> ",
        styles: [".modal-header { padding: 10px; border-color: transparent; } .modal-body { position: relative; padding: 0px 5px !important; padding-top: 10px !important; } .modal-title { display: unset; margin-left: -6px; font-size: 16px !important; } .form-control { margin: 0 5%; float: none; width: 90%; } .modal-footer { padding: 10px 4px 20px 5px !important; text-align: right; border-color: transparent; } .text-danger { display: block; color: #ed6b75; font-size: 14px; margin: 5px 0px 0px 15px; } .btn-primary { background-color: #3B97FC; border-color: #3B97FC; padding: 5px 30px; width: 90%; margin: 0 5%; height: 32px; } .write-value-range { color: #7f939e; font-size: 14px; margin-left: 15px; } .write-value { padding-left: 8px; margin-left: 16px; height: 32px; } "]
    }),
    __param(0, Inject(LOCALIZATION)),
    __metadata("design:paramtypes", [Object, DataTypeService,
        FractionDigitService,
        NumericalOperationService,
        BsModalRef])
], WriteValueModalComponent);
export { WriteValueModalComponent };
