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

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

class SplitLayout extends HTMLElement {

  private offset: number;

  constructor() {
    super();

    let first = true;
    let justAdded = false;
    for (let child of this.children) {
      if (justAdded) { // skip, because the just added had enlarges the list of children
        justAdded = false;
        continue;
      }
      if (child.matches("input[type=hidden]")) {
        continue;
      }
      if (first) { // the first needs no splitter handle
        first = false;
        continue;
      }
      const splitter = document.createElement("div");
      splitter.classList.add(
          this.orientation === "horizontal" ? "tobago-splitLayout-horizontal" : "tobago-splitLayout-vertical"
      );
      justAdded = true;
      splitter.addEventListener("mousedown", this.start.bind(this));
      child.parentElement.insertBefore(splitter, child);
    }
  }

  get orientation(): string {
    return this.getAttribute("orientation");
  }

  set orientation(orientation: string) {
    this.setAttribute("orientation", orientation);
  }

  start(event: MouseEvent) {
    event.preventDefault();
    const splitter = event.target as HTMLElement;
    const previous = DomUtils.previousElementSibling(splitter);
    this.offset = this.orientation === "horizontal"
        ? event.pageX - previous.offsetWidth : event.pageY - previous.offsetHeight;
    const mousedown = SplitLayoutMousedown.save(event, splitter);
    document.addEventListener("mousemove", this.move.bind(this));
    document.addEventListener("mouseup", this.stop.bind(this));
    const previousArea = mousedown.previous;
    if (this.orientation === "horizontal") {
      previousArea.style.width = String(previousArea.offsetWidth + "px");
    } else {
      previousArea.style.height = String(previousArea.offsetHeight + "px");
    }
    previousArea.style.flexGrow = "inherit";
    previousArea.style.flexBasis = "auto";
    console.debug("initial width/height = '%s'",
        (this.orientation === "horizontal" ? previousArea.style.width : previousArea.style.height));
  }

  move(event: MouseEvent): void {
    event.preventDefault();
    const data = SplitLayoutMousedown.load();
    const previousArea = data.previous;
    if (this.orientation === "horizontal") {
      previousArea.style.width = String(event.pageX - this.offset) + "px";
    } else {
      previousArea.style.height = String(event.pageY - this.offset) + "px";
    }
  }

  stop(event: MouseEvent): void {
    document.removeEventListener("mousemove", this.move.bind(this)); // fixme remove the real added
    document.removeEventListener("mouseup", this.stop.bind(this)); // fixme remove the real added
    SplitLayoutMousedown.remove();
  }
}

/**
 * Data class to store "offset" and "splitter"-element of the mouse down event in the tobago-page.
 */
interface SplitLayoutMousedownData {
  readonly splitLayoutId: string;
  readonly splitterIndex: number;
  readonly horizontal: boolean;
}

class SplitLayoutMousedown {

  private data: SplitLayoutMousedownData;

  static save(event: MouseEvent, splitter: HTMLElement): SplitLayoutMousedown {
    const horizontal = splitter.classList.contains("tobago-splitLayout-horizontal");
    const previous = DomUtils.previousElementSibling(splitter);
    const data: SplitLayoutMousedownData = {
      splitLayoutId: splitter.parentElement.id,
      horizontal: horizontal,
      splitterIndex: this.indexOfSplitter(splitter, horizontal)
    };
    Page.page().dataset["SplitLayoutMousedownData"] = JSON.stringify(data);
    return new SplitLayoutMousedown(data);
  }

  static load() {
    return new SplitLayoutMousedown(Page.page().dataset["SplitLayoutMousedownData"]);
  }

  static remove() {
    Page.page().dataset["SplitLayoutMousedownData"] = null;
  }

  private static indexOfSplitter(splitter: HTMLElement, horizontal: boolean): number {
    const list = splitter.parentElement.getElementsByClassName(
        horizontal ? "tobago-splitLayout-horizontal" : "tobago-splitLayout-vertical");
    for (let i = 0; i < list.length; i++) {
      if (list.item(i) === splitter) {
        return i;
      }
    }
    return -1;
  }

  private constructor(data: SplitLayoutMousedownData | string) {
    this.data = typeof data === "string" ? JSON.parse(data) : data;
  }

  get splitter(): HTMLElement {
    return document.getElementById(this.data.splitLayoutId).getElementsByClassName(
        this.data.horizontal ? "tobago-splitLayout-horizontal" : "tobago-splitLayout-vertical")
        .item(this.data.splitterIndex) as HTMLElement;
  }

  get previous(): HTMLElement {
    return DomUtils.previousElementSibling(this.splitter);
  }
}

document.addEventListener("DOMContentLoaded", function (event) {
  window.customElements.define('tobago-split-layout', SplitLayout);
});
