/*
 * 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;

  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 + "'");
    }
  }

  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);
  }
}

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