var ImageDialog = Class.create({
  initialize: function(element, images) {
    this.element = $(element);
    this.images = images;
    this.content = this.element.down('.dialog_border.content');
    this.buildDialog();
    this.element.observe('mouseup', this.stopEvent);
    this.element.observe('mousedown', this.stopEvent);
  },
  show: function() {
    this.element.open();
  },
  buildDialog: function() {
    this.content.insert(new Element("h2").update("Insert image"));
    // this.tabs = new Element("div", {className: 'tabs'});
    // this.panels = new Element("div", {className: 'content'});
    this.buildExistingImagesPanel();
    this.createButtons();
  },
  buildExistingImagesPanel: function() {
    var tbody = new Element('tbody');
    var table = new Element('table').insert(tbody), tr = new Element('tr');
    this.foldersContainer = new Element('tbody');
    tbody.insert(tr.insert(new Element('td').insert(new Element('div', {id: 'folders'}).insert(new Element('table').insert(this.foldersContainer)))));
    this.images.each(function(resource) {
      this.addFolder(0, this.foldersContainer, resource);
    }.bind(this));
    this.imagesContainer = new Element('div', {id: 'images'});
    tr.insert(new Element('td').insert(this.imagesContainer));
    if(this.images.first())
      this.selectFolder(this.images.first(), this.foldersContainer.down('td'));
    this.content.insert(table);
  },
  addFolder: function(index, content, resource) {
    if (resource.type != 'Folder') return;
    var element = new Element("td", {className: 'folder', style: 'padding-left: ' + (10 * index + 2) + 'px'}).update(resource.name);
    element.insert({top: new Element('img', {src: '/images/icon_directory.png'})});
    element.observe("mouseover", element.addClassName.bind(element, 'hover'));
    element.observe("mouseout", element.removeClassName.bind(element, 'hover'));
    element.observe("click", this.selectFolder.bind(this, resource, element));
    content.insert(new Element('tr').insert(element));
    element.setStyle('width', element.getWidth());
    if (resource.children && resource.children.length != 0)
      resource.children.each(this.addFolder.curry(index + 1, content).bind(this));
  },
  selectFolder: function(folder, element) {
    if (folder.type != 'Folder') return;
    if (this.selectedFolder)
      this.selectedFolder.removeClassName('selected');
    element.addClassName('selected');
    this.selectedFolder = element;
    
    var table = new Element('tbody'), tr, td;
    folder.children.reject(function(resource) { return resource.type == 'Folder' }).inGroupsOf(4).collect(function(image_group) {
      tr = new Element('tr');
      image_group.each(function(image) {
        td = new Element('td', {style: 'vertical-align: top', className: 'image'});
        td.observe("mouseover", element.addClassName.bind(td, 'hover'));
        td.observe("mouseout", element.removeClassName.bind(td, 'hover'));
        td.observe("click", this.selectImage.bind(this, image, td));
        if (image)
          td.insert(new Element('img', {src: Routes.resizeFile('70x70', image.url), title: image.name}));
        tr.insert(td);
      }.bind(this));
      return tr;
    }.bind(this)).each(table.insert.bind(table));
    this.imagesContainer.update(new Element('table').insert(table));
  },
  selectImage: function(image, element) {
    if (image.type == 'Folder') return;
    if (this.selectedImage)
      this.selectedImage.removeClassName('selected');
    element.addClassName('selected');
    this.currentImage = image;
    this.selectedImage = element;
  },
  createButtons: function() {
    var container = new Element("div", {className: 'dialog_buttons'});
    this.cancelButton = new Element('img', {src: '/images/cancel_button.png'});
    this.cancelButton.observe('click', this.cancel.bind(this));
    container.insert(this.cancelButton);
    this.okButton = new Element('img', {src: '/images/ok_button.png'});
    this.okButton.observe('click', this.ok.bind(this));
    container.insert(this.okButton);
    this.content.insert(container);
  },
  cancel: function() {
    this.element.close();
  },
  ok: function() {
    if (!this.currentImage) return;
    this.element.close();
    this.insertImage();
  },
  insertImage: function() {
    if (window.PageEditor.range && Prototype.Browser.IE)
      window.PageEditor.range.select()
    var node = Selection().getRange().getNode();
    if (node && node.nodeName != 'P')
      node = node.up('p');
    if (node && node.nodeName != 'P')
      node = node.next('p');
    if (!node)
      node = $$('.editable p')[0];
    if (!node)
      return;
  
    console.log(this.currentImage.url)
    console.log(Routes.resizeFile('240x240', this.currentImage.url))
    var img = new Element('img', {src: Routes.resizeFile('240x240', this.currentImage.url), style: 'float: left'});
    node.insert({top: img});
    new ImageControl(img);
    // window.PageEditor.execCommand('insertimage', Routes.resizeFile('540x540', this.currentImage.url));
  },
  stopEvent: function(evnt) {
    Event.stop(evnt);
    return false;
  }
});

