export class Deferred {

	// tslint:disable: no-inferrable-types
	private isOpen: boolean = false;
	private isOpeningPromisePresent: any | Promise<void> = false;
	private isReadyCallback: any = () => undefined;

	public open(): void {

		this.isOpen = true;
		this.isReadyCallback();
		this.reset();
	}

	public close(): void {

		this.isOpen = false;
		this.reset();
	}

	private reset(): void {

		this.isReadyCallback = () => undefined;
		this.isOpeningPromisePresent = false;
	}

	public untilOpen(): Promise<any> {

		// If not open, start opening, otherwise wait
		return this.isOpeningPromisePresent ? this.isOpeningPromisePresent : this.isOpeningPromisePresent = new Promise((resolve) => {

			// If ready - resolve, if not - set resolve to
			this.isOpen ? resolve(undefined) : this.isReadyCallback = resolve;
		});
	}
}
