/* -*- C++ -*- */

/**
 * New starbar. documentation to come soon.
 */

var starbar = {

  /**
   * name MUST be the name of this object (should be 'starbar').
   */

   name: 'starbar',

   /**
    * Width and height of a single star bar. All measurements are in pixels.
    */

   height    : 12,
   width     : 60,

   star_width: 12,
   star_count: 5,

   gap_width : 1,  //gap between each star.

   min_score : 0,
   max_score : 5,

   score_step: 5, // stepping amount for score images.

   image_root: 'http://content.ytmnd.com/assets/images/starbar/', //'http://content.ytmnd.com/assets/star_bar/',
   image_type: 'gif',

   vote_url  : '/vote/interface.html?user=' + user_id + '&auth=' + vote_auth_hash,
   tooltips  : ['garbage','bad','mediocre','good','spectacular'],

   addons    : {},      // holds addon objects
   bars      : [], // array of our bar objects.
   images    : [], // array of images we are currently using, sans url (uri+filename)
   timers    : [], // timers for individual bars
   site_ids  : [], // site_ids[bar_id] = <real site_id>
   bar_addons: [], // a simple list of bar_ids and what addons they have.

   lookups   : ['votes','predictions', 'either'],
   //ajax_iface : window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0"),

   initiated:     false,
   enable_clicks: false,

   last_hovered: -1,

   init: function () {

     if (window.XMLHttpRequest) {
       this.ajax_iface = new XMLHttpRequest();
     }
     else {
       this.ajax_iface = new ActiveXObject("MSXML2.XMLHTTP.3.0");
     }
     
     this.types =
     {
       score   : { title: 'Score',     order: 10, color: 'red',    type: 'default'},
       rating  : { title: 'Voted',     order: 20, color: 'blue',   type: 'voted'  },
       rate    : { title: '',          order: 30, color: 'orange', type: 'hover'  },
       predict : { title: '',          order: 40, color: 'gold',   type: 'normal' },
       empty   : { title: '',          order: 50, color: 'grey',   type: 'normal' },
       fav     : { title: 'Favorite!', order: 60, color: 'fav',    type: 'special'},
       unfav   : { title: '',          order: 70, color: 'unfav',  type: 'special'},
       unrate  : { title: '',          order: 80, color: 'unrate', type: 'special'}
     };

     this.modes =
     {
       favd   : { type : this.types.fav,
		  hover: this.types.unfav,
		  data : 'is_fav',
		  click: '&a=uf'},
       rated  : { type : [this.types.score, this.types.rating],
		  hover: this.types.rating,
		  data : ['score', 'rating'],
		  click: '&a=v'},
       predict: { type : [this.types.score, this.types.predict],
		  hover: this.types.rating,
		  data : ['score', 'prediction'],
		  click: '&a=v'},
       normal : { type : this.types.score,
		  hover: this.types.rating,
		  data : 'score',
		  click: '&a=v'}
     };
     this.initiated = true;
    }
};


//var interface = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");


function bar ()
{
  /**
   * Info variables
   */

  this.site_id    = -1;
  this.score      = 0.0;
  this.rating     = false;
  this.prediction = false;
  this.is_fav     = false;


  this.addons = [];


  /**
   * Display variables
   */

  this.mode         = false;
  this.mode_stuck   = false;

  this.is_clickable = (typeof user_id == 'undefined' || user_id <= 0) ? false : true;  // boolean

  this.image        = false;  // full url to current image
  this.normal_image = false;  // full url to normal (non hover) image
  this.lookup       = false;  // what kind of extra data we should look up.
  this.alt_text     = '';

  /*
   * These functions can be overridden if necessary.
   */

  this.m_over     = starbar.m_over;
  this.m_out      = starbar.m_out;
  this.on_click   = starbar.on_click;

  this.ref = function() {
    return '.bars['+this.bar_id+']';
  };

  return this;
}



starbar.pageLoad = function()
{
  this.fetchVoteData();
  this.enable_clicks = true;
};



/**
 * Default mouse/click functions. These can be overridden globally or per bar.
 */

