var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { h, Host } from '@stencil/core';
import SlotChange from '../../shared/decorators/slot-change';
export class BsPagination {
  constructor() {
    this.size = undefined;
    this.align = 'left';
    this.label = 'Page navigation';
    this.controlled = true;
    this.page = 1;
    this.pageCount = 1;
    this.maxVisiblePages = 5;
    this.currentPage = 1;
  }
  /**
   * helper method to add size to each page item in pagination
   */
  addSizeToPageItems(slot) {
    Array.from(slot.assignedElements())
      .filter((el) => el.tagName == 'BS-PAGE-ITEM')
      .forEach((el) => {
      el.size = this.size;
    });
  }
  /**
   * an exposed method to manually set the page
   * @param pageNumber
   */
  async setPageTo(pageNumber) {
    // ensure the requested page number is valid
    if (pageNumber == this.currentPage || pageNumber < 1 || pageNumber > this.pageCount) {
      return;
    }
    this.currentPage = pageNumber;
    this.pagechanged.emit(this.currentPage);
  }
  /**
   * renders the pagination component
   */
  render() {
    return (h(Host, { "aria-label": this.label, class: `
                    pagination 
                    ${this.align === 'center' && 'justify-content-center'} 
                    ${this.align === 'right' && 'justify-content-end'}
                ` }, this.controlled && this.renderPageItems(), h("slot", null)));
  }
  /**
   * handles controlled pagination, where the component decides which page items to show
   * TODO: write some tests for this...
   */
  renderPageItems() {
    let pageItems = [];
    let startingPage = 0;
    let endingPage = this.pageCount - 1;
    pageItems.push(this.renderFirstPageItem());
    pageItems.push(this.renderPreviousPageItem());
    pageItems.push(this.renderSkipBackItem());
    // if have more pages than are available to display, need to figure out which ones to show
    if (this.pageCount > this.maxVisiblePages) {
      const midPoint = (this.maxVisiblePages - 1) / 2;
      const currPage = this.currentPage - 1; // doing this zero based
      // based on current page, figure out the starting and ending page numbers that we'll be displaying
      startingPage = currPage - midPoint < 0 ? 0 : currPage - midPoint; // using midpoint to avoid showing negative page numbers
      endingPage = startingPage + this.maxVisiblePages - 1;
      // whoops, ending page isn't valid (too large), fix the numbers to work backwards
      if (endingPage >= this.pageCount) {
        startingPage = this.pageCount - this.maxVisiblePages + 1;
        endingPage = this.pageCount - 1;
      }
    }
    // display the visible pages
    for (let i = (startingPage < 0 ? 0 : startingPage); i <= endingPage; i++) {
      pageItems.push(h("bs-page-item", { active: i + 1 == this.currentPage, onClick: () => this.setPageTo(i + 1) }, i + 1));
    }
    pageItems.push(this.renderSkipForwardItem());
    pageItems.push(this.renderNextPageItem());
    pageItems.push(this.renderLastPageItem());
    return pageItems;
  }
  renderFirstPageItem() {
    return (h("bs-page-item", { disabled: this.currentPage == 1, onClick: () => this.setPageTo(1) }, "First"));
  }
  renderPreviousPageItem() {
    return (h("bs-page-item", { disabled: this.currentPage == 1, onClick: () => this.setPageTo(this.currentPage - 1) }, "\u00AB"));
  }
  /**
   * when user has navigated beyond maxVisiblePages into the pagination, need to show an ellipsis to hide previous pages
   * when user clicks on those ellipsis it will skip them backwards
   */
  renderSkipBackItem() {
    if (this.currentPage > this.maxVisiblePages - 1) {
      return (h("bs-page-item", { onClick: () => this.setPageTo(this.currentPage - this.maxVisiblePages) }, "\u2026"));
    }
  }
  /**
   * when user has navigated beyond maxVisiblePages into the pagination, need to show an ellipsis to hide next pages
   * when user clicks on those ellipsis it will skip them forwards
   */
  renderSkipForwardItem() {
    if (this.currentPage < this.pageCount - this.maxVisiblePages + 1) {
      return (h("bs-page-item", { onClick: () => this.setPageTo(this.currentPage + this.maxVisiblePages) }, "\u2026"));
    }
  }
  renderNextPageItem() {
    return (h("bs-page-item", { disabled: this.currentPage >= this.pageCount, onClick: () => this.setPageTo(this.currentPage + 1) }, "\u00BB"));
  }
  renderLastPageItem() {
    return (h("bs-page-item", { disabled: this.currentPage >= this.pageCount, onClick: () => this.setPageTo(this.pageCount) }, "Last"));
  }
  static get is() { return "bs-pagination"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["bs-pagination.scss"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["bs-pagination.css"]
    };
  }
  static get properties() {
    return {
      "size": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'sm' | 'lg'",
          "resolved": "\"lg\" | \"sm\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "optional, size of the pagination items"
        },
        "attribute": "size",
        "reflect": false
      },
      "align": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "'left' | 'center' | 'right'",
          "resolved": "\"center\" | \"left\" | \"right\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "change alignment of pagination"
        },
        "attribute": "align",
        "reflect": false,
        "defaultValue": "'left'"
      },
      "label": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "a descriptive label to reflect the purpose of the pagination"
        },
        "attribute": "label",
        "reflect": false,
        "defaultValue": "'Page navigation'"
      },
      "controlled": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "turn off controlled to handle display of page items manually"
        },
        "attribute": "controlled",
        "reflect": false,
        "defaultValue": "true"
      },
      "page": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "set page to override the current page"
        },
        "attribute": "page",
        "reflect": false,
        "defaultValue": "1"
      },
      "pageCount": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "set page count so pagination knows how to display it's items"
        },
        "attribute": "page-count",
        "reflect": false,
        "defaultValue": "1"
      },
      "maxVisiblePages": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "if there are more than maxVisiblePages, the pagination will show clickable ellipsis when needed to hide them"
        },
        "attribute": "max-visible-pages",
        "reflect": false,
        "defaultValue": "5"
      }
    };
  }
  static get states() {
    return {
      "currentPage": {}
    };
  }
  static get events() {
    return [{
        "method": "pagechanged",
        "name": "pagechanged",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "called when the page changes"
        },
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        }
      }];
  }
  static get methods() {
    return {
      "setPageTo": {
        "complexType": {
          "signature": "(pageNumber: number) => Promise<void>",
          "parameters": [{
              "tags": [{
                  "name": "param",
                  "text": "pageNumber"
                }],
              "text": ""
            }],
          "references": {
            "Promise": {
              "location": "global"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "an exposed method to manually set the page",
          "tags": [{
              "name": "param",
              "text": "pageNumber"
            }]
        }
      }
    };
  }
  static get watchers() {
    return [{
        "propName": "size",
        "methodName": "addSizeToPageItems"
      }, {
        "propName": "page",
        "methodName": "setPageTo"
      }];
  }
}
__decorate([
  SlotChange()
], BsPagination.prototype, "addSizeToPageItems", null);
//# sourceMappingURL=bs-pagination.js.map
