// $Id: discuss.js 261 2009-05-21 07:40:51Z twodash $
var Discuss = {};
Discuss.Root = Class.create({
  initialize: function() {
    this.messages = new Discuss.Messages();
    Object.extend(this, this.messages.getProfile());

    this.members = new Discuss.Members();
    this.calendar = new Discuss.Calendar(this);

    //periodical update scheduler
    this.scheduler = new Discuss.Scheduler(this);

    //ajax request processor
    this.join = new Discuss.Join(this);
    this.open = new Discuss.Open(this);
    this.post = new Discuss.Post(this);
    this.leave = new Discuss.Leave();
    this.log = new Discuss.Log(this);

    // set event listeners.
    Event.observe('discuss', 'click', this.onClickDiscuss.bindAsEventListener(this));
    Event.observe('discuss_tarea', 'keypress', this.onKeypressTarea.bindAsEventListener(this));
    Event.observe('discuss_tarea', 'keyup', this.onKeyupTarea);
    if (Prototype.Browser.Opera) {
      Event.observe(window, 'unload', this.leaveAway.bindAsEventListener(this));
    } else {
      Event.observe(window, 'beforeunload', this.leaveAway.bindAsEventListener(this));
    }

    this.mode = -1;
    this.context = '';
    this.idle = true;
    this.currentMessage = '';
    if (!this.checkContext() && this.discuss_id != undefined) {
      this.goDiscussion();
      this.showClient();
      this.showDiscussion();
    }
  },

  checkContext: function() {
    var hash = window.location.hash;
    if (hash.length > 0 && hash != this.context) {
      this.context = hash;
      var hashArray = hash.split(":");
      var start = 0;
      var mode = 0;
      var id = 0;
      //break intentionally omitted
      switch (hashArray.length) {
      case 4:
        start = hashArray[3] - 0;
      case 3:
        mode = hashArray[2] - 0;
      case 2:
        id = hashArray[1] - 0;
      }

      if (id > 0) {
        this.discuss_id = id;
        if (mode != 1) {
          this.goDiscussion();
          this.showClient();
          this.showDiscussion();
        } else {
          this.open.request(start);
          this.showLog();
          this.showClient();
        }
        return true;
      }
    }
    return false;
  },

  showClient: function() {
    Element.hide('discuss_list');
    $('discuss_subject').innerHTML = this.discussion[this.discuss_id];
    $('discuss_client').style.display = 'block';
    this.calendar.show();
  },

  goDiscussion: function() {
    this.mode = 0;
    this.messages.clear();
    if (this.nobody) {
      this.messages.anchor('welcome', this.nobody);
    } else {
      this.join.request({discuss_id: this.discuss_id});
    }
  },

  showDiscussion: function() {
    $('discuss_send').disabled = true;
    var form = $('discuss_form');
    if (!Element.visible(form)) {
      Element.show(form);
    }
    $('discuss_toggle').innerHTML = 'Looking on chat room';
    $('discuss_tarea').focus();
  },

  showLog: function() {
    this.mode = 1;
    Element.hide('discuss_form');
    $('discuss_toggle').innerHTML = 'Enter chat room';
  },

  readyDiscussion: function(key) {
    window.location.hash = '#d:' + this.discuss_id;
    this.scheduler.start(this.discuss_id, key);
    this.idle = false;
    if (this.currentMessage.length > 0) {
      this.postRequest(this.currentMessage);
    }
  },

  readyLog: function(key) {
    window.location.hash = ['#d:', this.discuss_id, ':1:', this.messages.current].join('');
  },

  ////////////////////
  // Event listener //
  ////////////////////

  onKeypressTarea: function(e) {
    if (e.keyCode == Event.KEY_RETURN) {
      this.sendMessage(e.target.value);
      Event.stop(e);
    }
  },

  onKeyupTarea: function(e) {
    if(!this.idle && e.target.value.length > 0){
      $('discuss_send').disabled = false;
    } else {
      $('discuss_send').disabled = true;
    }
  },

  onClickDiscuss: function(e) {
    switch (true) {
    case (e.target.id == 'discuss_send'):
      var tarea = $('discuss_tarea');
      this.sendMessage(tarea.value);
      tarea.focus();
      break;

    case (e.target.id == 'discussLprev'):
      if (this.messages.min > 1) {
        if (this.mode == 0) {
          this.leaveAway();
          this.showLog();
        }
        this.log.request({d:this.discuss_id, s:this.messages.min, p:1}, 0);
      }
      break;

    case (e.target.id == 'discussLnext'):
      this.log.request({d:this.discuss_id, s:this.messages.max}, 1);
      break;

    case (e.target.id == 'discussLerror'):
      this.join.request({discuss_id: this.discuss_id});
      break;

    case (e.target.id == 'discuss_messages'):
      if (this.mode == 1) {
        var cy = e.offsetY || e.layerY ;
        if (cy > e.target.scrollHeight - 25) {
          this.log.request({d:this.discuss_id, s:this.messages.max}, 1);
        }
      }
      break;

    case (e.target.id == 'discuss_toggle'):
      if (this.mode == 1) {
        this.goDiscussion();
        this.showDiscussion();
      } else {
        this.leaveAway();
        if (this.nobody) {
          this.calendar.reset();
          this.open.request();
        } else {
          this.calendar.requestDays();
        }
        this.showLog();
      }
      break;

    case (e.target.id == 'discuss_close'):
      this.mode = -1;
      this.leaveAway();
      this.calendar.hide();
      Element.hide('discuss_client');
      Element.show('discuss_list');
      window.location.hash = '#';
      break;

    case (e.target.id.substr(0, 8) == 'subject_'):
      this.discuss_id = e.target.id.substr(8);
      this.goDiscussion();
      this.showClient();
      this.showDiscussion();
      break;

    case (e.target.id.substr(0, 8) == 'loglink_'):
      this.discuss_id = e.target.id.substr(8);
      this.messages.clear();
      this.open.request();
      this.showLog();
      this.showClient();
      break;
    }
    return false;
  },

  sendMessage: function(input) {
    input = input.replace(/^\s+|\s+$/g, '');
    if (input.length > 0) {
      if (this.nobody) {
        this.nobody = false;
        this.join.request({discuss_id: this.discuss_id, guestname: input});

        $('discuss_tarea').value = '';
        $('discuss_send').disabled = true;
      } else if (!this.idle) {
        this.postRequest(input);
        this.currentMessage = input;
        $('discuss_tarea').value = '';
        $('discuss_send').disabled = true;
      }
      this.idle = true;
    }
  },

  postRequest: function(input) {
    var colors = $A(document.getElementById('discuss_buttons').getElementsByTagName('input'));
    var color = 0;
    for (var i = 0, length = colors.length; i < length; i++) {
      if (colors[i].checked) {
        color = colors[i].value;
        break;
      }
    }
    this.post.request({d: this.discuss_id, m: input, c: color});
  },

  onSuccessSendMessage: function() {
    this.currentMessage = '';
    this.idle = false;
    if($('discuss_tarea').value.length > 0){
      $('discuss_send').disabled = false;
    }
  },

  dailyLog: function(parameters) {
    if (this.mode == 0) {
      this.leaveAway();
      this.showLog();
    }
    parameters.d = this.discuss_id;
    this.log.request(parameters, 2);
  },

  leaveAway: function() {
    if (this.scheduler.underContinuation) {
      this.leave.request({d:this.discuss_id});
      this.scheduler.stop();
    }
  },

  onError: function() {
    this.scheduler.stop();
    this.messages.anchor('error', 'Some problem occurred. Click here to restart.');
  }
});//end of Discuss.Root


