// Generated by CoffeeScript 1.8.0
(function() {
  var CropTool, Dropzone, ENABLE_ASPECT_RATIO_BUTTON, delay,
    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
    __slice = [].slice,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  delay = function(ms, func) {
    return setTimeout(func, ms);
  };

  ENABLE_ASPECT_RATIO_BUTTON = false;

  CropTool = (function() {
    function CropTool($el) {
      this.cropHandler = __bind(this.cropHandler, this);
      this.release = __bind(this.release, this);
      this.resizePreview = __bind(this.resizePreview, this);
      this.$img = $el;
      this.init();
    }

    CropTool.prototype.init = function() {
      var api, _base;
      api = null;
      this.$img.Jcrop({
        bgColor: 'none',
        bgOpacity: 1,
        onChange: this.cropHandler,
        onSelect: this.cropHandler,
        onRelease: this.release
      }, function() {
        return api = this;
      });
      this.api = api;
      this.bounds = this.api.getBounds();
      this.imageSize = {
        width: this.$img.prop('naturalWidth'),
        height: this.$img.prop('naturalHeight')
      };
      this.previewSize = {
        width: this.imageSize.width,
        height: this.imageSize.height
      };
      this.crop = {
        width: this.imageSize.width,
        height: this.imageSize.height,
        left: 0,
        top: 0
      };
      this.canvas = document.createElement('canvas');
      this.canvas.width = this.previewSize.width;
      this.canvas.height = this.previewSize.height;
      if ((_base = this.canvas).toBlob == null) {
        _base.toBlob = this.canvas.msToBlob;
      }
      this.ctx = this.canvas.getContext('2d');
      this.redrawing = false;
      this.queuedRedraw = false;
      return this.api.setSelect([0, 0].concat(__slice.call(this.bounds)));
    };

    CropTool.prototype.destroy = function() {
      this.api.ui.holder.hide();
      return this.api.destroy();
    };

    CropTool.prototype.getCropAspectRatio = function() {
      return this.crop.width / this.crop.height;
    };

    CropTool.prototype.setAspectRatio = function(ratio) {
      return this.api.setOptions({
        aspectRatio: ratio
      });
    };

    CropTool.prototype.setPreviewAttributes = function(attrs) {
      var attr, value, _results;
      if (this.preview == null) {
        this.redraw();
      }
      _results = [];
      for (attr in attrs) {
        value = attrs[attr];
        _results.push(this.preview.attr(attr, value));
      }
      return _results;
    };

    CropTool.prototype.resizePreview = function(previewSize) {
      this.previewSize = previewSize;
      return this.redraw();
    };

    CropTool.prototype.redraw = function() {
      var hasPreview, height, height2, img, ratio, width, width2, win;
      if (this.redrawing) {
        this.queuedRedraw = true;
        return;
      }
      this.redrawing = true;
      win = window.parent.parent;
      hasPreview = this.preview != null;
      if (!hasPreview) {
        this.preview = $(new win.Image);
      }
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      width = Math.min(this.crop.width, this.previewSize.width);
      height = Math.min(this.crop.height, this.previewSize.height);
      if (!ENABLE_ASPECT_RATIO_BUTTON) {
        ratio = this.getCropAspectRatio();
        height2 = width / ratio;
        width2 = height * ratio;
        if (height2 <= height) {
          height = height2;
        } else {
          width = width2;
        }
      }
      if (this.canvas.width !== width) {
        this.canvas.width = width;
      }
      if (this.canvas.height !== height) {
        this.canvas.height = height;
      }
      img = this.preview[0];
      if (width >= this.imageSize.width && height >= this.imageSize.height && this.crop.left <= 0 && this.crop.top <= 0) {
        img.src = this.$img[0].src;
        if (!hasPreview) {
          this.$img.trigger('crop:preview', this.preview);
        }
        this.$img.trigger('crop:attributes');
        this.redrawing = false;
        return;
      }
      this.ctx.drawImage(this.$img[0], this.crop.left, this.crop.top, this.crop.width, this.crop.height, 0, 0, width, height);
      return this.canvas.toBlob((function(_this) {
        return function(blob) {
          var url;
          url = win.URL.createObjectURL(blob);
          img.src = url;
          return img.onload = function() {
            var queued;
            img.onload = void 0;
            win.URL.revokeObjectURL(url);
            queued = _this.queuedRedraw;
            _this.redrawing = false;
            _this.queuedRedraw = false;
            if (!hasPreview) {
              _this.$img.trigger('crop:preview', _this.preview);
            }
            _this.$img.trigger('crop:attributes');
            if (queued) {
              return _this.redraw();
            }
          };
        };
      })(this));
    };

    CropTool.prototype.release = function() {
      this.crop = {
        width: this.imageSize.width,
        height: this.imageSize.height,
        left: 0,
        top: 0
      };
      return this.redraw();
    };

    CropTool.prototype.cropPreview = function(coords) {
      if (!coords) {
        coords = this.api.tellSelect();
      }
      if (coords.w <= 0 || coords.h <= 0) {
        return;
      }
      this.crop = {
        width: Math.round(coords.w / this.bounds[0] * this.imageSize.width),
        height: Math.round(coords.h / this.bounds[1] * this.imageSize.height),
        left: Math.round(coords.x / this.bounds[0] * this.imageSize.width),
        top: Math.round(coords.y / this.bounds[1] * this.imageSize.height)
      };
      return this.redraw();
    };

    CropTool.prototype.cropHandler = function(coords) {
      var $crop, newVal, oldVal;
      this.cropPreview(coords);
      $crop = $('#field-crop');
      oldVal = $crop.val();
      newVal = this.crop.width >= this.imageSize.width && this.crop.height >= this.imageSize.height && this.crop.left <= 0 && this.crop.top <= 0 ? '' : [this.crop.left, this.crop.top, this.crop.left + this.crop.width, this.crop.top + this.crop.height].join(',');
      if (newVal !== oldVal) {
        $crop.val(newVal);
        return $crop.trigger('change');
      }
    };

    return CropTool;

  })();

  Dropzone = (function() {
    function Dropzone(config) {
      this.dragHandler = __bind(this.dragHandler, this);
      var $windows;
      this.field = config.field;
      this.el = config.el;
      this.$el = $(config.el);
      this.$span = this.$el.find('span');
      $windows = $(window).add(window.parent);
      $windows.on('dragenter dragleave drop', this.dragHandler);
      $windows.on('drop dragover', function(event) {
        return event.preventDefault();
      });
      this.$el.on('click', (function(_this) {
        return function() {
          if (_this.hasError()) {
            _this.$el.removeClass('error');
            return _this.hide();
          } else {
            return _this.field.trigger('click');
          }
        };
      })(this));
    }

    Dropzone.prototype.hide = function(animate) {
      if (animate == null) {
        animate = false;
      }
      console.log('Dropzone.hide(), hasError:', this.hasError());
      if (!this.hasError()) {
        this.$el.removeAttr('data-shown');
        if (animate) {
          return this.$el.finish().fadeOut('fast');
        } else {
          return this.$el.hide();
        }
      }
    };

    Dropzone.prototype.show = function(animate) {
      if (animate == null) {
        animate = false;
      }
      this.$el.attr('data-shown', '');
      if (animate) {
        return this.$el.finish().fadeIn('fast');
      } else {
        return this.$el.show();
      }
    };

    Dropzone.prototype.hasError = function() {
      return this.$el.hasClass('error');
    };

    Dropzone.prototype.dragStart = function() {
      this.$el.removeClass().addClass('drag');
      return this.$span.html('<i class="icon-circle-arrow-down"></i> Drop your image here');
    };

    Dropzone.prototype.dragOver = function() {
      this.$el.removeClass().addClass('drag-over');
      return this.$span.html('<i class="icon-cloud-upload"></i> Release to upload');
    };

    Dropzone.prototype.dragDrop = function() {
      this.$el.removeClass().addClass('drop');
      return this.$span.html('<i class="icon-spinner icon-spin icon-large"></i>');
    };

    Dropzone.prototype.dragError = function() {
      this.$el.removeClass().addClass('error');
      this.$span.html('<i class="icon-warning-sign"></i> Failed to upload image');
      return this.show();
    };

    Dropzone.prototype.dragHandler = function(event) {
      var justEntered, onTarget;
      onTarget = event.target === this.$el[0];
      justEntered = this.timeoutId != null;
      if (justEntered) {
        clearTimeout(this.timeoutId);
        this.timeoutId = void 0;
      }
      if (event.type === 'dragenter') {
        this.show(true);
        if (onTarget) {
          this.dragOver();
        } else {
          this.dragStart();
        }
        return this.timeoutId = delay(0, (function(_this) {
          return function() {
            return _this.timeoutId = void 0;
          };
        })(this));
      } else {
        if ((event.type === 'drop' && !onTarget) || (event.type === 'dragleave' && !justEntered)) {
          this.dragStart();
          return this.hide(false);
        }
      }
    };

    return Dropzone;

  })();

  window.ImageEditor = (function(_super) {
    __extends(ImageEditor, _super);

    function ImageEditor() {
      this.uploadError = __bind(this.uploadError, this);
      this.uploadComplete = __bind(this.uploadComplete, this);
      this.uploadStart = __bind(this.uploadStart, this);
      this.prepareUpload = __bind(this.prepareUpload, this);
      this.toggleAspectRatio = __bind(this.toggleAspectRatio, this);
      this.updateImageAttributes = __bind(this.updateImageAttributes, this);
      this.resizeImage = __bind(this.resizeImage, this);
      return ImageEditor.__super__.constructor.apply(this, arguments);
    }

    ImageEditor.prototype.initialize = function(config) {
      console.log('ImageEditor.initialize', this);
      ImageEditor.__super__.initialize.call(this, config);
      this.firstRender = true;
      this.field = $(config.field);
      this.preview = $(config.preview);
      this.dropzone = new Dropzone({
        field: this.field,
        el: config.dropzone
      });
      this.field.fileupload({
        dropZone: this.dropzone.el,
        drop: this.prepareUpload,
        send: this.uploadStart,
        done: this.uploadComplete,
        fail: this.uploadError,
        progressall: (function(_this) {
          return function(event, data) {
            return _this.progressbar.update(data);
          };
        })(this)
      });
      this.widthField = $('#field-width');
      this.heightField = $('#field-height');
      this.ratioButton = $('#ar-lock');
      $('#html-pane input').on('input', (function(_this) {
        return function() {
          return _this.updateImageAttributes();
        };
      })(this));
      this.widthField.on('input', (function(_this) {
        return function() {
          return _this.resizeImage({
            keepWidth: true,
            keepRatio: _this.ratioButton.hasClass('active')
          });
        };
      })(this));
      this.widthField.on('blur', (function(_this) {
        return function() {
          if (_this.crop) {
            return _this.widthField.val(_this.crop.canvas.width);
          }
        };
      })(this));
      this.heightField.on('input', (function(_this) {
        return function() {
          return _this.resizeImage({
            keepWidth: false,
            keepRatio: _this.ratioButton.hasClass('active')
          });
        };
      })(this));
      this.heightField.on('blur', (function(_this) {
        return function() {
          if (_this.crop) {
            return _this.heightField.val(_this.crop.canvas.height);
          }
        };
      })(this));
      this.ratioButton.on('click', this.toggleAspectRatio);
      this.ratioButton.tooltip();
      if (!ENABLE_ASPECT_RATIO_BUTTON) {
        return this.ratioButton.css({
          visibility: 'hidden',
          padding: 0,
          width: 10
        });
      }
    };

    ImageEditor.prototype.render = function(node) {
      console.log('ImageEditor.render()', {
        firstRender: this.firstRender,
        node: node
      });
      ImageEditor.__super__.render.call(this, node);
      if (node && node.data) {
        this.updateForm(node.data);
        if (node.data.url) {
          this.dropzone.dragDrop();
          this.renderThumbnail(node.data.url);
        } else {
          this.dropzone.dragStart();
        }
      } else {
        this.updateForm({
          filename: '',
          width: '',
          height: '',
          id: '',
          'class': '',
          alt: ''
        });
        this.removeThumbnail();
      }
      return this.firstRender = false;
    };

    ImageEditor.prototype.updateForm = function(data) {
      $("input[name='data[filename]']").val(data.filename);
      $("input[name='data[width]']").val(data.width);
      $("input[name='data[height]']").val(data.height);
      $("input[name='data[crop]']").val('');
      $("input[name='data[id]']").val(data.id);
      $("input[name='data[class]']").val(data["class"]);
      $("input[name='data[alt]']").val(data.alt);
      return this.ratioButton.removeClass('active');
    };

    ImageEditor.prototype.renderThumbnail = function(url) {
      var $image, image, needsRedraw;
      needsRedraw = !this.firstRender;
      console.log('ImageEditor.renderThumbnail()', {
        needsRedraw: needsRedraw
      });
      image = new Image;
      image.src = url;
      image.className = 'original';
      $image = $(image);
      return $image.on('load', (function(_this) {
        return function() {
          _this.dropzone.hide();
          _this.preview.hide();
          _this.preview.html(image);
          return _this.preview.fadeIn(100, function() {
            $image.on('crop:preview', function(event, html) {
              var _ref;
              if ((_ref = _this.crop) != null) {
                _ref.setPreviewAttributes(_this.getHtmlFields());
              }
              return _this.triggerRender(html);
            });
            $image.on('crop:attributes', function() {
              _this.updateImageAttributes();
              if (_this.crop) {
                if (!_this.widthField.is(':focus')) {
                  _this.widthField.val(_this.crop.canvas.width);
                }
                if (!_this.heightField.is(':focus')) {
                  return _this.heightField.val(_this.crop.canvas.height);
                }
              }
            });
            _this.crop = new CropTool($image);
            if (needsRedraw) {
              return _this.crop.redraw();
            }
          });
        };
      })(this));
    };

    ImageEditor.prototype.removeThumbnail = function() {
      var _ref;
      console.log('ImageEditor.removeThumbnail()');
      if ((_ref = this.crop) != null) {
        _ref.destroy();
      }
      this.preview.empty();
      this.dropzone.show();
      return this.dropzone.dragStart();
    };

    ImageEditor.prototype.dimensions = function() {
      var h, w;
      w = parseInt(this.widthField.val(), 10) || 0;
      h = parseInt(this.heightField.val(), 10) || 0;
      return [w, h];
    };

    ImageEditor.prototype.resizeImage = function(_arg) {
      var h, keepRatio, keepWidth, ratio, w, _ref;
      keepWidth = _arg.keepWidth, keepRatio = _arg.keepRatio;
      if (!this.crop) {
        return;
      }
      _ref = this.dimensions(), w = _ref[0], h = _ref[1];
      if (keepRatio || !ENABLE_ASPECT_RATIO_BUTTON) {
        ratio = this.crop.getCropAspectRatio();
        if (keepWidth) {
          h = Math.round(w / ratio);
          this.heightField.val(h);
        } else {
          w = Math.round(h * ratio);
          this.widthField.val(w);
        }
      }
      this.crop.resizePreview({
        width: w,
        height: h
      });
      return this.updateImageAttributes();
    };

    ImageEditor.prototype.getHtmlFields = function() {
      var attr, attrs, value, _i, _j, _len, _len1, _ref, _ref1;
      attrs = {};
      _ref = ['id', 'class', 'alt'];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        attr = _ref[_i];
        value = $("input[name='data[" + attr + "]']").val();
        attrs[attr] = !value && attr !== 'alt' ? null : value;
      }
      if (this.crop) {
        _ref1 = ['width', 'height'];
        for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
          attr = _ref1[_j];
          attrs[attr] = this.crop.canvas[attr];
        }
      }
      return attrs;
    };

    ImageEditor.prototype.updateImageAttributes = function() {
      if (!this.crop) {
        return;
      }
      this.crop.setPreviewAttributes(this.getHtmlFields());
      return this.trigger('node:resize');
    };

    ImageEditor.prototype.toggleAspectRatio = function() {
      var ratio, ratioInactive;
      if (!this.crop) {
        return;
      }
      ratioInactive = this.ratioButton.hasClass('active');
      ratio = this.crop.getCropAspectRatio();
      this.crop.setAspectRatio(ratioInactive ? 0 : ratio);
      if (!ratioInactive) {
        return this.resizeImage({
          keepWidth: true,
          keepRatio: true
        });
      }
    };

    ImageEditor.prototype.prepareUpload = function() {
      $('input[name="data[width]"]').val('');
      $('input[name="data[height]"]').val('');
      return this.trigger('form:change');
    };

    ImageEditor.prototype.uploadStart = function(event, response) {
      var _ref;
      console.log('ImageEditor.uploadStart()');
      this.dropzone.dragDrop();
      this.progressbar.show();
      return (_ref = this.crop) != null ? _ref.destroy() : void 0;
    };

    ImageEditor.prototype.uploadComplete = function(event, response) {
      var node;
      console.log('ImageEditor.uploadComplete()');
      this.progressbar.hide();
      node = this.setNode(response.result);
      return this.render(node);
    };

    ImageEditor.prototype.uploadError = function(event, response) {
      console.log('ImageEditor.uploadError()');
      this.progressbar.hide();
      return this.dropzone.dragError();
    };

    return ImageEditor;

  })(window.Editor);

}).call(this);
