import { EventEmitter } from '@angular/core';
import { each } from 'lodash';
import { BitConditonLogic } from '../../model';
import { VariableStateEnum, VariableValue, VariableState } from '../../communication';
import { CurrentStateIdValue } from './current-stateId-value';
import { Binary } from '../../model/shared/binary';
import { VariableUtil } from '../../utils/variable-util';
import { VariableDefinition } from '../../communication/variable/variable-definition';
export class BitIndicatorLightOperator {
    constructor(settings, states, variableCommunicator, variableStore) {
        this.settings = settings;
        this.variableCommunicator = variableCommunicator;
        this.variableStore = variableStore;
        this.currentStateIdChanged = new EventEmitter();
        if (!this.settings) {
            throw new Error('settings cannot be null');
        }
        each(states, state => {
            const condition = state.condition;
            if (!condition) {
                throw new Error('Invalid bit condition.');
            }
            switch (+condition.logic) {
                case BitConditonLogic.Off:
                    if (this.offStateId) {
                        throw new Error('Dumplicate off state.');
                    }
                    this.offStateId = state.id;
                    break;
                case BitConditonLogic.On:
                    if (this.onStateId) {
                        throw new Error('Dumplicate on state.');
                    }
                    this.onStateId = state.id;
                    break;
                default:
                    throw new Error(`Unknown BitConditonLogic:${condition.logic}`);
            }
        });
    }
    get variableName() {
        const variableName = new VariableDefinition(this.settings.variableName, this.settings.variableGroupName, this.settings.dataSourceCode, this.settings.variableVersion);
        return VariableUtil.getConvertedVariableName(this.variableStore, variableName);
    }
    requestData(appId) {
        if (this.variableName) {
            this.variableCommunicator.subscribeVariableState(this.variableName).subscribe(variableStete => {
                if (variableStete.state === VariableStateEnum.Normal) {
                    this.requestCurrentSateIdValue(this.variableCommunicator, appId);
                }
                else {
                    this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, variableStete.state)));
                }
            });
        }
    }
    requestCurrentSateIdValue(variableCommunicator, appId = '') {
        variableCommunicator.openVariable(this.variableName, appId).subscribe(value => {
            if (value.state === VariableStateEnum.DataNormal) {
                if (this.settings.isBitwiseIndex) {
                    const maxBitIndex = 31;
                    this.binary = new Binary(value.value, maxBitIndex + 1);
                    const newValue = new VariableValue(value.variableName, value.state, Number(this.binary.convertToBinary().substr(maxBitIndex - this.settings.bitIndex, 1)));
                    this.currentStateId = !newValue.value ? this.offStateId : this.onStateId;
                    this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, value.state), this.currentStateId));
                }
                else {
                    this.currentStateId = !value.value ? this.offStateId : this.onStateId;
                    this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, value.state), this.currentStateId));
                }
            }
            else {
                delete this.currentStateId;
                this.currentStateIdChanged.emit(new CurrentStateIdValue(new VariableState(this.variableName, value.state)));
            }
        });
    }
}