/*******************************************************************************
 * Ajax Periodical Request Controller ******************************************
 ******************************************************************************/
Discuss.Scheduler = Class.create({

  frequency: 1.5,//(sec)
  decay: 1,

  initialize: function(root) {
    var options = {
      onComplete: this._onComplete.bind(this)
    }
    this.diff = Object.extend(new Discuss.Diff(root), options);
    this.stay = Object.extend(new Discuss.Stay(root), options);
    this.renew = Object.extend(new Discuss.Renew(root), options);

    this.stay_frequency = root.stay_frequency * 1000;
    this.updater = {options:{}};
  },

  start: function(discuss_id, key) {
    this._decay = 1;
    this.underContinuation = true;
    this.renew.postBody = $H({d:discuss_id}).toQueryString(),
    this.stay.postBody = $H({d:discuss_id}).toQueryString(),
    this.reset(key);

    this._onComplete();
  },

  reset: function(key) {
    Object.extend(this.diff, key);
    this.expiry_time = key.expiry_time;
    this.nextStay = new Date().getTime() + this.stay_frequency;
  },

  stop: function() {
    this.underContinuation = false;
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
  },

  _onComplete: function() {
    this.timer = this.onTimerEvent.bind(this).delay(this._decay * this.frequency);
  },

  onTimerEvent: function() {
    var now = new Date().getTime();
    if (now >= this.expiry_time) {
      this.updater = this.renew.request();
    }
    else if (now >= this.nextStay) {
      this.updater = this.stay.request();
      this.nextStay = now + this.stay_frequency;
    }
    else {
      this.updater = this.diff.request();
    }
  },

  doDecay: function() {
    this._decay = this._decay * this.decay;
  }
});//end of Discuss.Scheduler

