Object.extend(Date.prototype, {
  strftime: function(format) {
    var day = this.getUTCDay(), month = this.getUTCMonth();
    var hours = this.getUTCHours(), minutes = this.getUTCMinutes();
    function pad(num) { return num.toPaddedString(2); };

    return format.gsub(/\%([aAbBcdDHiImMpSwyY])/, function(part) {
      switch(part[1]) {
        case 'a': return $w("Sun Mon Tue Wed Thu Fri Sat")[day]; break;
        case 'A': return $w("Sunday Monday Tuesday Wednesday Thursday Friday Saturday")[day]; break;
        case 'b': return $w("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")[month]; break;
        case 'B': return $w("January February March April May June July August September October November December")[month]; break;
        case 'c': return this.toString(); break;
        case 'd': return this.getUTCDate(); break;
        case 'D': return pad(this.getUTCDate()); break;
        case 'H': return pad(hours); break;
        case 'i': return (hours === 12 || hours === 0) ? 12 : (hours + 12) % 12; break;
        case 'I': return pad((hours === 12 || hours === 0) ? 12 : (hours + 12) % 12); break;
        case 'm': return pad(month + 1); break;
        case 'M': return pad(minutes); break;
        case 'p': return hours > 11 ? 'PM' : 'AM'; break;
        case 'S': return pad(this.getUTCSeconds()); break;
        case 'w': return day; break;
        case 'y': return pad(this.getUTCFullYear() % 100); break;
        case 'Y': return this.getUTCFullYear().toString(); break;
      }
    }.bind(this));
  }
});

var M = {
  get: function(key) {
    return function(target) {
      return target[key];
    }
  },
  set: function(key, value) {
    return function(target) {
      target[key] = value;
    }
  },
  is: function(key) {
    return function(target) {
      return !!target[key];
    }
  },
  isnt: function(key) {
    return function(target) {
      return !target[key];
    }
  },
  send: function(method) {
    return function(target) {
      return target[method]();
    }
  }
}

function createBorder(className) {
  var table = new Element("table", {className: className});

  var tbody = new Element("tbody");
  table.insert(tbody);

  var top = new Element("tr");
  tbody.insert(top);
  var tl = new Element("td", {className: className + " tl"});
  top.insert(tl);
  var tc = new Element("td", {className: className + " tc"});
  top.insert(tc);
  var tr = new Element("td", {className: className + " tr"});
  top.insert(tr);

  var middle = new Element("tr");
  tbody.insert(middle);
  var cl = new Element("td", {className: className + " cl"});
  middle.insert(cl);
  var content = new Element("td", {className: className + " content"});
  middle.insert(content);
  var cr = new Element("td", {className: className + " cr"});
  middle.insert(cr);

  var bottom = new Element("tr");
  tbody.insert(bottom);
  var bl = new Element("td", {className: className + " bl"});
  bottom.insert(bl);
  var bc = new Element("td", {className: className + " bc"});
  bottom.insert(bc);
  var br = new Element("td", {className: className + " br"});
  bottom.insert(br);
  return [table, content];
}

function createConfirmationDialog() {
  window.confirmationDialog = new Element("div", {id: 'confirmation_dialog', className: 'dialog'});
  confirmationDialog.hide();
  var border = createBorder('dialog_border');
  confirmationDialog.insert(border[0]);
  var contents = border[1];
  contents.insert(new Element('h2').update('Confirmation'));
  contents.insert(new Element('div', {className: 'message'}));
  var buttonContainer = new Element('div', {className: 'dialog_buttons'});
  contents.insert(buttonContainer);
  buttonContainer.insert(new Element('img', {src: '/images/cancel_button.png', onclick: 'window.confirmationDialog.close()'}));
  buttonContainer.insert(new Element('img', {src: '/images/ok_button.png', className: 'ok-button'}));
  new Popup(confirmationDialog);
}

function confirmDialog(message, fn) {
  if (!window.confirmationDialog) createConfirmationDialog();
  confirmationDialog.down('.message').update(message);
  confirmationDialog.down('.ok-button').onclick = function() {
    fn();
    confirmationDialog.close();
  };
  confirmationDialog.open();
}

function fixIEOverlay(element) {
  if (!Prototype.Browser.IE) return;
  if (!element.iframe) {
    element.iframe = new Element('iframe', {src: 'javascript:void(0)'});
    element.iframe.setStyle({
      zIndex: (element.getStyle('zIndex') - 1),
      position: element.getStyle('position'),
      top: element.getStyle('top'),
      left: element.getStyle('left'),
      bottom: element.getStyle('bottom'),
      right: element.getStyle('right'),
      width: '100%',
      height: element.getStyle('height')
    });
    element.iframe.style.filter = "alpha(opacity=0)";
    element.insert({after: element.iframe});
  }
  if (element.visible())
    element.iframe.show();
  else
    element.iframe.hide();
}

Element.addMethods('select', {
  setOptions: function(element, options, dontPreserveSelection) {
    var value = element.getValue();
    element.innerHTML = '';
    options.each(function(option) {
      var optionTag = new Element('option', {value: option[1]}).update(option[0]);
      if (value == option[1] && !dontPreserveSelection)
        optionTag.setAttribute('selected', 'selected');
      element.insert(optionTag);
    })
  }
})

Element.addMethods('form', {
  deserialize: function(element, hash) {
    for (key in hash) {
      var input = element.select('[id$=' + key + ']')[0];
      if (input && hash[key]) input.setValue(hash[key]);
    }
  }
})

var SupportLeadersCombo = Class.create({
  initialize: function(input, prototype) {
    this.input = $(input);
    this.prototype = $(prototype);
    this.combo = new Combo(this.input, {url: '/autocomplete/support_group_leaders'}, this.add.bind(this));
    this.combo.hidden = {};
  },
  add: function() {
    var hash = Object.clone(this.combo.hidden.value);
    var element = this.prototype.clone(true);
    element.down('#name').update(hash.name);
    element.down('input').value = hash.id
    element.removeClassName('prototype');
    this.prototype.insert({before: element});
    this.input.value = '';
  }
});

function cycle(table) {
  $$('#' + table + ' tr').each(function(row, index) {
    row.removeClassName('even').removeClassName('odd');
    row.addClassName(index % 2 == 0 ? 'odd' : 'even');
  });
}

function ensureInteger(input) {
  if (input) {
    var value = parseInt($F(input.id).gsub('-', ''))
    input.value = isNaN(value) ? '' : value;
  }
}
