// namespace
var Domonet = {};

Domonet.Master = Class.create({
  initialize: function(url) {
    this.requestData(url);
  },
  requestData: function(url) {
    new Ajax.Request(url, { method: 'get', onSuccess: this.storeData.bind(this) });
  },
  storeData: function(res) {
    this.data = $H(res.responseText.evalJSON());
  }
});

Domonet.AreaMaster = Class.create(Domonet.Master, {
  initialize: function($super) {
    $super('/javascripts/areas.js');
  },

  getAreas: function(apref) {
    var areaInfo = this.data.get(apref);
    if (areaInfo == undefined) {
      return undefined;
    }
    return $H(areaInfo.areas);
  }
});

Domonet.StationMaster = Class.create(Domonet.Master, {
  initialize: function($super) {
    $super('/javascripts/stations.js');
  },

  getRoutes: function(prefectures) {
    return prefectures.map(function(p) { return this.data.get(p); }.bind(this)).flatten().inject($A([]), function(acc, e) {
      if ( ! acc.find(function(n) { return n.code == e.code; })) { acc.push(e); }
      return acc;
    }).sortBy(function(r) { return r.name; });
  },

  getStations: function(prefectures, routes) {
    var stations = $A([]);
    routes.each(function(routeCode) {
      prefectures.map(function(pref) { return pref.length == 1 ? '0' + pref : pref; }).each(function(sprefCode) {
        var routeData = this.data.get(sprefCode).find(function(route) { return route.code == routeCode; });
        if (routeData != undefined) {
          stationData = routeData.stations.findAll(function(station) { return station.spref == sprefCode; });
          stationData.each(function(e) {
            if ( ! stations.find(function(n) { return n.code == e.code; })) {
              stations.push(e);
            }
          });
        }
      }.bind(this));
    }.bind(this));
    return stations.sortBy(function(s) { return s.name; });
  }
});

Domonet.JobGroupMaster = Class.create(Domonet.Master, {
  initialize: function($super) {
    $super('/javascripts/job_groups.js');
  }
});

Domonet.PaymentMaster = Class.create(Domonet.Master, {
  initialize: function($super) {
    $super('/javascripts/payments.js');
  }
});

Domonet.FormHelper = Class.create({
  replaceOptions: function(select, options, minimum_count) {
    this.clearOptions(select);
    Element.insert(select, this.createOption({code: '', name: '選択してください'}));
    options.each(function(o) { Element.insert(select, this.createOption(o)); }.bind(this));
    this.enableSelect(select, options.size() > (minimum_count || 0));
  },

  clearOptions: function(select) {
    while (select.childNodes.length > 0) {
      select.removeChild(select.lastChild);
    }
  },

  createOption: function(o) {
    return Builder.node('option', { value: o.code }, o.name);
  },

  enableSelect: function(select, enable) {
    select.disabled = !enable;
    var options = $A(select.options);
    options.each(function(o) { o.selected = false; });
    options[0].selected = true;
  },
  valueOfSelect: function(select) {
    return $A([ $F(select) ]).flatten().reject(function(n) { return n == ''; });
  }
});

Domonet.StationFormHelper = Class.create(Domonet.FormHelper, {
  initialize: function($super, args) {
    $super();
    this.master = new Domonet.StationMaster();
    this.sprefSelect = $(args.spref);
    this.routeSelect = $(args.route);
    this.stationSelect = $(args.station);
  },

  updateRoutes: function() {
    var sprefs = this.valueOfSelect(this.sprefSelect);
    var routes = this.master.getRoutes(sprefs.map(function(spref) {
      return spref.length == 1 ? '0' + spref : spref;
    }));
    this.replaceOptions(this.routeSelect, routes);
    this.replaceOptions(this.stationSelect, $A([]));
  },

  updateStations: function() {
    var sprefs = this.valueOfSelect(this.sprefSelect);
    var routes = this.valueOfSelect(this.routeSelect);

    this.replaceOptions(this.stationSelect, this.master.getStations(sprefs, routes));
  }
});