////////////////////////////////////////////////////////////////////////////////
// Ajax Request Proccesor
////////////////////////////////////////////////////////////////////////////////
Discuss.Diff = Class.create({
  initialize: function(root) {
    this.root = root;
    this.method = 'get';
    this.on200 = this._onSuccess.bind(this);
    this.on206 = this._onSuccess.bind(this);
    this.onFailure = this._onFailure.bind(this);
    this.on304 = this._on304.bind(this);
    this.on404 = this._on404.bind(this);
  },

  request: function() {
    this.requestHeaders = {"Accept-Encoding":""};
    if (this.size > 0) {
      this.requestHeaders.Range = ['bytes=', this.size, '-'].join('');
    }
    if (this.mod) {
      this.requestHeaders["If-Modified-Since"] = this.mod;
    }
    var updater = new Ajax.Request(this.url, this);
    return updater;
  },

  _onSuccess: function(response, headerJSON) {
    response._header = function(name) {
      try { return this.getResponseHeader(name) } catch (e) { return null };
    }
    var last = response._header('Last-Modified');
    var ran = response._header('Content-Range');
    var len = response._header('Content-Length');
    var size_t = 0;

    if(last) this.mod = last;
    if(ran) {
      size_t = (ran.match(/\/(\d+)$/))[1];
    } else if (len) {
      size_t = len - 0;
    }
    if (size_t > this.size) {
      this.size = size_t;
      this.root.scheduler._decay = 1;
      var lines = response.responseText.split("\n");
      lines.each(this.update, this);
    } else if (size_t > 0) {
      this.root.scheduler.expiry_time = 0;
    }
  },

  update: function(line_in_response) {
    try {
      var response_object = line_in_response.evalJSON();
    } catch (e) {
      return;
    }
    if (typeof response_object != 'object') {
        this.root.messages.anchor('message', 'Log data is not valid. Check response text or log file, if possible.');
        return;
    }
    switch(response_object.x) {
    case 'J':
      this.root.members.join_on(response_object);
      break;
    case 'L':
      this.root.members.remove(response_object);
      break;
    default:
      this.root.messages.write(response_object);
	play();
    }
  },

  _onFailure: function() {
    this.root.onError();
  },

  _on304: function() {
    this.root.scheduler.doDecay();
  },

  _on404: function() {
    this.root.scheduler.expiry_time = 0;
  }
});

Discuss.Stay = Class.create({
  url: './index.php/stay',

  initialize: function(root) {
    this.root = root;
    this.onSuccess = this._onSuccess.bind(this);
    this.onFailure = this._onFailure.bind(this);
  },

  request: function() {
    var updater = new Ajax.Request(this.url, this);
    return updater;
  },

  _onSuccess: function(response, headerJSON) {
    var members = (headerJSON) ? headerJSON : response.responseJSON;
    if (members) {
      this.root.members.seat(members);
    }
  },

  _onFailure: function() {
    this.root.onError();
  }
});

