Editor.Command = {
  extend: function(mixin) {
    var klass = Class.create();
    Object.extend(Object.extend(klass.prototype, Editor.Command.Base.prototype), mixin);
    return klass;
  }
}

Editor.Command.Base = Class.create();
Editor.Command.Base.prototype = {
  name: false,

  baseInitialize: function(name, options) {
    this.name    = this.name || name;
    this.options = options   || false;
  },
  
  initialize: function(name, options) {
    this.baseInitialize(name, options);
  },

  call: function(options) {
    this.options = options || this.options;
    this.before();
    Editor.current.execute(this.name, this.options);
    Editor.current.iframe.window().focus();
    this.after();
  },

  before: Prototype.K,
  after:  Prototype.K
}

Editor.Command.FormatBlock = Editor.Command.extend({
  initialize: function(tagName) {
    this.name    = "FormatBlock";
    this.tagName = tagName;
    this.options = "<" + tagName + ">";
  }
});

Editor.Command.InsertImage = Editor.Command.extend({
  initialize: function(name) {
    this.name     = "InsertImage";
    this.options  = false;
    this.baseCall = this.call;
    this.call     = function(src, align) {
      this.options = src + "?-editor-last-inserted-image"
      this.align   = align;
      this.baseCall();
    }
  },

  after: function() {
    var images   = Editor.current.find("img");
    var inserted = images.find(function(i) {
      return Element.readAttribute(i, "src").match(/\?-editor-last-inserted-image$/);
    });
    if (inserted) {
      //console.log(this.align);
      inserted.src = Element.readAttribute(inserted, "src").replace(/\?-editor-last-inserted-image$/, "");
      if (this.align == "left" || this.align == "right") {
        Element.setStyle(inserted, {"float": this.align});
        return;
      } else {
        Element.setStyle(inserted, {"display": "block"});
        return;
      }
      // -- Weirdness correction --
      // Gecko adds a br element following anything you insert
      if (inserted.nextSibling.nodeName.toLowerCase() == "br") {
        inserted.parentNode.removeChild(inserted.nextSibling);
      }
      // IE likes to put the inserted image in the following block-level element
      if (inserted.parentNode.childNodes.length > 1) {
        var parent = inserted.parentNode;
        var prev   = parent.previousSibling;
        if (prev.nodeName == parent.nodeName && prev.childNodes.length == 0) {
          prev.appendChild(parent.removeChild(inserted));
        } else {
          var e = Editor.current.iframe.wrap(inserted);
          prev.parentNode.insertBefore(e, parent);
        }
      }
    }
  }
});

Editor.Command.InsertTable = Editor.Command.extend({
  initialize: Prototype.emptyFunction,
  
  call: function(rows, cols) {
    rows          = 2;
    cols          = 2;
    var table     = Editor.current.iframe.document().createElement("table");
    var cellWidth = Math.round(100 / cols);

    for (var i = 0; i < rows; i++) {
      var row = table.insertRow(i);
      for (var j = 0; j < cols; j++) {
        var cell = row.insertCell(j);
        Element.setStyle(cell, { width: cellWidth + "%" });
      }
    }

    var replace = $s().commonAncestor();
    replace.parentNode.replaceChild(table, replace);
    Element.addClassName(table, "editor-focused");
  }
});

Editor.Command.CreateLink = Editor.Command.extend({
  name: "CreateLink"
});

Editor.Command.Unlink = Editor.Command.extend({
  name: "Unlink"
});
