JALHotels.ReservationModule.DynamicPackage = function(formId, hotels) {
  this.f = $('#' + formId);
  this.now = new Date();
  this.hotels = {};
}

JALHotels.ReservationModule.DynamicPackage.prototype = {

  setMultipleHotels : function(hotels) {
    $('select[name=region]', this.f).val('none');
    this.resetHotel($('select[name=yad_no0]', this.f));
    this.setHotelNone($('select[name=yad_no0]', this.f));
    this.setDates();
    this.setAirports();
    this.setHotels(hotels);
    this.addRegionListener();
    this.addHotelListener();
    this.addAirportListener();
    this.addDateListener();
    this.addSubmitListener();
  },

  setSingleHotel : function(hotel) {
    this.setDates();
    this.setAirports();
    this.addAirportListener();
    this.setHotel(hotel);
    this.addDateListener();
    this.addSubmitListener();
  },

  setDates : function() {
    var checkIn = new Date(this.now.getFullYear(), this.now.getMonth(), this.now.getDate() + 10); // 訪問日の10日後
    var checkOut = new Date(this.now.getFullYear(), this.now.getMonth(), this.now.getDate() + 11); // 訪問日の11日後
    $('select[name=dep_boardMonth]', this.f).val(checkIn.getMonth() + 1);
    this.setDayOptions($('select[name=dep_boardDay]', this.f));
    $('select[name=dep_boardDay]', this.f).val(checkIn.getDate());
    $('select[name=arr_boardMonth]', this.f).val(checkOut.getMonth() + 1);
    this.setDayOptions($('select[name=arr_boardDay]', this.f));
    $('select[name=arr_boardDay]', this.f).val(checkOut.getDate());
  },

  setAirports : function() {
    $('select[name=dep_boardAirport]', this.f).val('TYO');
    $('input[name=arr_arrivalAirport]', this.f).val('TYO');
  },

  resetHotel : function(el) {
    el.empty();
  },

  setHotelNone : function(el) {
    el.append('<option value="none">ホテルを選択してください</option>');
  },

  setHotels : function(hotels)  {
    for(var i in hotels) {
      if (this.hotels[hotels[i].region] == undefined) this.hotels[hotels[i].region] = [];
      this.hotels[hotels[i].region][i] = hotels[i].yadNo;
      this.hotels[hotels[i].yadNo] = hotels[i];
    }
  },

  setHotel : function(hotel) {
    $('input[name=yad_no0]', this.f).val(hotel.yadNo);
    $('select[name=dep_arrivalAirport]', self.f).val(hotel.dest);
    $('select[name=dep_arrivalAirport]', self.f).trigger('change');
    $('input[name=t_pref]', self.f).val(hotel.pref);
    $('input[name=t_area]', self.f).val(hotel.area);
  },

  addRegionListener : function() {
    var self = this;
    $('select[name=region]', self.f).change(function(e) {
      self.resetHotel($('select[name=yad_no0]', self.f));
      if ($(this).val() != 'none') {
        var hotelsByRegion = self.hotels[$(this).val()];
        for(var i in hotelsByRegion) {
          var hotel = self.hotels[hotelsByRegion[i]];
          var option = '<option value="' + hotel.yadNo + '">' + hotel.name + '</option>';
          $('select[name=yad_no0]', self.f).append(option);
        }
        $('select[name=yad_no0]', self.f).trigger('change');
      }
      else {
        self.setHotelNone($('select[name=yad_no0]', this.f));
        $('select[name=dep_arrivalAirport]', self.f).val('');
        $('select[name=dep_arrivalAirport]', self.f).trigger('change');
      }
    });
  },

  addHotelListener : function() {
    var self = this;
    $('select[name=yad_no0]', self.f).change(function(e) {
      $('select[name=dep_arrivalAirport]', self.f).val(self.hotels[$(this).val()].dest);
      $('select[name=dep_arrivalAirport]', self.f).trigger('change');
      $('input[name=t_pref]', self.f).val(self.hotels[$(this).val()].pref);
      $('input[name=t_area]', self.f).val(self.hotels[$(this).val()].area);
    });
  },

  addAirportListener : function() {
    var self = this;
    $('select[name=dep_boardAirport],select[name=dep_arrivalAirport]', self.f).change(function(e) {
      $('input[name=arr_arrivalAirport]', self.f).val($('select[name=dep_boardAirport]', self.f).val());
      $('input[name=arr_boardAirport]', self.f).val($('select[name=dep_arrivalAirport]', self.f).val());
    });
  },

  setDayOptions : function(el) {
    var self = this;
    var prefix = $(el).attr('name').replace('Day', '');
    var depDate = new Date(
      self.now.getFullYear(),
      $('select[name=' + prefix + 'Month]', self.f).val() - 1,
      $('select[name=' + prefix + 'Day]', self.f).val());
    if (depDate.getTime() < self.now.getTime()) {
      depDate.setFullYear(self.now.getFullYear() + 1);
    }
    var firstDayOfNextMonth = new Date(
      depDate.getFullYear(),
      $('select[name=' + prefix + 'Month]', self.f).val(), // next month
      1);
    var lastDay = (new Date(firstDayOfNextMonth -1)).getDate();
    $('select[name=' + prefix + 'Day]', self.f).empty();
    for(i = 1; i <= lastDay; i ++) {
      var option = '<option value="' + i + '">' + i + '</option>';
      $('select[name=' + prefix + 'Day]', self.f).append(option);
    }
  },

  addDateListener : function() {
    var self = this;
    $('select[name=dep_boardMonth],select[name=dep_boardDay],select[name=arr_boardMonth],select[name=arr_boardDay]', self.f).change(function(e) {
      var depDate = new Date(
        self.now.getFullYear(),
        $('select[name=dep_boardMonth]', self.f).val() - 1,
        $('select[name=dep_boardDay]', self.f).val(),23,59,59);
      var retDate = new Date(
        self.now.getFullYear(),
        $('select[name=arr_boardMonth]',self.f).val() - 1,
        $('select[name=arr_boardDay]', self.f).val(),23,59,59);
      if (depDate.getTime() < self.now.getTime()) {
        depDate.setFullYear(self.now.getFullYear() + 1);
      }
      if (retDate.getTime() < self.now.getTime()) {
        retDate.setFullYear(self.now.getFullYear() + 1);
      }
      if (depDate.getTime() < retDate.getTime()) {
        var difference = retDate.getTime() - depDate.getTime();
        difference = Math.floor(difference / (1000 * 60 * 60 * 24));
        $('input[name=period]', self.f).val(difference);
      }
    });

    // whenever the check-in date changes, update the check-out date select fields
    $('select[name=dep_boardMonth],select[name=dep_boardDay]', self.f).change(function(e) {
      var depDate = new Date(
        self.now.getFullYear(),
        $('select[name=dep_boardMonth]', self.f).val() - 1,
        $('select[name=dep_boardDay]', self.f).val(), 23, 59, 59);
      if (depDate.getTime() < self.now.getTime()) {
        depDate.setFullYear(self.now.getFullYear() + 1);
      }
      var firstDayOfNextMonth = new Date(
        depDate.getFullYear(),
        $('select[name=dep_boardMonth]', self.f).val(), // next month
        1);
      var lastDay = (new Date(firstDayOfNextMonth -1)).getDate();
      if (Number($('select[name=dep_boardDay]', self.f).val()) <= lastDay) {
        var nextDay = new Date(
          depDate.getFullYear(),
          Number($('select[name=dep_boardMonth]', self.f).val()) - 1,
          Number($('select[name=dep_boardDay]', self.f).val()) + 1);
      }
      else {
        // add logic to set check-in to the 1st of the month
        var nextDay = new Date(
          depDate.getFullYear(),
          Number($('select[name=dep_boardMonth]', self.f).val()) - 1,
          2);
      }
      $('select[name=arr_boardMonth]', self.f).val(nextDay.getMonth() + 1);
      self.setDayOptions($('select[name=arr_boardDay]', self.f));
      $('select[name=arr_boardDay]', self.f).val(nextDay.getDate());
      $('input[name=period]', self.f).val(1); // check-out changes to the next day; therefore, period is one day
    });

    $('select[name=dep_boardMonth],select[name=dep_boardDay],select[name=arr_boardMonth],select[name=arr_boardDay]', self.f).change(function(e) {
      var ciDateD = $('select[name=dep_boardDay]', self.f).val();
      var coDateD = $('select[name=arr_boardDay]', self.f).val();
      self.setDayOptions($('select[name=dep_boardDay]', self.f));
      self.setDayOptions($('select[name=arr_boardDay]', self.f));
      $('select[name=dep_boardDay]', self.f).val(ciDateD);
      $('select[name=arr_boardDay]', self.f).val(coDateD);
    });
  },

  addSubmitListener : function() {
    var self = this;
    $(self.f).submit(function(e) {
      if (($('select[name=yad_no0]', self.f).length > 0) &&
          ($('select[name=yad_no0]', self.f).val() == 'none')) {
        e.preventDefault();
      }
      if (($('select[name=dep_boardAirport]', self.f).val() == '') ||
          ($('select[name=dep_arrivalAirport]', self.f).val() == '')) {
        e.preventDefault();
      }
    });
  }
}
