text: import { Component, Directive, ElementRef, EventEmitter, HostListener, Input, NgZone, Renderer, Optional, Output } from '@angular/core';
  import { Content } from '../content/content';
  import { DomController } from '../../platform/dom-controller';
  import { isTrueProperty, reorderArray } from '../../util/util';
  import { findReorderItem } from './item-reorder-util';
  import { ItemReorderGesture } from '../item/item-reorder-gesture';
  import { Platform } from '../../platform/platform';
  export class ReorderIndexes {
      /**
       * @param {?} from
       * @param {?} to
       */
      constructor(from, to) {
          this.from = from;
          this.to = to;
      }
      /**
       * @param {?} array
       * @return {?}
       */
      applyTo(array) {
          reorderArray(array, this);
      }
  }
  function ReorderIndexes_tsickle_Closure_declarations() {
      /** @type {?} */
      ReorderIndexes.prototype.from;
      /** @type {?} */
      ReorderIndexes.prototype.to;
  }
  /**
   * \@name ItemReorder
   * \@description
   * Item reorder adds the ability to change an item's order in a group.
   * It can be used within an `ion-list` or `ion-item-group` to provide a
   * visual drag and drop interface.
   *
   * ## Grouping Items
   *
   * All reorderable items must be grouped in the same element. If an item
   * should not be reordered, it shouldn't be included in this group. For
   * example, the following code works because the items are grouped in the
   * `<ion-list>`:
   *
   *  ```html
   *  <ion-list reorder="true">
   *    <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
   *  </ion-list>
   *  ```
   *
   * However, the below list includes a header that shouldn't be reordered:
   *
   *  ```html
   *  <ion-list reorder="true">
   *    <ion-list-header>Header</ion-list-header>
   *    <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
   *  </ion-list>
   *  ```
   *
   * In order to mix different sets of items, `ion-item-group` should be used to
   * group the reorderable items:
   *
   *  ```html
   *  <ion-list>
   *    <ion-list-header>Header</ion-list-header>
   *    <ion-item-group reorder="true">
   *      <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
   *    </ion-item-group>
   *  </ion-list>
   *  ```
   *
   * It's important to note that in this example, the `[reorder]` directive is applied to
   * the `<ion-item-group>` instead of the `<ion-list>`. This way makes it possible to
   * mix items that should and shouldn't be reordered.
   *
   *
   * ## Implementing the Reorder Function
   *
   * When the item is dragged and dropped into the new position, the `(ionItemReorder)` event is
   * emitted. This event provides the initial index (from) and the new index (to) of the reordered
   * item. For example, if the first item is dragged to the fifth position, the event will emit
   * `{from: 0, to: 4}`. Note that the index starts at zero.
   *
   * A function should be called when the event is emitted that handles the reordering of the items.
   * See [usage](#usage) below for some examples.
   *
   *
   * \@usage
   *
   * ```html
   * <ion-list>
   *   <ion-list-header>Header</ion-list-header>
   *   <ion-item-group reorder="true" (ionItemReorder)="reorderItems($event)">
   *     <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
   *   </ion-item-group>
   * </ion-list>
   * ```
   *
   * ```ts
   * class MyComponent {
   *   items = [];
   *
   *   constructor() {
   *     for (let x = 0; x < 5; x++) {
   *       this.items.push(x);
   *     }
   *   }
   *
   *   reorderItems(indexes) {
   *     let element = this.items[indexes.from];
   *     this.items.splice(indexes.from, 1);
   *     this.items.splice(indexes.to, 0, element);
   *   }
   * }
   * ```
   *
   * Ionic also provides a helper function called `reorderArray` to
   * reorder the array of items. This can be used instead:
   *
   * ```ts
   * import { reorderArray } from 'ionic-angular';
   *
   * class MyComponent {
   *   items = [];
   *
   *   constructor() {
   *     for (let x = 0; x < 5; x++) {
   *       this.items.push(x);
   *     }
   *   }
   *
   *   reorderItems(indexes) {
   *     this.items = reorderArray(this.items, indexes);
   *   }
   * }
   * ```
   * Alternatevely you can execute helper function inside template:
   *
   * ```html
   * <ion-list>
   *   <ion-list-header>Header</ion-list-header>
   *   <ion-item-group reorder="true" (ionItemReorder)="$event.applyTo(items)">
   *     <ion-item *ngFor="let item of items">{% raw %}{{ item }}{% endraw %}</ion-item>
   *   </ion-item-group>
   * </ion-list>
   * ```
   *
   * \@demo /docs/v2/demos/src/item-reorder/
   * @see {\@link /docs/v2/components#lists List Component Docs}
   * @see {\@link ../../list/List List API Docs}
   * @see {\@link ../Item Item API Docs}
   */
  export class ItemReorder {
      /**
       * @param {?} _plt
       * @param {?} _dom
       * @param {?} elementRef
       * @param {?} _rendered
       * @param {?} _zone
       * @param {?} _content
       */
      constructor(_plt, _dom, elementRef, _rendered, _zone, _content) {
          this._plt = _plt;
          this._dom = _dom;
          this._rendered = _rendered;
          this._zone = _zone;
          this._content = _content;
          this._enableReorder = false;
          this._visibleReorder = false;
          this._lastToIndex = -1;
          /**
           * @output {object} Emitted when the item is reordered. Emits an object
           * with `from` and `to` properties.
           */
          this.ionItemReorder = new EventEmitter();
          this._element = elementRef.nativeElement;
      }
      /**
       * @return {?}
       */
      ngOnDestroy() {
          this._element = null;
          this._reorderGesture && this._reorderGesture.destroy();
      }
      /**
       * @return {?}
       */
      get reorder() {
          return this._enableReorder;
      }
      /**
       * @param {?} val
       * @return {?}
       */
      set reorder(val) {
          let /** @type {?} */ enabled = isTrueProperty(val);
          if (!enabled && this._reorderGesture) {
              this._reorderGesture.destroy();
              this._reorderGesture = null;
              this._visibleReorder = false;
              setTimeout(() => this._enableReorder = false, 400);
          }
          else if (enabled && !this._reorderGesture) {
              (void 0) /* console.debug */;
              this._reorderGesture = new ItemReorderGesture(this._plt, this);
              this._enableReorder = true;
              this._dom.write(() => {
                  this._zone.run(() => {
                      this._visibleReorder = true;
                  });
              }, 16);
          }
      }
      /**
       * @return {?}
       */
      _reorderPrepare() {
          let /** @type {?} */ ele = this._element;
          let /** @type {?} */ children = ele.children;
          for (let /** @type {?} */ i = 0, /** @type {?} */ ilen = children.length; i < ilen; i++) {
              var /** @type {?} */ child = children[i];
              child.$ionIndex = i;
              child.$ionReorderList = ele;
          }
      }
      /**
       * @return {?}
       */
      _reorderStart() {
          this.setElementClass('reorder-list-active', true);
      }
      /**
       * @param {?} fromIndex
       * @param {?} toIndex
       * @return {?}
       */
      _reorderEmit(fromIndex, toIndex) {
          this._reorderReset();
          if (fromIndex !== toIndex) {
              this._zone.run(() => {
                  const /** @type {?} */ indexes = new ReorderIndexes(fromIndex, toIndex);
                  this.ionItemReorder.emit(indexes);
              });
          }
      }
      /**
       * @param {?} scroll
       * @return {?}
       */
      _scrollContent(scroll) {
          const /** @type {?} */ scrollTop = this._content.scrollTop + scroll;
          if (scroll !== 0) {
              this._content.scrollTo(0, scrollTop, 0);
          }
          return scrollTop;
      }
      /**
       * @return {?}
       */
      _reorderReset() {
          let /** @type {?} */ children = this._element.children;
          let /** @type {?} */ len = children.length;
          this.setElementClass('reorder-list-active', false);
          let /** @type {?} */ transform = this._plt.Css.transform;
          for (let /** @type {?} */ i = 0; i < len; i++) {
              ((children[i])).style[transform] = '';
          }
          this._lastToIndex = -1;
      }
      /**
       * @param {?} fromIndex
       * @param {?} toIndex
       * @param {?} itemHeight
       * @return {?}
       */
      _reorderMove(fromIndex, toIndex, itemHeight) {
          if (this._lastToIndex === -1) {
              this._lastToIndex = fromIndex;
          }
          let /** @type {?} */ lastToIndex = this._lastToIndex;
          this._lastToIndex = toIndex;
          // TODO: I think both loops can be merged into a single one
          // but I had no luck last time I tried
          /********* DOM READ ********** */
          let /** @type {?} */ children = this._element.children;
          /********* DOM WRITE ********* */
          let /** @type {?} */ transform = this._plt.Css.transform;
          if (toIndex >= lastToIndex) {
              for (var /** @type {?} */ i = lastToIndex; i <= toIndex; i++) {
                  if (i !== fromIndex) {
                      ((children[i])).style[transform] = (i > fromIndex)
                          ? `translateY(${-itemHeight}px)` : '';
                  }
              }
          }
          if (toIndex <= lastToIndex) {
              for (var /** @type {?} */ i = toIndex; i <= lastToIndex; i++) {
                  if (i !== fromIndex) {
                      ((children[i])).style[transform] = (i < fromIndex)
                          ? `translateY(${itemHeight}px)` : '';
                  }
              }
          }
      }
      /**
       * @param {?} classname
       * @param {?} add
       * @return {?}
       */
      setElementClass(classname, add) {
          this._rendered.setElementClass(this._element, classname, add);
      }
      /**
       * @return {?}
       */
      getNativeElement() {
          return this._element;
      }
  }
  ItemReorder.decorators = [
      { type: Directive, args: [{
                  selector: 'ion-list[reorder],ion-item-group[reorder]',
                  host: {
                      '[class.reorder-enabled]': '_enableReorder',
                      '[class.reorder-visible]': '_visibleReorder',
                  }
              },] },
  ];
  /** @nocollapse */
  ItemReorder.ctorParameters = () => [
      { type: Platform, },
      { type: DomController, },
      { type: ElementRef, },
      { type: Renderer, },
      { type: NgZone, },
      { type: Content, decorators: [{ type: Optional },] },
  ];
  ItemReorder.propDecorators = {
      'ionItemReorder': [{ type: Output },],
      'reorder': [{ type: Input },],
  };
  function ItemReorder_tsickle_Closure_declarations() {
      /** @type {?} */
      ItemReorder.decorators;
      /**
       * @nocollapse
       * @type {?}
       */
      ItemReorder.ctorParameters;
      /** @type {?} */
      ItemReorder.propDecorators;
      /** @type {?} */
      ItemReorder.prototype._enableReorder;
      /** @type {?} */
      ItemReorder.prototype._visibleReorder;
      /** @type {?} */
      ItemReorder.prototype._reorderGesture;
      /** @type {?} */
      ItemReorder.prototype._lastToIndex;
      /** @type {?} */
      ItemReorder.prototype._element;
      /**
       * \@output {object} Emitted when the item is reordered. Emits an object
       * with `from` and `to` properties.
       * @type {?}
       */
      ItemReorder.prototype.ionItemReorder;
      /** @type {?} */
      ItemReorder.prototype._plt;
      /** @type {?} */
      ItemReorder.prototype._dom;
      /** @type {?} */
      ItemReorder.prototype._rendered;
      /** @type {?} */
      ItemReorder.prototype._zone;
      /** @type {?} */
      ItemReorder.prototype._content;
  }
  export class Reorder {
      /**
       * @param {?} elementRef
       */
      constructor(elementRef) {
          this.elementRef = elementRef;
          elementRef.nativeElement['$ionComponent'] = this;
      }
      /**
       * @return {?}
       */
      getReorderNode() {
          return findReorderItem(this.elementRef.nativeElement, null);
      }
      /**
       * @param {?} ev
       * @return {?}
       */
      onClick(ev) {
          // Stop propagation if click event reaches ion-reorder
          ev.preventDefault();
          ev.stopPropagation();
      }
  }
  Reorder.decorators = [
      { type: Component, args: [{
                  selector: 'ion-reorder',
                  template: `<ion-icon name="reorder"></ion-icon>`
              },] },
  ];
  /** @nocollapse */
  Reorder.ctorParameters = () => [
      { type: ElementRef, },
  ];
  Reorder.propDecorators = {
      'onClick': [{ type: HostListener, args: ['click', ['$event'],] },],
  };
  function Reorder_tsickle_Closure_declarations() {
      /** @type {?} */
      Reorder.decorators;
      /**
       * @nocollapse
       * @type {?}
       */
      Reorder.ctorParameters;
      /** @type {?} */
      Reorder.propDecorators;
      /** @type {?} */
      Reorder.prototype.elementRef;
  }
  //# sourceMappingURL=item-reorder.js.map