if (!RB)
  var RB = {};

RB.VotePanel = Class.create({
  initialize: function(container, options) {
    this.container = $(container);
    this.width = this.container.getWidth();
    this.height = 320;
    this.options = options;
    this.masterVoteButton = this.container.down('form.master-vote-button');

    this.total_pages = options.total_pages;
    this.current_page = options.current_page;
    this.loadedPages = [this.current_page];
    this.loadingPages = [];

    this.loadingImageSrc = '/images/forum/clearbits/bg_blank.gif'; // this.container.down('.loading-image').src;

    if (this.options.allowVoting) {
      this.masterVoteButton.observe('submit', function(e) {
        e.stop();
        form = $(e.target);
        if (form.hasClassName("votable")) {
          new Ajax.Request(form.action, {parameters: Form.serialize(form)});
          new_value = 1 - form.vote.value;
          form.vote.value = new_value;
          tokens = this.masterVoteButton.action.split('/'); 
          entry_id = tokens[tokens.length - 2];
          $('entry-' + entry_id + '-caption').down('form').vote.value = new_value;

          this.toggleVoteButton(form);
          this.showEntry(this.entryNumber);
        }
      }.bind(this));
    }

    this.slots = {
      prev:    this.container.down('img.prev'),
      next:    this.container.down('img.next'),
      current: this.container.down('img.current')
    }

    $H(this.slots).values().concat(this.container.select('.controls')).concat(this.container.select('.vote-panel-criteria')).invoke("show");

    new Effect.Opacity(this.slots.next, {to: 0.35, duration: 0.0});
    new Effect.Opacity(this.slots.prev, {to: 0.35, duration: 0.0});

    this.slots.current.observe('click', function() {
      window.location = this.currentEntry.next('div').down('a').href;
    }.bind(this));

    this.cookieJar = new CookieJar({
      expires: 3600 * 24 * 7  // 1 week
    });
    this.entryNumber = this.cookieJar.get('offset2_' + options.requestPath.split('/').last().split('-').first()) * 1 || 1;
    
    if (!this.showEntry(this.entryNumber)) {
      if (!this.showEntry(this.options.entry_number)) {
        this.showEntry(1);
      }
    }

    [this.container.down('.controls .left'), this.slots.prev].each(function(elem) {
      elem.observe('click', function(e) { 
        e.stop();
        if (this.entryNumber > 1) {
          this.entryNumber += -1;
          if (!this.showEntry(this.entryNumber))
            this.entryNumber -= -1;
        }
      }.bind(this));
    }.bind(this));  

    [this.container.down('.controls .right'), this.slots.next].each(function(elem) { 
      elem.observe('click', function(e) { 
        e.stop();
        if (this.entryNumber < this.options.totalEntries) {
          this.entryNumber += 1;
          if (!this.showEntry(this.entryNumber))
            this.entryNumber -= 1;
        }
      }.bind(this));
    }.bind(this));
  },
  
  showEntry: function(entryNumber) {
    id = 'entry-' + entryNumber;
    entry = this.container.down('img.' + id);

    if (!entry)
      return false;

    this.currentEntry = entry;  
    this.cookieJar.put('offset2_' + this.options.requestPath.split('/').last().split('-').first(), this.extractId(this.currentEntry, 'entry'));
    getSrc = function(obj, entryNumber) {
      if (entryNumber < 1 || entryNumber > this.options.totalEntries)
        obj.hide();
      else
        obj.show();

      img = this.container.down('img.entry-' + entryNumber);
      if (img) {
        obj.src = img.src;
        obj.style.width = img.getWidth() + 'px';
        obj.style.height = img.getHeight() + 'px';
      } else {
        obj.src = this.loadingImageSrc;
        obj.style.width = '';
        obj.style.height = '';
      }
    }.bind(this);
    this.slots.prev.src = this.loadingImageSrc;
    this.slots.current.src = this.loadingImageSrc;
    this.slots.next.src = this.loadingImageSrc;

    getSrc(this.slots.prev, entryNumber - 1);
    getSrc(this.slots.current, entryNumber);
    getSrc(this.slots.next, entryNumber + 1);

    var captionDiv = entry.next('.caption');
    form = captionDiv.down('form');
    this.masterVoteButton.setAttribute('action', form.getAttribute('action'));
    this.masterVoteButton.vote.setAttribute('value', form.vote.getAttribute('value'));
    this.toggleVoteButton(form);
    this.container.select('.caption').invoke('hide');
    if (form.vote.value == '0') {
      captionDiv.select('.vote').invoke('hide');
      captionDiv.select('.retract').invoke('show');
    } else {
      captionDiv.select('.vote').invoke('show');
      captionDiv.select('.retract').invoke('hide');
    }
    captionDiv.show();

    // Position slots
    this.slots.next.style.right = '60px';
    this.slots.prev.style.left = '60px';

    resize = function(elem, multiplier) {
      d = elem.getDimensions();
      elem.style.width = (d.width * multiplier) + 'px';
      elem.style.height = (d.height * multiplier) + 'px';
      elem.style.top = (this.height - d.height * multiplier) / 2 + 'px';
    }.bind(this);
    resize(this.slots.next, 0.5);
    resize(this.slots.current, 1.0);
    resize(this.slots.prev, 0.5);

    this.slots.current.style.left = (this.width / 2 - this.slots.current.getWidth() / 2) + 'px';

    if (entry.hasClassName('loadprev') && this.loadedPages.indexOf(this.rollPage(this.currentPage(), -1))) {
      this.loadPage(this.rollPage(this.currentPage(), -1));
    }
    if (entry.hasClassName('loadnext') && this.loadedPages.indexOf(this.rollPage(this.currentPage(), +1))) {
      this.loadPage(this.rollPage(this.currentPage(), +1));
    }
    return true;
  },
  currentPage: function() {
    return this.extractId(this.currentEntry, 'page');
  },
  rollPage: function(current_page, direction) {
    return (current_page + direction + this.total_pages - 1) % this.total_pages + 1;
  },
  loadPage: function(page) {
    if (this.loadingPages.indexOf(page) < 0) {
      this.loadingPages.push(page);
      new Ajax.Request(this.options.requestPath + '/entries/for_voting?page=' + page, {
        method: 'get',
        onSuccess: function(transport) {
          this.loadedPages.push(page);
          this.container.down('div.loading-area').insert({bottom: transport.responseText});
          this.showEntry(this.entryNumber);
        }.bind(this)
      })
    }
  },
  toggleVoteButton: function(form) {
    if (form.hasClassName("votable")) {
      this.masterVoteButton.addClassName("votable");
      if (form.vote.value == '0') {
        this.masterVoteButton.down("input[name=submit_button]").writeAttribute({
          'src':   '/images/groups/challenges_remove_vote_button.gif',
          'title': 'Remove your vote on this entry',
          'alt':   'Remove your vote on this entry'
        });    
      } else {
        this.masterVoteButton.down("input[name=submit_button]").writeAttribute({
          'src':   '/images/groups/challenges_vote_button_02.gif',
          'title': 'Vote for this entry',
          'alt':   'Vote for this entry'
        });    
      }
    } else {
      src = form.down("input[name=submit_button]");
      this.masterVoteButton.removeClassName("votable");
      this.masterVoteButton.down("input[name=submit_button]").writeAttribute({
        'src':   src.src,
        'title': src.title,
        'alt':   src.alt
      });
    }
  },
  // Private
  extractId: function(obj, type) {
    var tokens = obj.className.split(' ').grep(type).first().split('-');
    return tokens.pop() * 1;
  }
});
