import { Subject, PartialObserver } from 'rxjs';

export class Emitter {
  private subjects: Map<string, Subject<any>>;

  public constructor() {
    this.subjects = new Map();
  }

  private static createName(name: string): string {
    return '$' + name;
  }

  /**
   * emit
   */
  public emit(name: string, data?: any) {
    const fnName = Emitter.createName(name);

    if (!this.subjects.has(fnName)) {
      this.subjects.set(fnName, new Subject());
    }

    this.subjects.get(fnName).next(data);
  }

  /**
   * listen
   */
  public listen(name: string, handler: (data?: any) => void) {
    const fnName = Emitter.createName(name);

    if (!this.subjects.has(fnName)) {
      this.subjects.set(fnName, new Subject());
    }

    return this.subjects.get(fnName).subscribe(handler);
  }

  /**
   * dispose
   */
  public dispose() {
    const _subjects = this.subjects;
    _subjects.forEach((value: Subject<any>, key: string) => {
      if (_subjects.has(key)) {
        _subjects.get(key).unsubscribe();
      }
    });

    this.subjects = new Map();
  }
}
