text: // Copyright (C) 2016 Sergey Akopkokhyants
  // This project is licensed under the terms of the MIT license.
  // https://github.com/akserg/ng2-dnd
  import { Injectable, ChangeDetectorRef } from '@angular/core';
  import { ElementRef } from '@angular/core';
  import { DragDropConfig } from './dnd.config';
  import { DragDropService } from './dnd.service';
  import { isString, isFunction, isPresent, createImage, callFun } from './dnd.utils';
  export var AbstractComponent = (function () {
      function AbstractComponent(elemRef, _dragDropService, _config, _cdr) {
          var _this = this;
          this._dragDropService = _dragDropService;
          this._config = _config;
          this._cdr = _cdr;
          /**
           * Whether the object is draggable. Default is true.
           */
          this._dragEnabled = false;
          /**
           * Allows drop on this element
           */
          this.dropEnabled = false;
          this.dropZones = [];
          this.cloneItem = false;
          this._elem = elemRef.nativeElement;
          //
          // DROP events
          //
          this._elem.ondragenter = function (event) {
              _this._onDragEnter(event);
          };
          this._elem.ondragover = function (event) {
              _this._onDragOver(event);
              //
              if (event.dataTransfer != null) {
                  event.dataTransfer.dropEffect = _this._config.dropEffect.name;
              }
              return false;
          };
          this._elem.ondragleave = function (event) {
              _this._onDragLeave(event);
          };
          this._elem.ondrop = function (event) {
              _this._onDrop(event);
          };
          //
          // Drag events
          //
          this._elem.ondragstart = function (event) {
              // console.log('ondragstart', event.target);
              _this._onDragStart(event);
              //
              if (event.dataTransfer != null) {
                  event.dataTransfer.setData('text', '');
                  // Change drag effect
                  event.dataTransfer.effectAllowed = _this.effectAllowed || _this._config.dragEffect.name;
                  // Change drag image
                  if (isPresent(_this.dragImage)) {
                      if (isString(_this.dragImage)) {
                          event.dataTransfer.setDragImage(createImage(_this.dragImage));
                      }
                      else if (isFunction(_this.dragImage)) {
                          event.dataTransfer.setDragImage(callFun(_this.dragImage));
                      }
                      else {
                          var img = _this.dragImage;
                          event.dataTransfer.setDragImage(img.imageElement, img.x_offset, img.y_offset);
                      }
                  }
                  else if (isPresent(_this._config.dragImage)) {
                      var dragImage = _this._config.dragImage;
                      event.dataTransfer.setDragImage(dragImage.imageElement, dragImage.x_offset, dragImage.y_offset);
                  }
                  else if (_this.cloneItem) {
                      _this._dragHelper = _this._elem.cloneNode(true);
                      _this._dragHelper.classList.add('dnd-drag-item');
                      _this._dragHelper.style.position = "absolute";
                      _this._dragHelper.style.top = "0px";
                      _this._dragHelper.style.left = "-1000px";
                      _this._elem.parentElement.appendChild(_this._dragHelper);
                      event.dataTransfer.setDragImage(_this._dragHelper, event.offsetX, event.offsetY);
                  }
                  // Change drag cursor
                  if (_this._dragEnabled) {
                      _this._elem.style.cursor = _this.effectCursor ? _this.effectCursor : _this._config.dragCursor;
                  }
                  else {
                      _this._elem.style.cursor = _this._defaultCursor;
                  }
              }
          };
          this._elem.ondragend = function (event) {
              if (_this._elem.parentElement && _this._dragHelper) {
                  _this._elem.parentElement.removeChild(_this._dragHelper);
              }
              // console.log('ondragend', event.target);
              _this._onDragEnd(event);
              // Restore style of dragged element
              _this._elem.style.cursor = _this._defaultCursor;
          };
      }
      Object.defineProperty(AbstractComponent.prototype, "dragEnabled", {
          get: function () {
              return this._dragEnabled;
          },
          set: function (enabled) {
              this._dragEnabled = !!enabled;
              this._elem.draggable = this._dragEnabled;
          },
          enumerable: true,
          configurable: true
      });
      /******* Change detection ******/
      AbstractComponent.prototype.detectChanges = function () {
          var _this = this;
          // Programmatically run change detection to fix issue in Safari
          setTimeout(function () {
              _this._cdr.detectChanges();
          }, 250);
      };
      //****** Droppable *******//
      AbstractComponent.prototype._onDragEnter = function (event) {
          // console.log('ondragenter._isDropAllowed', this._isDropAllowed);
          if (this._isDropAllowed) {
              // event.preventDefault();
              this._onDragEnterCallback(event);
          }
      };
      AbstractComponent.prototype._onDragOver = function (event) {
          // // console.log('ondragover._isDropAllowed', this._isDropAllowed);
          if (this._isDropAllowed) {
              // The element is over the same source element - do nothing
              if (event.preventDefault) {
                  // Necessary. Allows us to drop.
                  event.preventDefault();
              }
              this._onDragOverCallback(event);
          }
      };
      AbstractComponent.prototype._onDragLeave = function (event) {
          // console.log('ondragleave._isDropAllowed', this._isDropAllowed);
          if (this._isDropAllowed) {
              // event.preventDefault();
              this._onDragLeaveCallback(event);
          }
      };
      AbstractComponent.prototype._onDrop = function (event) {
          // console.log('ondrop._isDropAllowed', this._isDropAllowed);
          if (this._isDropAllowed) {
              if (event.preventDefault) {
                  // Necessary. Allows us to drop.
                  event.preventDefault();
              }
              if (event.stopPropagation) {
                  // Necessary. Allows us to drop.
                  event.stopPropagation();
              }
              this._onDropCallback(event);
              this.detectChanges();
          }
      };
      Object.defineProperty(AbstractComponent.prototype, "_isDropAllowed", {
          get: function () {
              if (this._dragDropService.isDragged && this.dropEnabled) {
                  // First, if `allowDrop` is set, call it to determine whether the
                  // dragged element can be dropped here.
                  if (this.allowDrop) {
                      return this.allowDrop(this._dragDropService.dragData);
                  }
                  // Otherwise, use dropZones if they are set.
                  if (this.dropZones.length === 0 && this._dragDropService.allowedDropZones.length === 0) {
                      return true;
                  }
                  for (var i = 0; i < this._dragDropService.allowedDropZones.length; i++) {
                      var dragZone = this._dragDropService.allowedDropZones[i];
                      if (this.dropZones.indexOf(dragZone) !== -1) {
                          return true;
                      }
                  }
              }
              return false;
          },
          enumerable: true,
          configurable: true
      });
      //*********** Draggable **********//
      AbstractComponent.prototype._onDragStart = function (event) {
          // console.log('ondragstart.dragEnabled', this._dragEnabled);
          if (this._dragEnabled) {
              this._dragDropService.allowedDropZones = this.dropZones;
              // console.log('ondragstart.allowedDropZones', this._dragDropService.allowedDropZones);
              this._onDragStartCallback(event);
          }
      };
      AbstractComponent.prototype._onDragEnd = function (event) {
          this._dragDropService.allowedDropZones = [];
          // console.log('ondragend.allowedDropZones', this._dragDropService.allowedDropZones);
          this._onDragEndCallback(event);
      };
      //**** Drop Callbacks ****//
      AbstractComponent.prototype._onDragEnterCallback = function (event) { };
      AbstractComponent.prototype._onDragOverCallback = function (event) { };
      AbstractComponent.prototype._onDragLeaveCallback = function (event) { };
      AbstractComponent.prototype._onDropCallback = function (event) { };
      //**** Drag Callbacks ****//
      AbstractComponent.prototype._onDragStartCallback = function (event) { };
      AbstractComponent.prototype._onDragEndCallback = function (event) { };
      AbstractComponent.decorators = [
          { type: Injectable },
      ];
      /** @nocollapse */
      AbstractComponent.ctorParameters = function () { return [
          { type: ElementRef, },
          { type: DragDropService, },
          { type: DragDropConfig, },
          { type: ChangeDetectorRef, },
      ]; };
      return AbstractComponent;
  }());
  