import { BarGraphDirection } from '../model';
import { ReadableElement } from './base/readable-element';
import { calculatePercent } from './shared/math-utils';
import { VariableUtil } from '../utils/variable-util';
import { VariableValueType } from '../model/shared/condition/variable-value-type';
export class BarGraphElement extends ReadableElement {
    constructor(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId) {
        super(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId);
        this.defaultBarColor = '#6fd149';
        this.defaultUpperLimitColor = '#ff4448';
        this.defaultLowerLimitColor = '#0f60e8';
        this.barText = '';
        this.valueObj = {};
        this.isNeedUpdateScale = false;
        this.needAddNumber = 0;
        this.needInitTransform = true;
        if ((this.model.minValueType === VariableValueType.Constant && this.model.maxValueType === VariableValueType.Variable)
            || this.model.maxValueType === VariableValueType.Constant && this.model.minValueType === VariableValueType.Variable) {
            this.isNeedUpdateScale = true;
            this.updateScale();
            this.isNeedUpdateScale = false;
        }
        this.$barRect = this.$element.find('rect');
        this.$barText = this.$element.find('text[id="text"]').last();
        if (this.model.version && this.model.version >= 1) {
            const backgroundColor = this.model.backgroundColor ? this.model.backgroundColor : 'transparent';
            this.barElement = this.$element.children(`path[fill='${backgroundColor}']`);
            this.defaultTransform = this.barElement.attr('transform');
            this.$barRect.attr('transform', this.defaultTransform);
        }
        setTimeout(() => {
            if (this.model.maxValueType !== VariableValueType.Variable || this.model.minValueType !== VariableValueType.Variable) {
                this.initFrameNode();
            }
        });
    }
    get readVariableName() {
        if (!this.model) {
            throw new Error('Model cannot be null');
        }
        if (null == this.model.version || this.model.version < 2) {
            return this.model.variableName;
        }
        else {
            const variable = this.model.readVariable;
            if (!variable) {
                return undefined;
            }
            return VariableUtil.getConvertedVariableName(this.variableStore, variable);
        }
    }
    initTransform() {
        if (this.needAddNumber <= 3)
            return;
        this.$element[0].childNodes.forEach((node, index) => {
            const matrixE = node.transform.baseVal[0].matrix.e;
            node.transform.baseVal[0].matrix.e = matrixE + (this.needAddNumber - 3) * 7;
            if (node.nodeName === 'g') {
                const nodeValue = node.attributes['clip-path'].value.replace('url(#', '').replace(')', '');
                const rootNode = node.parentNode.parentNode.parentElement;
                const clipPath = $(rootNode).find(`clipPath[id="${nodeValue}"]`);
                const demoPath = clipPath.find('path');
                const dValues = demoPath.attr('d').split(',');
                const retValues = [];
                dValues.forEach((line) => {
                    const values = [];
                    line.split(' ').forEach((item) => {
                        const nItem = Number(item);
                        if (!isNaN(nItem) && item < 100) {
                            item = nItem > 0 ? nItem + (this.needAddNumber - 3) * 7 : nItem - (this.needAddNumber - 3) * 7;
                        }
                        values.push(item);
                    });
                    retValues.push(values.join(' '));
                });
                demoPath.attr('d', retValues.join(','));
            }
            else if (index === this.$element[0].childNodes.length - 1) {
                this.defaultTransform = node.attributes['transform'].value;
            }
        });
    }
    initFrameNode() {
        const arcPath = Snap(this.$element[0]);
        const b = arcPath.getBBox(true);
        const width = this.needAddNumber <= 3 ? b.width : b.width + (this.needAddNumber - 3) * 7;
        this.rootElement.append('rect').attr('id', 'StateFrame').attr('width', width).attr('height', b.height).attr('fill', 'transparent');
    }
    updateValueObj(value, variableName) {
        var _a, _b, _c;
        if (((_a = this.model.readVariable) === null || _a === void 0 ? void 0 : _a.name) === variableName) {
            this.isNeedUpdateScale = false;
            this.valueObj.value = value;
        }
        if (((_b = this.model.minVariable) === null || _b === void 0 ? void 0 : _b.name) === variableName) {
            this.isNeedUpdateScale = true;
            this.valueObj.min = value;
        }
        if (((_c = this.model.maxVariable) === null || _c === void 0 ? void 0 : _c.name) === variableName) {
            this.isNeedUpdateScale = true;
            this.valueObj.max = value;
        }
    }
    updateScale() {
        if (!this.isNeedUpdateScale) {
            return;
        }
        const textElements = this.$element.find('g:first > text');
        let min = this.model.minValueType ? this.valueObj.min : this.model.min;
        let max = this.model.maxValueType ? this.valueObj.max : this.model.max;
        min = Number(min);
        max = Number(max);
        if (isNaN(min) || isNaN(max)) {
            min = BarGraphElement.DEFAULT_MIN_VALUE;
            max = BarGraphElement.DEFAULT_MAX_VALUE;
        }
        if (this.model.maxValueType === VariableValueType.Variable && this.model.minValueType === VariableValueType.Variable) {
            this.needAddNumber = max.toString().length > min.toString().length ? max.toString().length : min.toString().length;
            if (this.needInitTransform) {
                this.initTransform();
                this.initFrameNode();
                this.needInitTransform = false;
            }
        }
        const avgSacle = ((max - min) / this.model.masterDivisionNumber).toFixed(5);
        for (let i = 0; i < textElements.length; i++) {
            const text = textElements[i];
            if (!text.innerHTML) {
                continue;
            }
            let sacleValue = ((Number(avgSacle) * i) + min).toFixed(0);
            // 整数位和小数位格式化；
            if (this.model.fractionDigits > 0) {
                sacleValue = (sacleValue / Math.pow(10, this.model.fractionDigits)).toFixed(this.model.fractionDigits);
            }
            if (!isNaN(sacleValue)) {
                text.innerHTML = sacleValue;
                if (this.model.minValueType !== VariableValueType.Constant || this.model.maxValueType !== VariableValueType.Constant) {
                    // FLEXCLOUD-2619 刻度未对齐问题
                    let translateX = 0;
                    const sacleLen = sacleValue.toString().length;
                    switch (sacleLen) {
                        case 1:
                            translateX = 13;
                            break;
                        case 2:
                            translateX = 7;
                            break;
                        case 3:
                            translateX = this.model.fractionDigits ? 5 : 0;
                            break;
                        default:
                            if (sacleLen > 3 && this.needAddNumber > 3) {
                                translateX = -(sacleLen - 3) * 7;
                            }
                            break;
                    }
                    text.transform.baseVal[0].matrix.e = translateX;
                }
            }
        }
    }
    updateVariableValue(value, variableName) {
        this.updateValueObj(value, variableName);
        this.updateScale();
        const variableValue = Number(this.valueObj.value);
        let maxValue = this.model.maxValueType ? this.valueObj.max : this.model.max;
        let minValue = this.model.minValueType ? this.valueObj.min : this.model.min;
        minValue = Number(minValue);
        maxValue = Number(maxValue);
        if (isNaN(minValue) || isNaN(maxValue)) {
            minValue = BarGraphElement.DEFAULT_MIN_VALUE;
            maxValue = BarGraphElement.DEFAULT_MAX_VALUE;
        }
        if (isNaN(variableValue)) {
            return;
        }
        const useAlarmLimit = this.model.useAlarmLimit;
        const useAlarmUpperLimit = null != this.model.upperLimit;
        const useAlarmLowerLimit = null != this.model.lowerLimit;
        let barColor = this.model.barColor;
        const upperLimitColor = this.model.upperLimitColor;
        const lowerLimitColor = this.model.lowerLimitColor;
        const percentageFont = this.model.percentageFont;
        let box;
        if (this.model.version && this.model.version >= 1) {
            box = this.barElement[0].getBBox();
        }
        else {
            box = this.$barRect.parent()[0].getBBox();
        }
        const percent = calculatePercent(minValue, maxValue, variableValue);
        let translateY = 0;
        if (this.model.direction === BarGraphDirection.DownToUp || this.model.direction === BarGraphDirection.LeftToRight) {
            translateY = box.height * (1 - percent);
        }
        if (!barColor) {
            barColor = this.defaultBarColor;
        }
        if (useAlarmLimit) {
            if (useAlarmUpperLimit && variableValue > +this.model.upperLimit) {
                if (upperLimitColor) {
                    barColor = upperLimitColor;
                }
                else {
                    barColor = this.defaultUpperLimitColor;
                }
            }
            else if (useAlarmLowerLimit && variableValue < +this.model.lowerLimit) {
                if (lowerLimitColor) {
                    barColor = lowerLimitColor;
                }
                else {
                    barColor = this.defaultLowerLimitColor;
                }
            }
        }
        this.$barRect.attr('height', box.height * percent);
        this.$barRect.attr('width', box.width);
        this.$barRect.attr('fill', barColor);
        if (this.model.version && this.model.version >= 1) {
            this.$barRect.attr('transform', this.defaultTransform + ` translate(0,${translateY})`);
        }
        else {
            this.$barRect.attr('transform', `translate(0,${translateY})`);
        }
        this.barText = (percent * 100).toFixed(0) + '%';
        this.$barText.text(this.barText);
        if (percentageFont) {
            this.$barText.attr('font-family', 'Microsoft YaHei');
            this.$barText.attr('font-size', percentageFont.fontSize + '');
            this.$barText.attr('fill', percentageFont.color);
            if (percentageFont.isBold) {
                this.$barText.attr('font-weight', 'bold');
            }
            if (percentageFont.isItalic) {
                this.$barText.attr('font-style', 'italic');
            }
            if (percentageFont.isUnderline) {
                this.$barText.attr('text-decoration', 'underline');
            }
        }
    }
}
BarGraphElement.DEFAULT_MIN_VALUE = 0;
BarGraphElement.DEFAULT_MAX_VALUE = 100;
