import { Host, h } from '@stencil/core';
/**
 * Pagination component which is used to divide large amounts of content into
 * smaller, easier to understand chunks. It is used when there is a finite list
 * of results on an individual page, and is placed at the bottom of the page
 * under the content.
 */
export class BsPagination {
  constructor() {
    this.showFirstLastButtons = false;
    this.prevPageText = undefined;
    this.firstPageText = undefined;
    this.nextPageText = undefined;
    this.lastPageText = undefined;
    this.fixed = false;
    this.variant = 'base';
    this.selection = undefined;
    this.centerDisplay = 'numbers';
    this.breakText = '…';
    this.pageRange = 3;
    this.pageCount = undefined;
    this.centerLabel = undefined;
    this.itemsPerGroup = 25;
    this.itemsCount = undefined;
    this.resultsIncrements = undefined;
    this.selectionState = undefined;
  }
  componentDidLoad() {
    // If no selection initially given, select the first option
    if (this.selection === undefined) {
      if (this.variant === 'results') {
        this.selectionState = parseInt(this.resultsIncrements.split(',')[0]);
      }
      else {
        this.selectionState = 1;
      }
    }
    else {
      this.selectionState = this.selection;
    }
  }
  handleSelectionPropChange(newVal) {
    this.selectionState = newVal;
  }
  handleSelectionStateChange(newVal, oldVal) {
    // Don't emit on initial load
    if (oldVal !== undefined) {
      this.selchange.emit(newVal);
    }
  }
  get actualPageCount() {
    if (!this._actualPageCount) {
      if (this.variant === 'group') {
        this._actualPageCount = Math.ceil(this.itemsCount / this.itemsPerGroup);
      }
      else if (this.variant === 'base') {
        this._actualPageCount = this.pageCount;
      }
    }
    return this._actualPageCount;
  }
  /**
   * Reset actual page count when any of these props changes so it can be
   * re-calculated on next `get`.
   */
  handlePageCountChange() {
    this._actualPageCount = undefined;
  }
  /**
   * Handles special variant cases such as `centerDisplay="text"` having the
   * same style as `variant="group"`.
   */
  getVariant() {
    if (this.variant === 'base') {
      if (this.centerDisplay === 'text') {
        return 'group';
      }
      else {
        return undefined;
      }
    }
    return this.variant;
  }
  handleFirstNav() {
    this.selectionState = 1;
  }
  getFirstPageButton() {
    const disabled = this.selectionState === 1;
    if (this.showFirstLastButtons) {
      if (this.firstPageText) {
        return (h("button", { type: "button", class: "bs-pagination-word-caret", title: this.firstPageText, disabled: disabled, onClick: () => this.handleFirstNav() }, h("bs-icon-caret-left-double", null), this.firstPageText));
      }
      else {
        return (h("button", { type: "button", title: "first", disabled: disabled, onClick: () => this.handleFirstNav() }, h("bs-icon-caret-left-double", null)));
      }
    }
    return undefined;
  }
  handlePrevNav() {
    // Use Math.max to never go below the first page
    this.selectionState = Math.max(this.selectionState - 1, 1);
  }
  getPrevPageButton() {
    const disabled = this.selectionState === 1;
    if (this.prevPageText) {
      return (h("button", { type: "button", class: "bs-pagination-word-caret", title: this.prevPageText, disabled: disabled, onClick: () => this.handlePrevNav() }, h("bs-icon-caret-left", null), this.prevPageText));
    }
    else {
      return (h("button", { type: "button", title: "prev", disabled: disabled, onClick: () => this.handlePrevNav() }, h("bs-icon-caret-left", null)));
    }
  }
  handleLastNav() {
    this.selectionState = this.actualPageCount;
  }
  getLastPageButton() {
    const disabled = this.selectionState === this.actualPageCount;
    if (this.showFirstLastButtons) {
      if (this.lastPageText) {
        return (h("button", { type: "button", class: "bs-pagination-word-caret", title: this.lastPageText, disabled: disabled, onClick: () => this.handleLastNav() }, this.lastPageText, h("bs-icon-caret-right-double", null)));
      }
      else {
        return (h("button", { type: "button", title: "last", disabled: disabled, onClick: () => this.handleLastNav() }, h("bs-icon-caret-right-double", null)));
      }
    }
    return undefined;
  }
  handleNextNav() {
    // Use Math.min to never go over the pageCount
    this.selectionState = Math.min(this.selectionState + 1, this.actualPageCount);
  }
  getNextPageButton() {
    const disabled = this.selectionState === this.actualPageCount;
    if (this.nextPageText) {
      return (h("button", { type: "button", class: "bs-pagination-word-caret", title: this.nextPageText, disabled: disabled, onClick: () => this.handleNextNav() }, this.nextPageText, h("bs-icon-caret-right", null)));
    }
    else {
      return (h("button", { type: "button", title: "next", disabled: disabled, onClick: () => this.handleNextNav() }, h("bs-icon-caret-right", null)));
    }
  }
  determinePageNumberRange() {
    // Start assuming all pages shown
    let left = 1;
    let right = this.actualPageCount;
    // Not showing all pages, so time to calculate
    if (this.pageRange < this.actualPageCount) {
      // Look left/right
      const offset = (this.pageRange - 1) / 2;
      left = this.selectionState - offset;
      right = this.selectionState + offset;
      // Extended past left end, so look right by the extra amount
      if (left < 1) {
        right = right + (1 - left);
        left = 1;
      }
      // Extended past right end, so look left by the extra amount
      if (right > this.actualPageCount) {
        left = left - (right - this.actualPageCount);
        right = this.actualPageCount;
      }
    }
    // Both ends are already included in the output, so this left/right update
    // prevents duplicates of them
    if (left === 1) {
      left++;
    }
    if (right === this.actualPageCount) {
      right--;
    }
    return { left, right };
  }
  handleSelection(selection) {
    this.selectionState = selection;
  }
  getPageNumbersDisplay() {
    // Always show first page number
    const pageNumbers = [
      h("button", { type: "button", key: "page-1", "data-selected": this.selectionState === 1 ? '' : undefined, disabled: this.selectionState === 1, onClick: () => this.handleSelection(1) }, "1")
    ];
    // Only one page, no need for further calculation
    if (this.actualPageCount === 1) {
      return pageNumbers;
    }
    const { left, right } = this.determinePageNumberRange();
    // Show left dots if left is at least two spaces away from the first page
    if (left > 2) {
      pageNumbers.push(h("span", null, this.breakText));
    }
    // Add the page numbers to display (e.g. for pageRange === 3, [7, 8, 9])
    for (let i = left; i <= right; i++) {
      pageNumbers.push(h("button", { type: "button", key: `page-${i}`, "data-selected": this.selectionState === i ? '' : undefined, disabled: this.selectionState === i, onClick: () => this.handleSelection(i) }, i));
    }
    // Show right dots if the right is at least two spaces away from the last page
    if (right < this.actualPageCount - 1) {
      pageNumbers.push(h("span", null, this.breakText));
    }
    // Always show the last page number
    pageNumbers.push(h("button", { type: "button", key: `page-${this.actualPageCount}`, "data-selected": this.selectionState === this.actualPageCount ? '' : undefined, disabled: this.selectionState === this.actualPageCount, onClick: () => this.handleSelection(this.actualPageCount) }, this.actualPageCount));
    return pageNumbers;
  }
  getPageTextDisplay() {
    var _a;
    return `${(_a = this.centerLabel) !== null && _a !== void 0 ? _a : 'Page'} ${this.selectionState} of ${this.actualPageCount}`;
  }
  getGroupTextDisplay() {
    var _a;
    // selectionState starts at 1 rather than 0
    const first = ((this.selectionState - 1) * this.itemsPerGroup) + 1;
    // Use Math.min to never go over the totalCounts
    const last = Math.min((first - 1) + this.itemsPerGroup, this.itemsCount);
    return `${(_a = this.centerLabel) !== null && _a !== void 0 ? _a : 'Results'} ${first} - ${last} of ${this.itemsCount}`;
  }
  getResultsDisplay() {
    const increments = this.resultsIncrements.split(',');
    const result = increments.map((increment) => {
      const incrementNum = parseInt(increment);
      return (h("button", { type: "button", key: `results-${increment}`, "data-selected": this.selectionState === incrementNum ? '' : undefined, disabled: this.selectionState === incrementNum, onClick: () => this.handleSelection(incrementNum) }, increment));
    });
    return result;
  }
  render() {
    return (h(Host, null, h("div", { class: "bs-pagination", "data-variant": this.getVariant(), "data-fixed": this.fixed }, (this.variant === 'base' || this.variant === 'group') && (h("div", { class: "bs-pagination-carets" }, this.getFirstPageButton(), this.getPrevPageButton())), this.variant === 'base' && this.centerDisplay === 'numbers' && (h("div", { class: "bs-pagination-page-numbers" }, this.getPageNumbersDisplay())), this.variant === 'base' && this.centerDisplay === 'text' && (h("span", null, this.getPageTextDisplay())), this.variant === 'group' && (h("span", null, this.getGroupTextDisplay())), this.variant === 'results' && [
      h("span", null, "Results Per Page:"),
      h("div", { class: "bs-pagination-results-numbers" }, this.getResultsDisplay())
    ], (this.variant === 'base' || this.variant === 'group') && (h("div", { class: "bs-pagination-carets" }, this.getNextPageButton(), this.getLastPageButton())))));
  }
  static get is() { return "bs-pagination"; }
  static get originalStyleUrls() {
    return {
      "$": ["bs-pagination.scss"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["bs-pagination.css"]
    };
  }
  static get properties() {
    return {
      "showFirstLastButtons": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Whether to show the \"first page\"/\"last page\" caret buttons."
        },
        "attribute": "show-first-last-buttons",
        "reflect": false,
        "defaultValue": "false"
      },
      "prevPageText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Text that will be shown next to the \"previous page\" caret button."
        },
        "attribute": "prev-page-text",
        "reflect": false
      },
      "firstPageText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Text that will be shown next to the \"first page\" caret button."
        },
        "attribute": "first-page-text",
        "reflect": false
      },
      "nextPageText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Text that will be shown next to the \"next page\" caret button."
        },
        "attribute": "next-page-text",
        "reflect": false
      },
      "lastPageText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Text that will be shown next to the \"last page\" caret button."
        },
        "attribute": "last-page-text",
        "reflect": false
      },
      "fixed": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Whether the pagination should be fixed to the bottom of the screen."
        },
        "attribute": "fixed",
        "reflect": false,
        "defaultValue": "false"
      },
      "variant": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'base'|'group'|'results'",
          "resolved": "\"base\" | \"group\" | \"results\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Which variant of pagination to show."
        },
        "attribute": "variant",
        "reflect": false,
        "defaultValue": "'base'"
      },
      "selection": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "The current active selection (page, results, etc.). If nothing provided,\nwill select the first page / results group by default."
        },
        "attribute": "selection",
        "reflect": false
      },
      "centerDisplay": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'numbers'|'text'",
          "resolved": "\"numbers\" | \"text\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "What to display between the navigation carets. A value of `\"numbers\"` will\nshow a list of page numbers and `\"text\"` will show which page is currently\nbeing shown. Only applicable for `variant=\"base\"`."
        },
        "attribute": "center-display",
        "reflect": false,
        "defaultValue": "'numbers'"
      },
      "breakText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Character to show when there's a break in page numbers. Only applicable for\n`variant=\"base\" centerDisplay=\"numbers\"`."
        },
        "attribute": "break-text",
        "reflect": false,
        "defaultValue": "'\u2026'"
      },
      "pageRange": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "How many pages to show before using the `break-text` character to break up\nthe pages. Should be an odd number to function properly. Only applicable\nfor `variant=\"base\" centerDisplay=\"numbers\"`."
        },
        "attribute": "page-range",
        "reflect": false,
        "defaultValue": "3"
      },
      "pageCount": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Total number of pages. Only applicable for `variant=\"base\"."
        },
        "attribute": "page-count",
        "reflect": false
      },
      "centerLabel": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Text to display between the navigation carets. Only applicable for\n`variant=\"base\" center-display=\"text\"` and `variant=\"group\"`. Defaults to\n`\"Page\"` for `variant=\"base\"` and `\"Results\"` for `variant=\"group\"`."
        },
        "attribute": "center-label",
        "reflect": false
      },
      "itemsPerGroup": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "How many items per group. Only applicable for `variant=\"group\"`."
        },
        "attribute": "items-per-group",
        "reflect": false,
        "defaultValue": "25"
      },
      "itemsCount": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "How many total items there are. Only applicable for `variant=\"group\"`."
        },
        "attribute": "items-count",
        "reflect": false
      },
      "resultsIncrements": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Comma-separated list of the desired \"Results Per Page\" increment buttons.\nOnly applicable for `variant=\"results\"`."
        },
        "attribute": "results-increments",
        "reflect": false
      }
    };
  }
  static get states() {
    return {
      "selectionState": {}
    };
  }
  static get events() {
    return [{
        "method": "selchange",
        "name": "selchange",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emits the page or results number that was selected."
        },
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        }
      }];
  }
  static get watchers() {
    return [{
        "propName": "selection",
        "methodName": "handleSelectionPropChange"
      }, {
        "propName": "selectionState",
        "methodName": "handleSelectionStateChange"
      }, {
        "propName": "pageCount",
        "methodName": "handlePageCountChange"
      }, {
        "propName": "itemsCount",
        "methodName": "handlePageCountChange"
      }, {
        "propName": "itemsPerGroup",
        "methodName": "handlePageCountChange"
      }];
  }
}
//# sourceMappingURL=bs-pagination.js.map