Discuss.Renew = Class.create({
  url: './index.php/renew',

  initialize: function(root) {
    this.root = root;
    this.onSuccess = this._onSuccess.bind(this);
    this.onFailure = this._onFailure.bind(this);
  },

  request: function() {
    var updater = new Ajax.Request(this.url, this);
    return updater;
  },

  _onSuccess: function(response, headerJSON) {
    var ticket = (headerJSON) ? headerJSON : response.responseJSON;

    if (ticket) {
      ticket.message.each(this.root.messages.write, this.root.messages);
      this.root.members.seat(ticket.attendee);
      this.root.scheduler.reset(ticket.key);
    } else {
      this.root.scheduler.stop();
    }
  },

  _onFailure: function() {
    this.root.onError();
  }
});

Discuss.Join = Class.create({
  initialize: function(root) {
    this.root = root;
    this.onSuccess = this._onSuccess.bind(this);
  },

  request: function(postBody) {
    this.postBody = $H(postBody).toQueryString();
    var request = new Ajax.Request('./index.php/join', this);
  },

  _onSuccess: function(response, headerJSON) {
    var ticket = (headerJSON) ? headerJSON : response.responseJSON;

    if (ticket) {
      if (ticket.key) {
        if (ticket.message.length > 0) {
          this.root.messages.open(ticket.message);
        }
        this.root.members.seat(ticket.attendee);
        this.root.readyDiscussion(ticket.key);
      } else {
        this.root.messages.write(ticket);
      }
    } else {
      window.status = response.responseText.slice(0, 30);
    }
  },

  onFailure: function(response, headerJSON) {
    window.status = ['HTTP ', response.status, ' ', response.statusText].join('');
  }
});

Discuss.Open = Class.create({
  initialize: function(root) {
    this.root = root;
    this.onSuccess = this._onSuccess.bind(this);
  },

  request: function(start) {
    var postBody = {discuss_id: this.root.discuss_id};
    if (start) {
      postBody.s = start;
      this.mode = 1;
    } else {
      this.mode = 0;
    }
    this.postBody = $H(postBody).toQueryString();
    var request = new Ajax.Request('./index.php/open', this);
  },

  _onSuccess: function(response, headerJSON) {
    if (response.responseJSON) {
      if (this.mode) {
        this.root.messages.render(response.responseJSON.message);
      } else {
        this.root.messages.open(response.responseJSON.message, 1);
      }
      this.root.calendar.render(response.responseJSON.days);
      this.root.readyLog();
    }
  },

  onFailure: function(response, headerJSON) {
    window.status = ['HTTP ', response.status, ' ', response.statusText].join('');
  }
});

Discuss.Leave = Class.create({
  request: function(postBody) {
    var options = {
      postBody: $H(postBody).toQueryString()
    }
    var request = new Ajax.Request('./index.php/leave', options);
  }
});

Discuss.Post = Class.create({
  initialize: function(root) {
    this.root = root;
    this.onSuccess = this._onSuccess.bind(this);
    this.onFailure = this._onFailure.bind(this);
  },

  request: function(postBody) {
    this.postBody = $H(postBody).toQueryString();
    var request = new Ajax.Request('./index.php/post', this);
  },

  _onSuccess: function(response, headerJSON) {
    this.root.onSuccessSendMessage();
    var message = (headerJSON) ? headerJSON : response.responseJSON;
    this.root.messages.write(message);
  },

  _onFailure: function() {
    this.root.onError();
  }
});

Discuss.Log = Class.create({
  initialize: function(root) {
    this.root = root;
    this.method = 'get';
    this.onSuccess = this._onSuccess.bind(this);
    this.onFailure = this._onFailure.bind(this);
  },

  request: function(parameters, mode) {
    this.mode = mode;
    this.parameters = $H(parameters).toQueryString();
    var request = new Ajax.Request('./index.php/message', this);
  },

  _onSuccess: function(response, headerJSON) {
    var messages = (headerJSON) ? headerJSON : response.responseJSON;
    if (!messages || messages.length == 0) return;

    switch (this.mode) {
    case 0:
      this.root.messages.scroll(messages, true);
      break;
    case 1:
      this.root.messages.scroll(messages, false);
      break;
    case 2:
      this.root.messages.render(messages);
      break;
    }
    this.root.readyLog();
  },

  _onFailure: function() {
    this.root.messages.write({m:'Some problem occurred. Please try again later.'});
  }
});

