has("#drawing_time", function(element) {
  Tweetaways.DrawingTime.load();
  
  element.observe("click", function(e) {
    var button = e.findElement("button");
    var input = e.findElement("input");
    
    if (input || button)
      $("wants_specific_drawing_time_yes").checked = true;
    
    if (button) {
      var segment = button.up(".segment");
      var direction = button.hasClassName("up");
      var utc = segment.up(".half").hasClassName("utc");
      
      if (segment.hasClassName("date"))
        Tweetaways.DrawingTime.changeDate(direction ? 1 : -1, utc);
      else if (segment.hasClassName("hours"))
        Tweetaways.DrawingTime.changeHours(direction ? 1 : -1, utc);
      else if (segment.hasClassName("minutes"))
        Tweetaways.DrawingTime.changeMinutes(direction ? 1 : -1, utc);
      else if (segment.hasClassName("meridian"))
        Tweetaways.DrawingTime.changeMeridian(utc);
      
      e.stop();
      return false;
    }
  });
  
  // When we get a return key for input inputs, we DON'T want
  // to submit the form. Just blur the input.
  
  element.observe("keypress", function(e) {
    var input = e.findElement("input");
    
    if (input && e.keyCode == Event.KEY_RETURN) {
      input.blur();
      
      e.stop();
      return false;
    }
  });
  
  // On keyup, try and parse the input.
  
  element.observe("keyup", function(e) {
    var input = e.findElement("input");
    
    if (input) {
      var segment = input.up(".segment");
      var utc = segment.up(".half").hasClassName("utc");
      
      if (segment.hasClassName("date"))
        Tweetaways.DrawingTime.inputDate(input.value, utc);
      else if (segment.hasClassName("hours"))
        Tweetaways.DrawingTime.inputHours(input.value, utc);
      else if (segment.hasClassName("minutes"))
        Tweetaways.DrawingTime.inputMinutes(input.value, utc);
      else if (segment.hasClassName("meridian"))
        Tweetaways.DrawingTime.inputMeridian(input.value, utc);
        
      e.stop();
      return false;
    }
  });
  
  // When one of the date inputs gets a change event,
  // call update so we have the canonical form for new input.
  // This allows people to enter strings of more than one
  // character.
  
  element.observe("change", function(e) {
    var input = e.findElement("input");
    
    if (input) {
      Tweetaways.DrawingTime.update();
      $("wants_specific_drawing_time_yes").checked = true;
        
      e.stop();
      return false;
    }
  });
});

Tweetaways.DrawingTime = {
  MONTHS: [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
  ],
  
  load: function() {
    this.date = new Date();
    this.update();
  },
  
  update: function() {
    $("drawing_time").down(".local .date input").value = this.MONTHS[this.date.getMonth()] + " " + this.date.getDate();
    $("drawing_time").down(".local .hours input").value = this.date.getHours() % 12 == 0 ? 12 : this.date.getHours() % 12;
    $("drawing_time").down(".local .minutes input").value = this.date.getMinutes() < 10 ? "0" + this.date.getMinutes() : this.date.getMinutes();
    $("drawing_time").down(".local .meridian input").value = this.date.getHours() > 11 ? "PM" : "AM";
    
    $("drawing_time").down(".utc .date input").value = this.MONTHS[this.date.getUTCMonth()] + " " + this.date.getUTCDate();
    $("drawing_time").down(".utc .hours input").value = this.date.getUTCHours() % 12 == 0 ? 12 : this.date.getUTCHours() % 12;
    $("drawing_time").down(".utc .minutes input").value = this.date.getUTCMinutes() < 10 ? "0" + this.date.getUTCMinutes() : this.date.getUTCMinutes();
    $("drawing_time").down(".utc .meridian input").value = this.date.getUTCHours() > 11 ? "PM" : "AM";
    
    $("drawing_draw_at").value = this.date.toUTCString();
  },
  
  changeDate: function(offset, utc) {
    var date = new Date(this.date);
    
    if (utc) {
      date.setUTCDate(date.getUTCDate() + offset);
    } else {
      date.setDate(date.getDate() + offset);
    }
    
    if (date.getTime() <= new Date().getTime())
      this.date = date;
    
    this.update();
  },
  
  inputDate: function(value, utc) {
    this.update();
  },
  
  changeHours: function(offset, utc) {
    var date = new Date(this.date);
    
    if (utc) {
      date.setUTCHours(date.getUTCHours() + offset);
    } else {
      date.setHours(date.getHours() + offset);
    }
    
    if (date.getTime() <= new Date().getTime())
      this.date = date;
    
    this.update();
  },
  
  inputHours: function(value, utc) {
    var date = new Date(this.date);
    
    var digits = /(\d+)/.exec(value);
    
    if (digits) {
      var hours = parseInt(digits);
      
      if (hours < 13) {
        if (utc) {
          date.setUTCHours(hours);
        } else {
          date.setHours(hours);
        }
    
        if (date.getTime() <= new Date().getTime()) {
          if (utc) {
            this.date.setUTCHours(date.getUTCHours());
          } else {
            this.date.setHours(date.getHours());
          }
        }
        
        return;
      }
    }
  },
  
  changeMinutes: function(offset, utc) {
    var date = new Date(this.date);
    
    if (utc) {
      date.setUTCMinutes(date.getUTCMinutes() + offset);
    } else {
      date.setMinutes(date.getMinutes() + offset);
    }
    
    if (date.getTime() <= new Date().getTime())
      this.date = date;
    
    this.update();
  },
  
  inputMinutes: function(value, utc) {
    var date = new Date(this.date);
    
    var digits = /(\d+)/.exec(value);
    
    if (digits) {
      var minutes = parseInt(digits);
      
      if (minutes < 60) {
        if (utc) {
          date.setUTCMinutes(minutes);
        } else {
          date.setMinutes(minutes);
        }
    
        if (date.getTime() <= new Date().getTime()) {
          if (utc) {
            this.date.setUTCMinutes(date.getUTCMinutes());
          } else {
            this.date.setMinutes(date.getMinutes());
          }
        }
        
        return;
      }
    }
  },
  
  changeMeridian: function(utc) {
    var date = new Date(this.date);
    
    if (utc) {
      if (date.getUTCHours() > 12)
        date.setUTCHours(date.getUTCHours() - 12);
      else
        date.setUTCHours(date.getUTCHours() + 12);
    } else {
      if (date.getHours() > 12)
        date.setHours(date.getHours() - 12);
      else
        date.setHours(date.getHours() + 12);
    }
    
    if (date.getTime() <= new Date().getTime())
      this.date = date;
    
    this.update();
  },
  
  inputMeridian: function(value, utc) {
    this.update();
  }
}