var ImageControl = Class.create({
  initialize: function(img) {
    this.img = $(img);
    this.img.controlObj = this;
    this.enable();
    this.initDragDrop();
    this.initResize();
    this.img.observe('mousemove', this.updateControls.bind(this))
    this.img.observe('mouseout', this.updateControls.bind(this))
    this.handle.observe('mouseout', this.updateControls.bind(this))
  },
  disable: function() {
    this.disabled = true;
    this.img.style.cursor = '';
  },
  enable: function() {
    this.disabled = false;
    this.img.style.cursor = 'move';
  },
  updateControls: function(event) {
    var position = this.img.cumulativeOffset();
    var size = this.img.getDimensions();
    var pointer = event.pointer();
    if (pointer.x >= position[0] && pointer.x <= (position[0] + size.width) && pointer.y >= position[1] && pointer.y <= (position[1] + size.height) && !this.dragging)
      this.showControls();
    else
      this.hideControls();
  },
  showControls: function() {
    if (this.disabled) return;
    this.positionResizeHandle();
  },
  hideControls: function() {
    this.handle.hide();
  },
  initResize: function() {
    this.handle = new Element('div', {className: 'resize-handle'});
    this.handle.observe('mousedown', this.startResize.bind(this));
    $(document.body).observe('mouseup', this.endResize.bind(this));
    $(document.body).observe('mousemove', this.resize.bind(this));
    this.handle.hide();
    $(document.body).insert(this.handle);
  },
  startResize: function(event) {
    if (this.resizing) return;
    this.resizing = true;
    this.startResizePointer = event.pointer();
    this.startResizeDimensions = this.img.getDimensions();
    return event.stop();
  },
  endResize: function(event) {
    if (!this.resizing) return;
    this.resizing = false;
    this.updateImageSrc();
    this.updateControls(event);
    return event.stop();
  },
  resize: function(event) {
    if (!this.resizing) return;
    this.img.style.height = 'auto';
    if (this.img.getStyle('float') == 'left')
      this.img.style.width = (this.startResizeDimensions.width - (this.startResizePointer.x - event.pointer().x)) + 'px';
    else
      this.img.style.width = (this.startResizeDimensions.width - (event.pointer().x - this.startResizePointer.x)) + 'px';
    this.positionResizeHandle();
    return event.stop();
  },
  positionResizeHandle: function() {
    this.handle.show();
    var position = this.img.cumulativeOffset();
    var size = this.img.getDimensions();
    this.handle.style.top = (position[1] + size.height - this.handle.getDimensions().height) + 'px';
    if (this.img.getStyle('float') == 'left') {
      this.handle.style.left = (position[0] + size.width - this.handle.getDimensions().width) + 'px';
      this.handle.addClassName('right');
      this.handle.removeClassName('left');
    } else {
      this.handle.style.left = position[0] + 'px';
      this.handle.addClassName('left');
      this.handle.removeClassName('right');
    }
  },
  initDragDrop: function() {
    this.img.observe('mousedown', this.startDrag.bind(this));
    $(document.body).observe('mouseup', this.endDrag.bind(this));
    $(document.body).observe('mousemove', this.drag.bind(this));
  },
  startDrag: function(event) {
    if (this.disabled) return;
    if (this.dragging) return;
    this.dragging = true;
    this.hideControls();
    this.startDragPointer = event.pointer();
    this.startDragElement = this.img.cumulativeOffset();

    this.img.style.position = 'absolute';
    this.img.style.top = this.startDragElement.top + 'px';
    this.img.style.left = this.startDragElement.left + 'px';
    this.img.style.zIndex = 2000;

    this.dimensions = this.img.getDimensions()
    this.placeholder = new Element('div', {className: 'image-placeholder'});
    this.placeholder.setStyle({width: (this.dimensions.width - 2) + "px", height: (this.dimensions.height - 2) + 'px', 'float': this.img.getStyle('float')});
    this.img.insert({before: this.placeholder});

    $(document.body).insert(this.img);
    this.enumarateDropLocations();
    return event.stop();
  },
  endDrag: function(event) {
    if (!this.dragging) return;
    this.img.style.position = 'static';
    this.img.setStyle({'float': this.placeholder.getStyle('float')});
    this.placeholder.insert({before: this.img});
    this.placeholder.remove();
    this.showControls();
    this.dragging = false;
  },
  drag: function(event) {
    if (!this.dragging) return;
    var x = this.startDragElement[0] + (event.pointer().x - this.startDragPointer.x);
    var y = this.startDragElement[1] + (event.pointer().y - this.startDragPointer.y);
    var w = this.dimensions.width, h = this.dimensions.height;
    this.img.style.left = x + 'px';
    this.img.style.top = y + 'px';
    var location = this.dropLocations.detect(function(drop) { return drop.hit(x, y, w, h); });
    if (location)
      location.drop(this.placeholder);
    return event.stop();
  },
  enumarateDropLocations: function() {
    this.dropLocations = [];
    window.PageEditor.sections.each(function(section) {
      section.select('p').each(function(p) {
        this.dropLocations.push(new DropLocation(p, 'left'));
        this.dropLocations.push(new DropLocation(p, 'right'));
      }, this);
    }, this);
  },
  updateImageSrc: function() {
    var size = this.img.getDimensions();
    this.img.setAttribute('src', this.img.getAttribute('src').gsub(/\/\d+x\d+\//, '/' + size.width + 'x' + size.height + '/'));
  }
});

var DropLocation = Class.create({
  initialize: function(element, side) {
    this.element = $(element);
    this.side = side;

    // hold on to left and right so that they don't shift around in IE
    // remember that the drop locations are recomputed every time we start dragging
    this.left = this.element.cumulativeOffset()[0];
    this.right = this.left + this.element.getDimensions().width;
  },
  hit: function(x, y, w, h) {
    // recompute the top every time because it might change as the page shifts around
    this.top = this.element.cumulativeOffset()[1];
    return Math.abs(this.top - y) < 20 && // 20px above or below the top of the paragraph
           this.left - x < 50          && // no more than 50px past the left side
           x + w - this.right < 50     && // no more than 50px past the right side
           (this.side == 'left' ? 
             Math.abs(this.left - x) < Math.abs(this.right - (x + w)) : // closer to the left side
             Math.abs(this.left - x) > Math.abs(this.right - (x + w))   // closer to the right side
           );
  },
  drop: function(el) {
    var left = Math.abs(this.left - this.x)
    var right = Math.abs(this.right - (this.x + this.w))
    el.setStyle({'float': this.side});
    this.element.insert({top: el});
  }
})