// src/Carousel.ts
import CarouselSlider from "@boxslider/slider/effects/Carousel";

// src/Slider.ts
import BoxSlider, { defaultOptions } from "@boxslider/slider/BoxSlider";
function camelize(str) {
  return str.replace(/-./g, (m) => m[1].toUpperCase());
}
function getNumericAttribute(el, attribute, defaultValue) {
  const attributeValue = el.getAttribute(attribute);
  let value = NaN;
  if (attributeValue !== null) {
    value = parseInt(attributeValue, 10);
  }
  return isNaN(value) ? defaultValue : value;
}
function getBbooleanAttribute(el, attribute, defaultValue) {
  if (el.hasAttribute(attribute)) {
    return el.getAttribute(attribute) !== "false";
  }
  return defaultValue;
}
var BOOLEAN_ATTRIBUTES = ["auto-scroll", "pause-on-hover"];
var NUMBER_ATTRIBUTES = [
  "speed",
  "timeout",
  "start-index",
  "swipe",
  "swipe-tolerance"
];
var SLIDER_ATTRIBUTES = [...BOOLEAN_ATTRIBUTES, ...NUMBER_ATTRIBUTES];
var Slider = class extends HTMLElement {
  #slider;
  get slider() {
    return this.#slider;
  }
  get autoScroll() {
    return getBbooleanAttribute(this, "auto-scroll", defaultOptions.autoScroll);
  }
  get pauseOnHover() {
    return getBbooleanAttribute(
      this,
      "pause-on-hover",
      defaultOptions.pauseOnHover
    );
  }
  get speed() {
    return getNumericAttribute(this, "speed", defaultOptions.speed);
  }
  get startIndex() {
    return getNumericAttribute(this, "start-index", defaultOptions.startIndex);
  }
  get swipe() {
    return getBbooleanAttribute(this, "swipe", defaultOptions.swipe);
  }
  get swipeTolerance() {
    return getNumericAttribute(
      this,
      "swipe-tolerance",
      defaultOptions.swipeTolerance
    );
  }
  get timeout() {
    return getNumericAttribute(this, "timeout", defaultOptions.timeout);
  }
  get options() {
    return {
      autoScroll: this.autoScroll,
      pauseOnHover: this.pauseOnHover,
      speed: this.speed,
      startIndex: this.startIndex,
      swipe: this.swipe,
      swipeTolerance: this.swipeTolerance,
      timeout: this.timeout
    };
  }
  init(effect) {
    const slider = new BoxSlider(this, effect, this.options);
    const events = [
      "play",
      "pause",
      "before",
      "after",
      "destroy"
    ];
    events.forEach(
      (ev) => slider.addEventListener(
        ev,
        (detail) => this.dispatchEvent(new CustomEvent(ev, { detail }))
      )
    );
    this.#slider = slider;
  }
  reset(options, effect) {
    this.slider?.reset(options, effect);
  }
  attributeChangedCallback(name) {
    if (SLIDER_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset({ [propName]: this[propName] });
    }
  }
  disconnectedCallback() {
    this.slider?.destroy();
    this.#slider = void 0;
  }
};

