import { forEach } from 'lodash';
import { VariableStateEnum } from '../../communication';
import { ConditionalDynamicDisplayElement } from './conditional-dynamic-display-element';
import { State } from '../../model';
export class StateControlElement extends ConditionalDynamicDisplayElement {
    constructor(element, permissionChecker, variableCommunicator, variableStore, localization, signalRAppId) {
        super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
        this.localization = localization;
        this.isEnable = true;
        this.elementStates = [];
    }
    initState() {
        if (!this.elementStates.length) {
            return;
        }
        this.state = State.Loading;
        this.loadStateData(this.state);
    }
    updateElementStates(newElementStates) {
        forEach(this.elementStates, elementState => {
            forEach(newElementStates, newElementState => {
                if (elementState.variableName === newElementState.variableName) {
                    elementState.state = newElementState.state;
                }
            });
        });
        this.changeStates();
    }
    addElementState(newElementState) {
        let hasVariable = false;
        forEach(this.elementStates, elementState => {
            if (elementState.variableName === newElementState.variableName) {
                hasVariable = true;
            }
        });
        if (!hasVariable) {
            this.elementStates.push(newElementState);
        }
    }
    changeStates() {
        this.state = State.Normal;
        forEach(this.elementStates, elementState => {
            const currentState = this.getState(elementState);
            this.changeState(currentState);
        });
        if (this.state === State.Normal) {
            if (!this.isEnable) {
                this.state = State.Disable;
            }
        }
        this.loadStateData(this.state);
    }
    getState(elementState) {
        let currentState = State.Loading;
        switch (elementState.state) {
            case VariableStateEnum.Offline:
                currentState = State.Offline;
                break;
            case VariableStateEnum.Unbind:
                currentState = State.Unbind;
                break;
            case VariableStateEnum.DataNormal:
                currentState = State.Normal;
                break;
            case VariableStateEnum.Abnormal:
                currentState = State.Abnormal;
                break;
        }
        return currentState;
    }
    changeState(state) {
        switch (state) {
            case State.Unbind:
                this.state = State.Unbind;
                break;
            case State.Offline:
                if (this.state !== State.Unbind) {
                    this.state = State.Offline;
                }
                break;
            case State.Loading:
                if (this.state !== State.Unbind && this.state !== State.Offline) {
                    this.state = State.Loading;
                }
                break;
            case State.Abnormal:
                if (this.state !== State.Unbind && this.state !== State.Offline && this.state !== State.Loading) {
                    this.state = State.Abnormal;
                }
                break;
        }
    }
    loadStateData(state) {
        if (state === this.preState) {
            return;
        }
        this.preState = state;
        if (this.state === State.Normal) {
            this.clearTip();
            return;
        }
        let url = '';
        let title = '';
        let stroke = '';
        switch (state) {
            case State.Offline:
                url = 'assets/img/offline.svg';
                title = this.localization.offline;
                stroke = '#999999';
                break;
            case State.Unbind:
                url = 'assets/img/unbind.svg';
                title = this.localization.unbind;
                stroke = '#586e7c';
                break;
            case State.Abnormal:
                url = 'assets/img/abnormal.svg';
                title = this.localization.abnormal;
                stroke = '#f6a520';
                break;
            case State.Disable:
                url = 'assets/img/disabled.svg';
                title = this.localization.disable;
                stroke = '#ff4444';
                break;
            default:
                url = 'assets/img/loading.svg';
                title = this.localization.loading;
                stroke = '#226abc';
                break;
        }
        this.setState(url, title, stroke);
    }
    setState(url, title, stroke) {
        this.clearTip();
        if (!this.currentRect) {
            this.currentRect = this.$element.find('rect#StateFrame').first();
        }
        if (!this.currentRect.length) {
            return;
        }
        const document = this.$element[0].ownerDocument;
        const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
        if (imgObj) {
            const currentRectElement = this.currentRect[0];
            let x = Number(currentRectElement.getAttribute('width')) - 20;
            const currentRectX = currentRectElement.getAttribute('x');
            if (currentRectX !== null) {
                x += Number(currentRectX);
            }
            currentRectElement.setAttribute('stroke', stroke);
            currentRectElement.setAttribute('stroke-opacity', '0.5');
            imgObj.href.baseVal = url;
            imgObj.setAttributeNS(null, 'id', 'StateImage');
            imgObj.setAttributeNS(null, 'x', x.toString());
            imgObj.setAttributeNS(null, 'y', '0');
            imgObj.setAttributeNS(null, 'height', '20px');
            imgObj.setAttributeNS(null, 'width', '20px');
            const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
            const text = document.createTextNode(title);
            titleElement.appendChild(text);
            imgObj.appendChild(titleElement);
            this.$element.append(imgObj);
        }
    }
    clearTip() {
        if (!this.currentRect) {
            this.currentRect = this.$element.find('rect#StateFrame').first();
        }
        if (!this.currentRect.length) {
            return;
        }
        const currentRectElement = this.currentRect[0];
        const stroke = currentRectElement.getAttribute('stroke');
        if (stroke) {
            currentRectElement.removeAttribute('stroke');
        }
        this.$element.find('image#StateImage').remove();
    }
}