starbar.m_over = function (bar_id, star)
{
  if (typeof this.bars[bar_id] == 'undefined') return false;

  var sb = this.bars[bar_id];

  if (this.timers[bar_id] !== 0) {
    window.clearTimeout(this.timers[bar_id]);
    this.timers[bar_id] = 0;
  }

  if (this.last_hovered >= 0 && (this.last_hovered != bar_id || this.last_hovered == bar_id && star < 0)) {
    this.restoreBarImage(this.last_hovered);
  }

  this.last_hovered = bar_id;

  if (star > 0) {
    this.swapBarImage(bar_id, sb.mode.hover, star, true);
    window.status = this.tooltips[star - 1];
  }

  return false;
};


starbar.m_out = function (bar_id)
{
  window.status = "";

  if (this.timers[bar_id] === 0) {
    this.timers[bar_id] = window.setTimeout(this.name + '.restoreBarImage(' + bar_id + ')', 100);
  }

  return false;
};


starbar.on_click = function (bar_id, star)
{

  if (this.enable_clicks === false) {
    return false;
  }

  if (typeof bar_id == 'undefined' || typeof this.bars[bar_id] == 'undefined') {
    return false;
  }
  else {
    var sb = this.bars[bar_id];
  }

  this.enable_clicks = false;
  vote_url = this.vote_url + sb.mode.click + '&s=' + sb.site_id + '&v=' + star;

  //window.setTimeout(this.name+'.restoreBarImage('+bar_id+');', 10);

  this.fetchVoteData(vote_url);
  return false;
};



/**
 * Bar Image functions.
 */


starbar.restoreBarImage = function (bar_id)
{
  document.getElementById('sb_img_' + bar_id).src = this.bars[bar_id].normal_image;
  document.getElementById('sb_img_' + bar_id).alt = this.bars[bar_id].alt_text;

  window.status = "";

  this.timers[bar_id] = 0;

  if (this.last_hovered == bar_id) {
    this.last_hovered = -1;
  }
};


starbar.swapBarImage = function (bar_id, bar_type, stars)
{
  if (typeof stars == 'undefined') stars = 0.0;

  document.getElementById('sb_img_' + bar_id).src = this.getBarImage(bar_type, stars, true);
};


starbar.addBarAddon = function (bar_id, addon) 
{

 if (typeof bar_id == 'undefined' || typeof this.bars[bar_id] == 'undefined') {
    console.log('RETURNED FALSE, CANT FIND BAR_ID' + bar_id);
    return false;
  }
  else {
    var sb = this.bars[bar_id];
  }

 if (typeof this.addons[addon] == 'undefined') {
   return false;
 }
 else {
   if (typeof this.bar_addons[bar_id] == 'undefined') {
     this.bar_addons[bar_id] = [];
   }

   this.bar_addons[bar_id][addon] = true;
   sb.addons[this.addons[addon].name] = true;
   return true;
 }

};




// TODO: no site_id, check score parsing, make do_write.
// add(site_id, [score, rating, fav, predict], [addons], [do_write])

starbar.add = function (site_id, score, force_type, addon, do_write)
{
  if (this.initiated === false) { this.init(); }
  if (typeof site_id  == 'undefined') var site_id = false;
  if (typeof do_write != 'undefined') { do_write = false; } else { do_write = true; }

  var sb = new bar();

  sb.bar_id = this.bars.length;

  this.bars.push(sb);
  this.timers[sb.bar_id] = 0;

  if (site_id !== false && site_id >= 1) {
    sb.site_id = site_id;
    this.site_ids.push(site_id);
  }
  else {
    sb.site_id = false;
    this.site_ids.push(false);
    sb.is_clickable = false;
  }

if (typeof score != 'undefined') {
    sb.score = parseFloat(score);
  }
  else if (typeof score == 'object') {
    switch (score.length) {
      case 4: sb.prediction = score[3];
      case 3: sb.is_fav     = true;
      case 2: sb.rating     = score[1];
      case 1: sb.score      = score[0];
      break;
    }
  }
  
  if (typeof force_type != 'undefined' && typeof this.modes[force_type] != 'undefined') {
    sb.mode = this.modes[force_type];
    sb.mode_stuck = true;
    //this.guessBarMode(sb.bar_id);
  }
  else {
    this.guessBarMode(sb.bar_id);
  }

  //ADDONS    
  if (typeof addon != 'undefined') {
    if (typeof addon == 'object') {
      for (var i in addon) {
	this.addBarAddon(sb.bar_id, addon[i]);
      }
    }
    else {
      this.addBarAddon(sb.bar_id, addon);
    }
  }



  with (document) {
    return this.insert(sb.bar_id, do_write);
  }
};