// src/Carousel.ts
var CAROUSEL_ATTRIBUTES = ["cover", "timing-function"];
var Carousel = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...CAROUSEL_ATTRIBUTES];
  get cover() {
    return getBbooleanAttribute(this, "cover", false);
  }
  get timingFunction() {
    return this.getAttribute("timing-function") || "ease-out";
  }
  connectedCallback() {
    this.init(
      new CarouselSlider({
        cover: this.cover,
        timingFunction: this.timingFunction
      })
    );
  }
  attributeChangedCallback(name) {
    if (CAROUSEL_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new CarouselSlider({
          cover: this.cover,
          timingFunction: this.timingFunction
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-carousel", Carousel);
}

// src/Cube.ts
import CubeSlider from "@boxslider/slider/effects/Cube";
var CUBE_ATTRIBUTES = ["direction", "perspective"];
var Cube = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...CUBE_ATTRIBUTES];
  get direction() {
    const propDirection = this.getAttribute("direction")?.trim();
    if (propDirection === "horizontal" || propDirection === "vertical") {
      return propDirection;
    }
    return "horizontal";
  }
  get perspective() {
    return getNumericAttribute(this, "perspective", 1e3);
  }
  attributeChangedCallback(name) {
    if (CUBE_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new CubeSlider({
          direction: this.direction,
          perspective: this.perspective
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
  connectedCallback() {
    this.init(
      new CubeSlider({
        direction: this.direction,
        perspective: this.perspective
      })
    );
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-cube", Cube);
}

// src/Fade.ts
import FadeSlider from "@boxslider/slider/effects/Fade";
var FADE_ATTRIBUTES = ["timing-function"];
var Fade = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...FADE_ATTRIBUTES];
  get timingFunction() {
    return this.getAttribute("timing-function")?.trim() || "ease-in-out";
  }
  attributeChangedCallback(name) {
    if (FADE_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new FadeSlider({
          timingFunction: this.timingFunction
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
  connectedCallback() {
    this.init(
      new FadeSlider({
        timingFunction: this.timingFunction
      })
    );
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-fade", Fade);
}

// src/Tile.ts
import TileSlider from "@boxslider/slider/effects/Tile";
var TILE_ATTRIBUTES = ["rows", "row-offset", "tile-effect"];
var Tile = class extends Slider {
  static observedAttributes = [...SLIDER_ATTRIBUTES, ...TILE_ATTRIBUTES];
  get rows() {
    return getNumericAttribute(this, "rows", 8);
  }
  get rowOffset() {
    return getNumericAttribute(this, "row-offset", 50);
  }
  get tileEffect() {
    return this.getAttribute("tile-effect") || "fade";
  }
  attributeChangedCallback(name) {
    if (TILE_ATTRIBUTES.includes(name)) {
      const propName = camelize(name);
      this.reset(
        { [propName]: this[propName] },
        new TileSlider({
          rows: this.rows,
          rowOffset: this.rowOffset,
          tileEffect: this.tileEffect
        })
      );
    } else {
      super.attributeChangedCallback(name);
    }
  }
  connectedCallback() {
    this.init(
      new TileSlider({
        rows: this.rows,
        rowOffset: this.rowOffset,
        tileEffect: this.tileEffect
      })
    );
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-tile", Tile);
}

// src/SliderControls.ts
var template = document.createElement("template");
template.innerHTML = `
<div part="container">
  <div part="slider">
    <slot id="slider"></slot>
  </div>

  <div part="controls">
    <slot name="prev-btn">
      <button part="prev-btn nav-btn" type="button" aria-label="Previous"></button>
    </slot>
    <slot name="next-btn">
      <button part="next-btn nav-btn" type="button" aria-label="Next"></button>
    </slot>
  </div>

  <slot name="index" part="index"></slot>
</div>
`;
var incrementingId = 1;
var SliderControls = class extends HTMLElement {
  #slider;
  connectedCallback() {
    this.setAttribute("aria-roledescription", "carousel");
    const shadow = this.attachShadow({ mode: "open" });
    const tree = template.content.cloneNode(true);
    const sliderSlot = tree.querySelector("#slider");
    sliderSlot?.addEventListener("slotchange", () => {
      const sliderComponent = sliderSlot.assignedElements()[0];
      if (!sliderComponent.id) {
        sliderComponent.id = `bs-slider-${incrementingId++}`;
      }
      this.#slider = sliderComponent?.slider;
      this.#slider?.addEventListener("after", ({ currentIndex }) => {
        indexSlot?.querySelectorAll("button").forEach((b, index) => {
          const isActive = index === currentIndex;
          b.setAttribute("aria-pressed", isActive ? "true" : "false");
          b.setAttribute("part", isActive ? "index-btn active" : "index-btn");
        });
      });
      const indexSlot = shadow.querySelector('slot[name="index"]');
      const slides = Array.from(this.#slider?.el.children || []).filter(
        (el) => el instanceof HTMLElement
      );
      if (slides.length > 1) {
        const frag = document.createDocumentFragment();
        for (let i = 0; i < slides.length; i++) {
          const btn = document.createElement("button");
          btn.setAttribute("aria-label", `View slide ${i + 1}`);
          btn.setAttribute(
            "part",
            i === this.#slider?.activeIndex ? "index-btn active" : "index-btn"
          );
          btn.setAttribute("type", "button");
          btn.setAttribute("aria-controls", sliderComponent.id);
          btn.addEventListener("click", () => {
            this.#slider?.skipTo(i).then();
          });
          frag.appendChild(btn);
        }
        indexSlot?.appendChild(frag);
      }
      indexSlot?.addEventListener("slotchange", () => {
        const index = indexSlot.assignedElements()[0];
        if (index.hasChildNodes()) {
          index.childNodes.forEach((node, index2) => {
            node.addEventListener("click", () => this.#slider?.skipTo(index2));
          });
        }
      });
    });
    const prevBtnSlot = tree.querySelector(
      'slot[name="prev-btn"]'
    );
    prevBtnSlot?.querySelector("button")?.addEventListener("click", () => this.#slider?.prev());
    prevBtnSlot?.addEventListener("slotchange", () => {
      const button = prevBtnSlot.assignedElements()[0];
      button?.addEventListener("click", () => {
        this.#slider?.prev();
      });
    });
    const nextBtnSlot = tree.querySelector(
      'slot[name="next-btn"]'
    );
    nextBtnSlot?.querySelector("button")?.addEventListener("click", () => this.#slider?.next());
    nextBtnSlot?.addEventListener("slotchange", () => {
      const button = nextBtnSlot.assignedElements()[0];
      button?.addEventListener("click", () => {
        this.#slider?.next();
      });
    });
    shadow.appendChild(tree);
  }
  disconnectedCallback() {
    this.#slider = void 0;
  }
};
if (typeof customElements !== "undefined") {
  customElements.define("bs-slider-controls", SliderControls);
}
export {
  Carousel,
  Cube,
  Fade,
  SliderControls,
  Tile
};
