/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Create a overlay barrier and animate it.
 */

import {DomUtils} from "./tobago-utils";
import {Config} from "./tobago-config";
import {Page} from "./tobago-page";

// XXX issue: if a ajax call is scheduled on the same element, the animation arrow will stacking and not desapearing.
// XXX issue: "error" is not implemented correctly
// see http://localhost:8080/demo-5-snapshot/content/30-concept/50-partial/Partial_Ajax.xhtml to use this feature
// XXX todo: check full page transitions

export class Overlay {

  private static readonly overlayMap: Map<string, Overlay> = new Map<string, Overlay>();

  /**
   * Is this overlay for an AJAX request, or an normal submit?
   * We need this information, because AJAX need to clone the animated image, but for a normal submit
   * we must not clone it, because the animation stops in some browsers.
   */
  ajax: boolean = true;

  /**
   * This boolean indicates, if the overlay is "error" or "wait".
   */
  error: boolean = false;

  /**
   * The delay for the wait overlay. If not set the default delay is read from Tobago.Config.
   */
  waitOverlayDelay: number = 0;

  element: HTMLElement;

  overlay: HTMLDivElement;

  constructor(element: HTMLElement, ajax = false, error = false, waitOverlayDelay?) {

    this.element = element;
    this.ajax = ajax;
    this.error = error;
    this.waitOverlayDelay = waitOverlayDelay
        ? waitOverlayDelay
        : Config.get(this.ajax ? "Ajax.waitOverlayDelay" : "Tobago.waitOverlayDelay");

    // create the overlay

    this.overlay = document.createElement('div');
    this.overlay.classList.add("tobago-page-overlay");
    this.overlay.classList.add(
        this.error ? "tobago-page-overlay-markup-error" : "tobago-page-overlay-markup-wait");

    let left = "0";
    let top = "0";
    if (this.element.matches("body")) {
      this.overlay.style.position = "fixed";
      this.overlay.style.zIndex = "1500"; // greater than the bootstrap navbar
    } else {
      const rect = this.element.getBoundingClientRect();
      left = (rect.left + document.body.scrollLeft) + "px";
      top = (rect.top + document.body.scrollTop) + "px";
      this.overlay.style.width = this.element.offsetWidth + "px";
      this.overlay.style.height = this.element.offsetHeight + "px";
// tbd: is this still needed?       this.overlay.style.position= "absolute" // XXX is set via class, but seams to be overridden in IE11?
    }

    document.getElementsByTagName("body")[0].append(this.overlay);

    let wait = document.createElement("div");
    wait.classList.add("tobago-page-overlayCenter");
    this.overlay.append(wait);

    let image = document.createElement("i");
    if (this.error) {
      image.classList.add("fa", "fa-flash", "fa-3x");
      wait.classList.add("alert-danger");
    } else {
      image.classList.add("fa", "fa-refresh", "fa-3x", "fa-spin");
      image.style.opacity = "0.4";
    }
    wait.append(image);
    wait.style.display = ""; //XXX ?

    this.overlay.style.backgroundColor = Page.page().style.backgroundColor;
    this.overlay.style.left = left;
    this.overlay.style.top = top;
    setTimeout(() => { // to play the CSS transition
      this.overlay.classList.add("tobago-page-overlay-timeout");
    }, this.waitOverlayDelay);

    Overlay.overlayMap.set(element.id, this);
    console.debug("----> set overlay " + element.id);
  }

  static destroy(id: string) {
    console.debug("----> get overlay " + id);
    const overlay = Overlay.overlayMap.get(id);
    if (overlay) {
      overlay.overlay.remove();
      Overlay.overlayMap.delete(id);
    } else {
      console.warn("Overlay not found for id='" + id + "'");
    }
  }
}

Config.set("Tobago.waitOverlayDelay", 1000);
Config.set("Ajax.waitOverlayDelay", 1000);