starbar.guessBarMode = function (bar_id)
{
  if (typeof this.bars[bar_id] == 'undefined') return false;

  var sb = this.bars[bar_id];

  if (sb.mode_stuck === true) {
    return false;
  }

  for (var mode in this.modes) {
    var matches_mode = false;
    var mode_data = this.modes[mode].data;

    if (typeof mode_data == 'object') {
      matches_mode = 0;
      for (var data in mode_data) {
	if (sb[mode_data[data]] !== false) { matches_mode++; }
      }

      if (matches_mode == mode_data.length) { matches_mode = true; } else { matches_mode = false; }
    }
    else {
      if (sb[mode_data] !== false) {
	matches_mode = true;
      }
    }

    if (matches_mode === true) {
      sb.mode = this.modes[mode];
      break;
    }
  }

  //MARK FINISH THIS OFF

  if (sb.mode == this.modes.favd) {
    sb.alt_text = this.types.fav.title;
  }
  else if (sb.mode == this.modes.rated) {
    sb.alt_text = this.types.rating.title + ': ' + sb.rating + ' stars';
  }
  else {
    sb.alt_text = this.types.score.title + ': ' + sb.score + ' stars';

    if (sb.prediction !== false) {
      sb.alt_text += ' Prediction: ' + sb.prediction + ' stars';
    }
  }

  if (sb.is_clickable === true) {
    var step = (this.score_step/10);

    for (var i = this.min_score; i <= this.max_score; i = i + step ) {
      if (i % 1 === 0) {
	var hover_image = this.getBarImage(sb.mode.hover, i, true);
	if (typeof this.images[hover_image] == 'undefined') {
	  this.images[hover_image] === false;
	}
      }
    }
  }
};

/**
 * get the image path/filename for a bar type.
 */

starbar.getBarImage = function (in_type, score, is_single)
{
  if (typeof is_single != 'boolean') is_single = true;

  var image_dir = '';
  var image_name = '';

  var primary_score, primary_type, secondary_score, secondary_type;


  if (is_single === true) {
    primary_type   = in_type;
    secondary_type = false;

    primary_score  = this.normalizeScore(score);
    is_single = true;
  }
  else {
    primary_type    = in_type[0];
    secondary_type  = in_type[1];

    primary_score   = this.normalizeScore(score[0]);
    secondary_score = this.normalizeScore(score[1]);
    is_single = false;
  }

  if (typeof primary_type == 'undefined') {
    //ERROR_REPORTING
  }


  if (primary_type.type == 'special') {
    image_name = primary_type.color;
  }
  else if (is_single === false && secondary_type.type == 'special') {
    image_name = secondary_type.color;
  }
  else if (is_single === true) {
    image_dir  = primary_type.color + '/';
    image_name = primary_score;
  }
  else {
    if (primary_type.order < secondary_type.order) {
      image_dir  = primary_type.color + '/' + secondary_type.color + '/';
      image_name = primary_score + '_' + secondary_score;
    }
    else {
      image_dir  = secondary_type.color + '/' + primary_type.color + '/';
      image_name = secondary_score + '_' + primary_score;
    }
  }

  var image_url = this.image_root + image_dir + image_name + '.' + this.image_type;

  if (typeof this.images[image_url] == 'undefined') {
    this.images[image_url] = false;
  }

  return image_url;
}


/**
 * set a bar's image to whatever the current settings are.
 */

starbar.setBarImage = function (bar_id)
{
  if (typeof bar_id == 'undefined' || typeof this.bars[bar_id] == 'undefined') {
    console.log('RETURNED FALSE, CANT FIND BAR_ID' + bar_id);
    return false;
  }
  else {
    var sb = this.bars[bar_id];

    if (sb.mode === false) {
      this.guessBarMode(bar_id);
    }
  }

  var score;
  v