String.prototype.repeat = function(length){
  var result = "";
  var self = this;
  length.times(function(){
    result += self.toString();
  });
  return result;
}
String.prototype.rjust = function(length, base){
  return ((base || " ").repeat(length) + this.toString()).slice(-length);
}

var SelectChain = new Class({
  initialize : function(parent, child, select_option, parser) {
    this.parent = $(parent);
    this.child = $(child);
    this.select_option = select_option;
    this.p = parser;
    this._default = this.child.get('value');
    var not_select = this.child.getElement('option');
    if(not_select && not_select.get('value') == "")
      this.default_set = [not_select.get('value'), not_select.get('text')];
    this.parent.addEvent('change', this.chain.bindWithEvent(this));
    //this.chain();
    window.addEvent('load', this.chain.bind(this));
  },
  chain : function(event) {
    var self = this;
    self.child.set('disabled', true);
    self.child.empty();
    if(self.default_set)
      self.child.adopt(new Element('option', {value:self.default_set[0], text:self.default_set[1]}));
    self.select_option.get(function(options){
      if(!options || options.length == 0) {
      } else {
        options = $A(options);
        self.child.set('disabled', false);
        if(self.p) {
          var result = [];
          $A(options).each(function(i){
            result.push([[i[self.p[0]]], i[self.p[1]]]);
          });
          options = $A(result);
        }
        options.each(function(i){
          var value = i[0];
          var text = i[1];
          var option = new Element('option', {value:value}).set('text', text);
          if(value == self._default) option.set('selected', true);
          self.child.adopt(option);
        });
      }
      self.child.fireEvent('change');
    });
  }
});

var SelectChainComplex = new Class({
  initialize : function(select_options) {
    this.parent = null;
    this.list_parser = null;
    this.select_options = select_options;
  },
  chain : function(child, parser) {
    if(this.parent) new SelectChain(this.parent, child, this.select_options.shift(), parser);
    this.parent = child;
    return this;
  }
});

var SelectOption = {};

SelectOption.Base = new Class({
  initialize : function(names, elms) {
    this.list_names = names;
    this.elms = $A(elms);
  },
  get : function(key, callback) {
  },
  params : function() {
    var self = this;
    var p = {};
    self.list_names.each(function(name, i){
      elm = $(self.elms[i]);
      p[name] = elm.get('value');
    });
    return p;
  }
});

SelectOption.ListOption = new Class({
  Extends : SelectOption.Base,
  initialize : function(names, elms, list) {
    this.parent(names, elms);
    this.list = $H(list);
  },
  get : function(callback) {
    callback(this.list.get("V:" + this.params()[this.list_names[0]]));
  }
});

SelectOption.RequestOption = new Class({
  Extends : SelectOption.Base,
  initialize : function(list_name, names, elms, url) {
    this.list_name = list_name;
    this.parent(names, elms);
    this.url = url;
    this.datacache = new Hash;
  },
  get : function(callback) {
    var self = this;
    var params = $H(self.params());
    if(list = self.datacache.get(params.toQueryString())){
      callback(list);
    } else {
      if(params.every(function(p){return p != ""})) {
        var req = new Request.JSON({url : self.url});
        req.addEvent('success', function(res) {
          var list = res.map(function(r){return r[self.list_name]});
          callback(list);
          self.datacache.set(params.toQueryString(), list);
        });
        req.get(params);
      } else {
        callback([]);
      }
    }
  }
});