/*******************************************************************************
* Interface ********************************************************************
********************************************************************************/
Discuss.Members = Class.create({
  initialize: function() {
    this.container = document.getElementById('discuss_members');
  },

  clear: function() {
    this.container.innerHTML = '';
  },

  seat: function(members) {
    var stack = $A(this.container.getElementsByTagName('span'));

    for (var i = 0, length = stack.length; i < length; i++) {
      if (!this.under_stay(stack[i], members)) {
        this.container.removeChild(stack[i]);
      }
    }

    for (var i = 0, length = members.length; i < length; i++) {
      this.add(members[i]);
    }
  },

  under_stay: function(stack, members) {
    for (var i = 0, length = members.length; i < length; i++) {
      if (members[i] && 'discuss_member_' + members[i].id == stack.id) {
        members.splice(i, 1);
        return true;
      }
    }
    return false;
  },

  join_on: function(object) {
    var stack = $A(this.container.getElementsByTagName('span'));

    for (var i = 0, length = stack.length; i < length; i++) {
      if (stack[i].id == 'discuss_member_' + object.id) {
        return;
      }
    }
    this.add(object);
  },

   add: function(object) {
    var element = document.createElement('span');
    element.id = 'discuss_member_' + object.id;
    element.appendChild(document.createTextNode(object.u));
    this.container.appendChild(element);
  },

  remove: function(object) {
    var stack = $A(this.container.getElementsByTagName('span'));
    for (var i = 0, length = stack.length; i < length; i++) {
      if (stack[i].id == 'discuss_member_' + object.id) {
        this.container.removeChild(stack[i]);
        break;
      }
    }
  }
});

