;(function($, window, document, undefined) {

var Resin = (function() {
  
  var ResinClass,
      ResinObject;
  
  var __toString = Object.prototype.toString,
      __hasProp = Object.prototype.hasOwnProperty,
      __slice = Array.prototype.slice,
      __makeArray = function(nonarray) { return __slice.call(nonarray); },
      __isArray = function(obj) { return __toString.call(obj) === '[object Array]'; },
      __isFunction = function(obj) { return __toString.call(obj) === '[object Function]'; };
  
  // class
  
  var initializing = false;
  
  ResinClass = function() {};
  
  ResinClass.create = function(base, obj) {
    var cls, proto, base_proto;
    
    if (typeof obj === 'undefined') {
      obj = base;
      base = ResinObject;
    }
    
    initializing = true;
    proto = new base();
    initializing = false;
    
    base_proto = base.prototype;
    
    for (var prop in obj) {
      if (__hasProp.call(obj, prop)) {
        proto[prop] = __isFunction(obj[prop])
          ? (function(name, fn) {
              return function() {
                var tmp, ret;
                tmp = this.__super__;
                this.__super__ = base_proto;
                ret = fn.apply(this, arguments);
                this.__super__ = tmp;
                return ret;
              };
            })(prop, obj[prop])
          : obj[prop];
      }
    }
    
    cls = function() {
      if (!initializing && this.__init__) {
        this.__init__.apply(this, arguments);
      }
    };
    cls.prototype = proto;
    cls.prototype.__super__ = base_proto;
    cls.prototype.constructor = cls;
    
    return cls;
  };
  
  // object
  
  ResinObject = function() {};
  
  ResinObject.proxy = function(fn) {
    var cls = this;
    return function() {
      return fn.apply(cls, arguments);
    };
  };
  
  ResinObject.prototype = {
    __init__: function() {}
  };
  
  // api
  
  return {
    Class: ResinClass,
    Object: ResinObject
  };

})();

$.Resin = window.Resin = Resin;

$.Class = function(base, obj) {
  return $.Resin.Class.create(base, obj);
};

})(jQuery, this, this.document);