Domonet.AreaFormHelper = Class.create(Domonet.FormHelper, {
  initialize: function($super, args) {
    $super();
    this.master = new Domonet.AreaMaster();
    this.prefSelect = $(args.pref);
    this.areaSelect = $(args.area);
    this.routeSelect = $(args.route);
  },

  updateAreas: function() {
    var apref = $F(this.prefSelect);
    if (apref.length == 1) {
      apref = '0' + apref;
    }
    var areas = this.master.getAreas(apref);

    var options = $A([]);
    if (areas != undefined) {
      areas.keys().inject(options, function(acc, e) {
        acc.push({code: e, name: areas.get(e)}); return acc;
      });
      options = options.sortBy(function(a) { return parseInt(a.code.gsub(/\*/, '9')); });
    }
    this.replaceOptions(this.areaSelect, options, 1);
  }
});

// job_groups.js
// "group_code1": {
//   "name": "group_name1",
//   "jobs": { "job_code11": "name11", "job_code12": "name12", ... }
// }, 
// "group_code2": {
//   "name": "group_name2",
//   "jobs": { "job_code21": "name21", "job_code22": "name22", ... }
// }, ... 
Domonet.JobGroupFormHelper = Class.create(Domonet.FormHelper, {
  initialize: function($super, args) {
    $super();
    this.master = new Domonet.JobGroupMaster();
    this.groupSelect = $(args.group);
    this.jobInGroupElement = $(args.jobInGroup);
    this.columns = args.columns;
  },

  updateJobs: function() {
    var group = this.master.data.get($F(this.groupSelect));

    var container = this.jobInGroupElement;
    if (container == undefined) {
      return;
    }

    while (container.childNodes.length > 0) {
      container.removeChild(container.lastChild);
    }
    if (group == undefined) {
      return;
    }
    var jobs = $H(group.jobs);
    var i = 0;
    jobs.keys().sort().inGroupsOf(this.columns).each(function(jobCodesInRow) {
      container.insert(Builder.node('ul',
        jobCodesInRow.collect(function(jobCode) {
          var item = $(Builder.node('li'));
          if (i % jobCodesInRow.size() == jobCodesInRow.size() - 1) {
            item.addClassName('lastchild');
          }
          var label = $(Builder.node('label'));
          if (jobCode != undefined) {
            var checkbox = Builder.node('input', { type: 'checkbox', id: 'job_' + (++i), value: jobCode });
            checkbox.name = 'job[]'; // なぜかidと同じになってしまう……
            label.insert(checkbox);
            label.insert(jobs.get(jobCode));
          }
          item.insert(label);
          return item;
        }.bind(this))));
    }.bind(this));
  }
});

Domonet.PaymentFormHelper = Class.create(Domonet.FormHelper, {
  initialize: function($super, args) {
    $super();
    this.master = new Domonet.PaymentMaster();
    this.paymentTypeSelect = $(args.paymentType);
    this.minimumPaymentSelect = $(args.minimumPayment);
  },

  updatePayments: function() {
    var options = null;
    var paymentType = this.master.data.get(this.paymentTypeSelect.value);

    if (paymentType == undefined) {
      options = $A([]);
    } else {
      options = $A(paymentType.ranges).reject(function(r) {
        return r[0] == '10' || r[0] == '9999';
      }).map(function(r) {
        return { code: r[0], name: r[1] + '以上' };
      });
    }
    this.replaceOptions(this.minimumPaymentSelect, options);
  }
});

Event.observe(window, 'load', function() {
  var kw = $('keyword');
  if (kw == undefined) {
    return;
  }
  var promptString = '絞り込むフリーワードを入力';
  var promptColor = '#999';
  var defaultColor = '#000';
  if (kw.value == promptString) {
    kw.style.color = promptColor;
  } else {
    kw.style.color = defaultColor;
  }
  Event.observe(kw, 'click', function(f) {
    if (kw.value == promptString) {
      kw.value = '';
    }
    kw.style.color = defaultColor;
  });
  Event.observe($('submit'), 'click', function(b) {
    if (kw.value == promptString) {
      kw.value = '';
    }
    kw.style.color = defaultColor;
  });
});

