class Class

def self.new(sup = Object, &block)

def self.new(sup = Object, &block)
  %x{
    function AnonClass(){};
    var klass   = Opal.boot(sup, AnonClass)
    klass._name = nil;
    sup.$inherited(klass);
    if (block !== nil) {
      var block_self = block._s;
      block._s = null;
      block.call(klass);
      block._s = block_self;
    }
    return klass;
  }
end

def alias_method(newname, oldname)

def alias_method(newname, oldname)
  `#{self}.prototype['$' + newname] = #{self}.prototype['$' + oldname]`
  self
end

def allocate

def allocate
  %x{
    var obj = new #{self};
    obj._id = Opal.uid();
    return obj;
  }
end

def ancestors

def ancestors
  %x{
    var parent = #{self},
        result = [];
    while (parent) {
      result.push(parent);
      parent = parent._super;
    }
    return result;
  }
end

def append_features(klass)

def append_features(klass)
  %x{
    var module = #{self};
    if (!klass.$included_modules) {
      klass.$included_modules = [];
    }
    for (var idx = 0, length = klass.$included_modules.length; idx < length; idx++) {
      if (klass.$included_modules[idx] === module) {
        return;
      }
    }
    klass.$included_modules.push(module);
    if (!module.$included_in) {
      module.$included_in = [];
    }
    module.$included_in.push(klass);
    var donator   = module.prototype,
        prototype = klass.prototype,
        methods   = module._methods;
    for (var i = 0, length = methods.length; i < length; i++) {
      var method = methods[i];
      prototype[method] = donator[method];
    }
    if (prototype._smethods) {
      prototype._sdonate(methods);
    }
    if (klass.$included_in) {
      klass._donate(methods.slice(), true);
    }
  }
  self
end

def attr_accessor(*names)

def attr_accessor(*names)
  attr_reader *names
  attr_writer *names
end

def attr_reader(*names)

def attr_reader(*names)
  %x{
    var proto = #{self}.prototype;
    for (var i = 0, length = names.length; i < length; i++) {
      (function(name) {
        proto[name] = nil;
        proto['$' + name] = function() {
          return this[name];
        };
      })(names[i]);
    }
  }
  nil
end

def attr_writer(*names)

def attr_writer(*names)
  %x{
    var proto = #{self}.prototype;
    for (var i = 0, length = names.length; i < length; i++) {
      (function(name) {
        proto[name] = nil;
        proto['$' + name + '='] = function(value) {
          return this[name] = value;
        };
      })(names[i]);
    }
  }
  nil
end

def define_method(name, &block)

def define_method(name, &block)
  %x{
    if (block === nil) {
      no_block_given();
    }
    var jsid    = '$' + name;
    block._jsid = jsid;
    block._sup  = #{self}.prototype[jsid];
    block._s    = null;
    #{self}.prototype[jsid] = block;
    #{self}._donate([jsid]);
    return nil;
  }
end

def include(*mods)

def include(*mods)
  %x{
    var i = mods.length - 1, mod;
    while (i >= 0) {
      mod = mods[i];
      i--;
      if (mod === #{self}) {
        continue;
      }
      #{ `mod`.append_features self };
      #{ `mod`.included self };
    }
    return #{self};
  }
end

def included(mod)

def included(mod)
end

def inherited(cls)

def inherited(cls)
end

def instance_methods(include_super = false)

def instance_methods(include_super = false)
  %x{
    var methods = [], proto = #{self}.prototype;
    for (var prop in #{self}.prototype) {
      if (!include_super && !proto.hasOwnProperty(prop)) {
        continue;
      }
      if (prop.charAt(0) === '$') {
        methods.push(prop.substr(1));
      }
    }
    return methods;
  }
end

def module_eval(&block)

def module_eval(&block)
  %x{
    if (block === nil) {
      no_block_given();
    }
    var block_self = block._s, result;
    block._s = null;
    result = block.call(#{self});
    block._s = block_self;
    return result;
  }
end

def name

def name
  `#{self}._name`
end

def new()

def new()
  %x{
    var args = __slice.call(arguments);
    var obj = new #{self};
    obj._id = Opal.uid();
    obj.$initialize.apply(obj, args);
    return obj;
  }
end

def public(*)

def public(*)
end

def superclass

def superclass
  %x{
    return #{self}._super || nil;
  }
end