import { each, forEach } from 'lodash';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export class PerViewVariableCommunicator {
    constructor(variableCommunicator) {
        this.observers = new Map();
        this.variableValuesChangedSubscriptions = new Array();
        this.variableStatesChangedSubscription = new Array();
        this._rawVariableCommunicator = variableCommunicator;
    }
    openVariable(variableName, appId) {
        return this.openVariables([variableName], appId).pipe(map(values => values[0]));
    }
    openVariables(variableNames, appId = '') {
        return new Observable(subscriber => {
            each(variableNames, variableName => {
                if (!this.observers.has(variableName)) {
                    this.observers.set(variableName, []);
                }
                this.observers.get(variableName).push(subscriber);
            });
            const subscription = this._rawVariableCommunicator.openVariables(variableNames, appId).subscribe(values => subscriber.next(values), error => subscriber.error(error), () => subscriber.complete());
            this.variableValuesChangedSubscriptions.push(subscription);
        });
    }
    write(variableName, value) {
        return this._rawVariableCommunicator.write(variableName, value);
    }
    writeWordByBit(variableName, index, value) {
        return this._rawVariableCommunicator.writeWordByBit(variableName, index, value);
    }
    subscribeVariableState(variableName) {
        return this.subscribeVariableStates([variableName]).pipe(map(values => values[0]));
    }
    subscribeVariableStates(variableNames) {
        return new Observable(subscriber => {
            const subscription = this._rawVariableCommunicator.subscribeVariableStates(variableNames).subscribe(values => subscriber.next(values), error => subscriber.error(error), () => subscriber.complete());
            this.variableStatesChangedSubscription.push(subscription);
        });
    }
    dispose() {
        forEach(this.variableValuesChangedSubscriptions, s => s.unsubscribe());
        forEach(this.variableStatesChangedSubscription, s => s.unsubscribe());
    }
}
