import {Injectable} from "@angular/core";
import {AppProgressIndicationComponent} from "../component/app-progress-indication.component";
import {NgbModal, NgbModalOptions, NgbModalRef} from "@ng-bootstrap/ng-bootstrap";

@Injectable()
export class AppProgressIndicationService {

  private static readonly EVENT_INTERCEPTOR = (event) => {
    event.preventDefault();
    event.stopPropagation();
  };

  protected counter: number = 0;
  protected focused: any;
  protected ngbModalRef: NgbModalRef;
  protected options: NgbModalOptions = {
    backdrop: 'static',
    keyboard: false,
    windowClass: 'modal-center loader'
  };

  constructor(protected ngbModal: NgbModal) {
  }

  public showProgressBar(): boolean {
    if (this.counter == 0) {
      this.disableEvents();
      this.saveFocus();
      this.showProgressIndicator();
    }
    ++this.counter;
    return this.counter == 1;
  }

  public hideProgressBar(): boolean {
    if (this.counter == 0) {
      return false;
    }
    if (this.counter == 1) {
      this.hideProgressIndicator();
      this.restoreFocus();
      this.enableEvents();
    }
    --this.counter;
    return this.counter == 0;
  }

  public unconditionallyHideProgressBar(): void {
    this.enableEvents();
    this.hideProgressIndicator();
  }

  public restoreProgressBar(): void {

    if (this.counter > 0 && this.ngbModalRef == null) {
      this.disableEvents();
      this.showProgressIndicator();
    }
  }

  protected showProgressIndicator() {
    this.ngbModalRef = this.ngbModal.open(AppProgressIndicationComponent, this.options);
  }

  protected hideProgressIndicator() {
    this.ngbModalRef.dismiss('cancel');
    this.ngbModalRef = null;
  }

  private saveFocus() {
    this.focused = $(':focus');
  }

  private restoreFocus() {
    if (this.focused) {
      this.focused.focus();
      this.focused = null;
    }
  }

  private disableEvents() {
    let body = $('body');
    body.keydown(AppProgressIndicationService.EVENT_INTERCEPTOR);
    body.keyup(AppProgressIndicationService.EVENT_INTERCEPTOR);
    body.contextmenu(AppProgressIndicationService.EVENT_INTERCEPTOR)
  }

  private enableEvents() {
    let body = $('body');
    body.off('keydown', AppProgressIndicationService.EVENT_INTERCEPTOR);
    body.off('keyup', AppProgressIndicationService.EVENT_INTERCEPTOR);
    body.off('contextmenu', AppProgressIndicationService.EVENT_INTERCEPTOR);
  }

}