Discuss.Messages = Class.create({
  initialize: function() {
    this.container = document.getElementById('discuss_messages');
    this.prefix = 'discuss_message_';
  },

  getProfile: function() {
    var profile = this.container.innerHTML.evalJSON();
    this.clear();
    return profile;
  },

  clear: function() {
    this.reference = null;
    this.container.innerHTML = '';
  },

  reset: function() {
    this.min = this.max = this.current = 0;
    this.reference = null;
    this.container.innerHTML = '';
    this.scrollHeight = 0;
  },

  open: function(objects, mode) {
    this.reset();
    this.desc = true;
    this.anchor('prev', '<< prev <<');
    objects.each(this.add, this);
    if (mode == 1) {
      this.container.scrollTop = 0;
    } else {
      this.container.scrollTop = this.container.scrollHeight - this.container.offsetHeight;
    }
    this.current = objects[objects.length - 1].id;
    this.scrollHeight = this.container.scrollHeight;
  },

  render: function(objects) {
    this.reset();
    this.desc = false;
    this.anchor('prev', '<< prev <<');
    objects.each(this.add, this);
    this.anchor('next', '>> next >>');
    this.container.scrollTop = 0;
    this.current = objects[0].id;
    this.scrollHeight = this.container.scrollHeight;
  },

  scroll: function(objects, desc) {
    this.desc = desc;
    objects.each(this.add, this);
    if (desc) {
      this.container.scrollTop = this.container.scrollTop - this.container.offsetHeight + this.container.scrollHeight - this.scrollHeight + 50;
      this.current = objects[objects.length - 1].id;
    } else {
      this.anchor('next', '>> next >>');
      this.container.scrollTop = this.container.scrollTop + this.container.offsetHeight - 50;
      this.current = objects[0].id;
    }
    this.scrollHeight = this.container.scrollHeight;
  },

  write: function(object) {
    this.desc = false;
    this.add(object);
    this.container.scrollTop = this.container.scrollHeight - this.container.offsetHeight;
    this.scrollHeight = this.container.scrollHeight;
  },

  anchor: function(id, message) {
    var element = document.createElement('p');
    element.id = 'discussL' + id;
    element.appendChild(document.createTextNode(message));
    this.container.appendChild(element);
  },

  add: function(object) {
    var elements = $A(this.container.getElementsByTagName('p'));
    for (var i = 0, length = elements.length; i < length; i++) {
      if (elements[i].id == this.prefix + object.id) {
        return;
      }
      if (!this.desc && elements[i].id == 'discussLnext') {
        this.container.removeChild(elements[i]);
      }
    }

    this.element = document.createElement('p');
    this.element.id = this.prefix + object.id;

    this.addColor(object.c);
    this.addName(object.u);
    this.addBody(object.m);
    this.addTimestamp(object.t);

    if (this.desc) {
      this.container.insertBefore(this.element, this.reference);
      this.reference = this.element;
      this.min = object.id;
      if (this.max == 0) this.max = object.id;
    } else {
      this.container.appendChild(this.element);
      this.max = object.id;
      if (this.min == 0) {
        this.min = object.id;
        this.reference = this.element;
      }
    }
  },

  addColor: function(color){
    if (color != undefined) {
      this.element.className = 'color' + color;
    }
  },

  addName: function(name) {
    var usernameContainer = document.createElement('b');
    usernameContainer.appendChild(document.createTextNode(name + ':'));
    this.element.appendChild(usernameContainer);
  },

  addBody: function(body) {
    if (match = body.match(/((?:https?|ftp):\/\/[!~*'();\/?:\@&=+\$,%#\w.-]+)/)) {
      this.element.appendChild(document.createTextNode(body.slice(0, match.index)));
      this.element.appendChild(this._hyperlink(match[0]));
      this.element.appendChild(document.createTextNode(body.slice(match.index + match[0].length)));
    } else {
      this.element.appendChild(document.createTextNode(body));
    }
  },

  _hyperlink: function(url){
    var linkHref = document.createElement('a');
    linkHref.setAttribute('href', url);
    linkHref.setAttribute('target', '_blank');
    if(url.length > 45) {
      url = url.substr(0, 40) + '...';
    }
    linkHref.appendChild(document.createTextNode(url));
    return linkHref;
  },

  addTimestamp: function(timestamp) {
    if(timestamp) {
      var timestampContainer = document.createElement('span');
      timestampContainer.className = 'timestamp';
      var timestampText = document.createTextNode(['(',timestamp,')'].join(''));
      timestampContainer.appendChild(timestampText);
      this.element.appendChild(timestampContainer);
    }
  }
});//end of Discuss.Messages

Discuss.Calendar = Class.create({
  initialize: function(root) {
    this.root = root;
    this.container = document.getElementById('discussCalendar');
    if (this.container) {
      this.available = true;
      this.monthSelector = (this.container.getElementsByTagName('div'))[0];
      Event.observe(this.container, 'click', this.onClickCalendar.bindAsEventListener(this));
    }
  },

  show: function() {
    if (this.available) {
      this.container.style.display = 'block';
      this.reset();
      this.render({});
    }
  },

  hide: function() {
    try {this.container.style.display = 'none';} catch (e) { }
  },

  reset: function() {
    var today = new Date();
    this.year = today.getFullYear();
    this.month = today.getMonth() + 1;
    try {this.monthSelector.innerHTML = '';} catch (e) { }
    this.months = null;
    this.rendered = false;
  },

  render: function(days) {
    if (!this.available) {
      return;
    }
    var elements = this.container.getElementsByTagName('span');
    for (var i = 0, length = elements.length; i < length; i++) {
      if (elements[i].id == 'discussCcaption') {
        elements[i].innerHTML = this.year + ' / ' + ('_0' + this.month).slice(-2);
        break;
      }
    }
    var numOfDays = new Date(this.year, this.month, 0).getDate();
    this.offset = new Date(this.year, this.month - 1, 1).getDay() - 1;

    elements = this.container.getElementsByTagName('td');
    var date = null;
    for (var i = 0, length = elements.length; i < length; i++) {
      date = i - this.offset;
      if (date > 0 && date <= numOfDays) {
        elements[i].innerHTML = date;
        if (days[date] == undefined) {
          elements[i].className = 'dateNoMessage';
        } else {
          elements[i].className = 'dateHasMessage';
          this.rendered = true;
        }
      } else {
        elements[i].innerHTML = '';
      }
    }
  },

  onClickCalendar: function(e) {
    switch (true) {
    case (e.target.id == 'discussCprev'):
      if (--this.month < 1) {
        this.year -= 1;
        this.month = 12;
      }
      this.scroll();
      break;

    case (e.target.id == 'discussCnext'):
      if (++this.month > 12) {
        this.year += 1;
        this.month = 1;
      }
      this.scroll();
      break;

    case (e.target.id == 'discussCdown'):
      if (this.root.mode >= 0) {
        this.showMonths(Event.pointerY(e) + 10, Event.pointerX(e));
      }
      break;

    case (e.target.id == 'discussMhead'):
      this.hideMonths();
      break;

    case (e.target.id.substr(0, 9) == 'discussC_'):
      if (e.target.className == 'dateHasMessage') {
        this.root.dailyLog({y: this.year, m: this.month, e: e.target.id.substr(9) - this.offset});
      } else if (!this.rendered && this.root.mode == 0) {
        this.requestDays();
        this.rendered = true;
      }
      break;

    case (e.target.id.substr(0, 9) == 'discussM_'):
      this.hideMonths();
      var year = e.target.id.substr(9, 4) - 0;
      var month = e.target.id.substr(13) - 0;
      if (!this.rendered || this.year != year || this.month != month) {
        this.year = year;
        this.month = month;
        this.requestDays();
      }
      break;
    }
    return false;
  },

  scroll: function() {
    if (this.months) {
      for (var i = 0, length = this.months.length; i < length; i++) {
        if (this.months[i] == this.year + ('_0' + this.month).slice(-2)) {
          this.requestDays();
          return;
        }
      }
    } else if (this.root.mode >= 0) {
      this.requestDays();
      return;
    }
    this.render({});
  },

  requestDays: function() {
    if (!this.available) {
      return;
    }
    if (this.options == undefined) {
      this.options = {
        method: 'get',
        asynchronous: false,
        onSuccess: this._onSuccessRequestDays.bind(this)
      }
    }
    var parameters = {d: this.root.discuss_id, y: this.year, m: this.month};
    this.options.parameters = $H(parameters).toQueryString();
    var request = new Ajax.Request('./index.php/days', this.options);
  },

  _onSuccessRequestDays: function(response, headerJSON) {
    var days = (headerJSON) ? headerJSON : response.responseJSON;
    this.render(days);
  },

  hideMonths: function() {
    this.monthSelector.style.top = '-1000px';
    this.monthSelector.style.left = '-1000px';
  },

  showMonths: function(cy, cx) {
    if (this.monthSelector.innerHTML == '') {
      var options = {
        method: 'get',
        asynchronous: false,
        onSuccess: this._onSuccessRequestMonths.bind(this),
        parameters: $H({d: this.root.discuss_id}).toQueryString()
      }
      var request = new Ajax.Request('./index.php/months', options);
    }
    this.monthSelector.style.top = cy + 'px';
    cx = (cx > this.monthSelector.offsetWidth) ? cx - this.monthSelector.offsetWidth : cx;
    this.monthSelector.style.left = cx + 'px';
  },

  _onSuccessRequestMonths: function(response, headerJSON) {
    this.months = (headerJSON) ? headerJSON : response.responseJSON;

    var element = document.createElement('span');
    element.id = 'discussMhead';
    element.appendChild(document.createTextNode('x'));
    this.monthSelector.appendChild(element);

    var year = '0000';
    for (var i = 0, length = this.months.length; i < length; i++) {
      if (this.months[i].substr(0, 4) != year) {
        year = this.months[i].substr(0, 4);
        this.monthSelector.appendChild(document.createElement('br'));
        this.monthSelector.appendChild(document.createTextNode(year));
      }
      element = document.createElement('span');
      element.id = 'discussM_' + this.months[i];
      element.appendChild(document.createTextNode(this.months[i].substr(4)));
      this.monthSelector.appendChild(element);
    }
  }
});

var discuss;
window.onload = function() {
  discuss = new Discuss.Root();
}
