'use strict';

var stringResources = require('./stringResources.js');
var enums = require('./enums.js');

var defaultOptions = {};
class DocumentMapArea {
  // #region fields    element: HTMLElement;
  options;
  viewerOptions;
  controller;
  notificationService;
  $element;
  $documentMap;
  documentMapVisible;
  enableAccessibility;
  currentReport;
  documentMapNecessary;
  // #endregion
  // #region constructor
  constructor(element, options, viewerOptions) {
    this.element = element;
    this.options = $.extend({}, defaultOptions, options, viewerOptions);
    this.controller = this.options.controller;
    if (!this.controller) {
      throw "No controller (telerikReporting.reportViewerController) has been specified.";
    }
    this.notificationService = this.options.notificationService;
    if (!this.notificationService) {
      throw "No notificationService (telerikReporting.NotificationService) has been specified.";
    }
    this.$element = $(this.element);
    this.$documentMap;
    this.documentMapVisible = this.options.documentMapVisible !== false;
    this.enableAccessibility = this.options.enableAccessibility;
    this.currentReport = null;
    this.documentMapNecessary = false;
    this.init();
  }
  // #endregion
  init() {
    this.$documentMap = $('<div id="' + this.options.viewerSelector + '-documentMap" data-role="treeview"></div>');
    this.$documentMap.appendTo(this.element);
    this._attachEvents();
    this.replaceStringResources(this.$element);
  }
  onTreeViewSelectionChanged(event) {
    var documentMapNode = event.sender.dataItem(event.node);
    var page = documentMapNode.page;
    var id = documentMapNode.id;
    this.controller.navigateToPage(page, {
      type: "bookmark",
      id
    });
  }
  onTreeViewNodeExpand(event) {
    if (this.enableAccessibility) {
      window.setTimeout(() => {
        this.setNodeAccessibilityAttributes(event.node);
      }, 100);
    }
  }
  setNodeAccessibilityAttributes(node) {
    var $items = $(node).find("li");
    Array.from($items).forEach((item) => {
      var $li = $(item);
      $li.attr("aria-label", $li[0].innerText);
    });
  }
  resetReportAndClearItems() {
    this.documentMapNecessary = false;
    this.showDocumentMap(false);
    const r = this.controller.getReportSource().report;
    const clearMapItems = this.currentReport !== r || !this.isVisible();
    this.currentReport = r;
    if (clearMapItems) {
      this.clearDocumentMap();
    }
  }
  clearDocumentMap() {
    this.displayDocumentMap([]);
  }
  displayDocumentMap(documentMap) {
    var hasDocumentMap = documentMap && !$.isEmptyObject(documentMap);
    var $treeView = this.$documentMap.data("kendoTreeView");
    if (!$treeView) {
      try {
        this.$documentMap.kendoTreeView({
          dataTextField: "text",
          select: this.onTreeViewSelectionChanged.bind(this)
        });
        $treeView = this.$documentMap.data("kendoTreeView");
      } catch (e) {
        console.error("Instantiation of Kendo TreeView as Document Map threw an exception", e);
        throw e;
      }
    }
    $treeView.setDataSource(documentMap);
    if (this.enableAccessibility) {
      this.setAccessibilityAttributes($treeView);
    }
    this.showDocumentMap(hasDocumentMap);
  }
  setAccessibilityAttributes(treeView) {
    treeView.bind("expand", this.onTreeViewNodeExpand.bind(this));
    treeView.element.attr("aria-label", stringResources.stringResources.ariaLabelDocumentMap);
    var listItems = treeView.element.find("ul");
    Array.from(listItems).forEach((list) => {
      this.setNodeAccessibilityAttributes(list);
    });
    if (this.documentMapNecessary) {
      this.setSplitbarAccessibilityAttributes();
    }
  }
  setSplitbarAccessibilityAttributes() {
    var splitbar = this.$element.next();
    if (this.options.documentMapAreaPosition === enums.DocumentMapAreaPositions.RIGHT) {
      splitbar = this.$element.prev();
    }
    splitbar.attr("aria-label", stringResources.stringResources.ariaLabelDocumentMapSplitter);
  }
  isVisible() {
    var args = {};
    this.notificationService.getDocumentMapState(args);
    return args.visible;
  }
  beginLoad() {
    this.$element.addClass("trv-loading");
  }
  endLoad() {
    this.$element.removeClass("trv-loading");
  }
  showDocumentMap(show) {
    var splitter = $("#" + this.options.viewerSelector + "-document-map-splitter").getKendoSplitter();
    var sibling = this.$element.next(".k-splitbar");
    if (this.options.documentMapAreaPosition === enums.DocumentMapAreaPositions.RIGHT) {
      sibling = this.$element.prev(".k-splitbar");
    }
    if (splitter) {
      (this.documentMapNecessary ? $.fn.removeClass : $.fn.addClass).call(sibling, "k-hidden");
      splitter.toggle(".trv-document-map", show);
    }
  }
  _attachEvents() {
    this.controller.on("beforeLoadParameters", () => {
      this.resetReportAndClearItems();
    }).on("beginLoadReport", () => {
      this.beginLoad();
    }).onAsync("reportLoadComplete", async (reportInfo) => {
      if (reportInfo.documentMapAvailable) {
        this.documentMapNecessary = true;
        this.displayDocumentMap(reportInfo.documentMapNodes);
        this.notificationService.setDocumentMapVisible({ enabled: true, visible: this.documentMapVisible });
      } else {
        this.documentMapNecessary = false;
        this.showDocumentMap(this.documentMapNecessary);
      }
      this.endLoad();
    }).on("error", () => {
      this.endLoad();
      this.clearDocumentMap();
    }).on("renderingStopped", () => {
      this.documentMapNecessary = false;
      this.showDocumentMap(false);
    });
    this.notificationService.setDocumentMapVisible((event, args) => {
      this.documentMapVisible = args.visible;
      this.showDocumentMap(this.documentMapVisible && this.documentMapNecessary);
    }).getDocumentMapState((event, args) => {
      args.enabled = this.documentMapNecessary;
      args.visible = this.documentMapVisible;
    });
  }
  replaceStringResources($documentMap) {
    var $documentMapOverlay = $documentMap.find(".trv-document-map-overlay");
    if (!$documentMapOverlay) {
      return;
    }
    $documentMapOverlay.attr("aria-label", stringResources.stringResources[$documentMapOverlay.attr("aria-label")]);
  }
  // #endregion
}

exports.DocumentMapArea = DocumentMapArea;
