// Generated by CoffeeScript 1.12.7 (function() {

var XMLAttribute, XMLElement, XMLNode, isFunction, isObject, ref,
  extend = 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; },
  hasProp = {}.hasOwnProperty;

ref = require('./Utility'), isObject = ref.isObject, isFunction = ref.isFunction;

XMLNode = require('./XMLNode');

XMLAttribute = require('./XMLAttribute');

module.exports = XMLElement = (function(superClass) {
  extend(XMLElement, superClass);

  function XMLElement(parent, name, attributes) {
    XMLElement.__super__.constructor.call(this, parent);
    if (name == null) {
      throw new Error("Missing element name");
    }
    this.name = this.stringify.eleName(name);
    this.attributes = {};
    if (attributes != null) {
      this.attribute(attributes);
    }
    if (parent.isDocument) {
      this.isRoot = true;
      this.documentObject = parent;
      parent.rootObject = this;
    }
  }

  XMLElement.prototype.clone = function() {
    var att, attName, clonedSelf, ref1;
    clonedSelf = Object.create(this);
    if (clonedSelf.isRoot) {
      clonedSelf.documentObject = null;
    }
    clonedSelf.attributes = {};
    ref1 = this.attributes;
    for (attName in ref1) {
      if (!hasProp.call(ref1, attName)) continue;
      att = ref1[attName];
      clonedSelf.attributes[attName] = att.clone();
    }
    clonedSelf.children = [];
    this.children.forEach(function(child) {
      var clonedChild;
      clonedChild = child.clone();
      clonedChild.parent = clonedSelf;
      return clonedSelf.children.push(clonedChild);
    });
    return clonedSelf;
  };

  XMLElement.prototype.attribute = function(name, value) {
    var attName, attValue;
    if (name != null) {
      name = name.valueOf();
    }
    if (isObject(name)) {
      for (attName in name) {
        if (!hasProp.call(name, attName)) continue;
        attValue = name[attName];
        this.attribute(attName, attValue);
      }
    } else {
      if (isFunction(value)) {
        value = value.apply();
      }
      if (!this.options.skipNullAttributes || (value != null)) {
        this.attributes[name] = new XMLAttribute(this, name, value);
      }
    }
    return this;
  };

  XMLElement.prototype.removeAttribute = function(name) {
    var attName, i, len;
    if (name == null) {
      throw new Error("Missing attribute name");
    }
    name = name.valueOf();
    if (Array.isArray(name)) {
      for (i = 0, len = name.length; i < len; i++) {
        attName = name[i];
        delete this.attributes[attName];
      }
    } else {
      delete this.attributes[name];
    }
    return this;
  };

  XMLElement.prototype.toString = function(options) {
    return this.options.writer.set(options).element(this);
  };

  XMLElement.prototype.att = function(name, value) {
    return this.attribute(name, value);
  };

  XMLElement.prototype.a = function(name, value) {
    return this.attribute(name, value);
  };

  return XMLElement;

})(XMLNode);

}).call(this);