(function() {

  this.def_class('Selector',DObject,function(__scope,__class){

    this.proxy = function(method) {
      if (this.prototype[method]) return;
      return this.define_method(method, function() {
        var args;
        var _this = this;
        args = arguments;
        return this.each(function(_tag) {
          if (_tag[method]) return _tag[method].apply(_tag, args);
        });
      });
    };__singleton_method_added(this,"proxy");

    this.first = function(selector, scope) {
      var sel;
      sel = new (__ctor(this))(selector, scope);
      return sel.first();
    };__singleton_method_added(this,"first");

    this.__ctor__ = function Selector(expressions, scope) {
      this["@expressions"] = expressions;
      this["@scope"] = scope || $doc;
      this["@lazy"] = true;
    }; this.__ctor__.prototype = this.prototype;;

    this.prototype.query = function() {
      var expr, i, l, part, queries, _i, _len, _primitive, _ref;
      if (this["@query"]) return this["@query"];
      queries = [];
      _ref = this["@expressions"];
      for (_i = 0, _len = (_ref.len ? _ref.len() : _ref.length),_primitive = (_ref instanceof Array || !_ref.at); _i < _len; _i++) {
        expr = _primitive ? _ref[_i] : _ref.at(_i);
        i = 0;
        l = expr.length;
        while (i < l) {
          part = expr[i];
          if (/^\w/.test(part)) {
            expr[i] = "." + part + "_";
          } else if (part === '[') {
            expr[i + 3] = ("" + expr[i + 3]).quoted();
            i += 3;
          } else if (part === '.') {
            i++;
          } else if (part === '#') {
            i++;
          }
          i++;
        }
        queries.push(expr.join(""));
      }
      return this["@query"] = queries.join(",");
    }; __method_added(this,"query");

    this.prototype.first = function() {
      if (this["@lazy"]) {
        return $__tag(this["@first"] || (this["@first"] = this["@scope"].querySelector(this.query())));
      } else {
        return $__tag(this.nodes()[0]);
      }
    }; __method_added(this,"first");

    this.prototype.nodes = function() {
      this["@nodes"] || (this["@nodes"] = this["@scope"].querySelectorAll(this.query()));
      this["@lazy"] = false;
      return this["@nodes"];
    }; __method_added(this,"nodes");

    this.prototype["any?"] = function() {
      return this["@first"] || this.nodes().length > 0;
    }; __method_added(this,"any?");

    this.prototype.count = function() {
      return this.nodes().length;
    }; __method_added(this,"count");

    this.prototype.size = function() {
      return this.nodes().length;
    }; __method_added(this,"size");

    this.prototype.at = function(idx) {
      return this.nodes()[idx];
    }; __method_added(this,"at");

    this.prototype.each = function(block) {
      var i, node, _len, _primitive, _ref;
      _ref = this.nodes();
      for (i = 0, _len = (_ref.len ? _ref.len() : _ref.length),_primitive = (_ref instanceof Array || !_ref.at); i < _len; i++) {
        node = _primitive ? _ref[i] : _ref.at(i);
        block($__tag(node), i);
      }
      return this;
    }; __method_added(this,"each");

    this.prototype["[]"] = function(index) {
      return $__tag(this.nodes()[index]);
    }; __method_added(this,"[]");

  });

  this.def_tag('NODE_TAG',"NODE_TAG",function(__scope,__class){

    if(!this.__ctor__){this.__ctor__= function NODE_TAG(){__class.__super__.__ctor__.apply(this, arguments)}; this.__ctor__.prototype = this.prototype; }

    this.method_added = function(name) {
      return __scope.Selector.proxy(name);
    };__singleton_method_added(this,"method_added");

  });

}).call($$base);

