// RATER
// =====
// TODO:
// * observe left / right keys
// * NOT WORKING IN SAFARI

var Players = [];
  
var Player = Class.create({
  playing:false,
  effect:null,
  handle_pause: 0.5,
  lineColor: "#fff",
  avgLineColor: "#666",
  initialize:function(opts){
    this.opts = opts;
    this.can_rate = opts.can_rate;
    
    if(this.can_rate){
      this.save_btn = $(opts.save_btn);
      this.save_btn.observe('click',this.save_meter.bind(this));
      this.rate_url = opts.rate_url;
    }
    
    this.container = $(opts.container);
    this.player_dims = {width:this.container.getWidth() - 10, height:this.container.getHeight() - 10}
    this.handle_offset = (this.player_dims.width / 2 - 5)+'px';
    
    var flashvars = {};
    
    flashvars.file = opts.file;
    flashvars.image = opts.image;
    
    flashvars.width = this.player_dims.width;
    flashvars.height = this.player_dims.height;
    flashvars.fullscreen = "true";
    flashvars.controlbar = "over";
    
    // setup if local asset playback
    if(opts.local){
      flashvars.controlbar = "none";
      flashvars.stretching = "fill";
    } else {
      flashvars.skin = "/iballz_skin.swf"
    }
    
    flashvars.tracecall = "flash";
    flashvars.autostart = opts.autostart || false;

    var params = {wmode:"transparent", allowfullscreen:"true", allowscriptaccess:'always'};
    var attributes = {};
    attributes.align = "top";

    var ssl = ("https:" == document.location.protocol) ? "s" : "";
    swfobject.embedSWF(opts.local ? "/player.swf" : "http"+ssl+"://"+VIDEOS_DOMAIN+"/player.swf", this.container.id, this.player_dims.width, this.player_dims.height,
     "9.0.115", "http"+ssl+"://"+VIDEOS_DOMAIN+"/expressInstall.swf", flashvars, params, attributes);

    this.duration = opts.duration;

    // init iBallz meter
    
    this.samples = [[0,0.5]];
    this.sample_values = [{"x":0, "y":0.5}];
    this.uniqueSamples = [[0,0.5]];
    
    if(opts.average_samples){
      this.average_samples = opts.average_samples.map(function(s){return {"x":s[0],"y":s[1]}});
    } else {
      this.average_samples = [];
    }
    
   if(this.can_rate){
     this.el = $('rater');
     this.handle = this.el.down('.handle');
     this.track = this.el.down('.track');
     this.track.setStyle({width:this.player_dims.width+'px'});

     swfobject.embedSWF("/open-flash-chart.swf", "chart", this.player_dims.width-10, "150", "9.0.115", {}, {}, {wmode:"transparent"}, {});

     // init slider controls
     this.slider = new Control.Slider(this.handle, this.track, {
      sliderValue:0.5, 
      onSlide:(function(value){
        if(this.effect) this.effect.cancel();
      }).bind(this),
      onChange:(function(value){
        setTimeout(this.neutralize.bind(this), this.handle_pause*1000);
      }).bind(this)
     });
    }
    
    this.player_index = Players.length;
    Players.push(this);
   },
   
   // ==== Chart ====
   init_chart:function(){
     return true;
   },
   
   get_chart_elements:function(){
     var els = [
         {
           "type": "scatter_line",
           "colour": "#F97900",
           "dot-size":  1,
           //"line-style": { "style":"dash", "off":2 },
           "values": this.sample_values
         }
       ];
     if(this.average_samples) els.push({
           "type": "scatter_line",
           "colour": "#CCCCCC",
       	   "dot-size":  1,
       	   //"line-style": { "style":"dash", "off":2 },
           "values": this.average_samples
         });
    
     return els;
   },

   get_chart_data:function(){
     return Object.toJSON({
       // "title": {
       //     "text": "iBallz meter",
       //     "style": "{font-size: 10px; color: #000; text-align: center;}"
       //   },
         //  "menu":{
         //    "colour":"#E0E0ff","outline_colour":"#707070",
         //    "values":[{"type":"camera-icon","text":"Save iBallz Meter","javascript-function":"alert"}]
         // },
         "bg_colour": "#333333",
       "elements": this.get_chart_elements(),
       "x_axis": {
         "min": 0,
         "max": this.duration + 1,
         "labels":{"visible": false},
         "stroke": 0,
         "offset": 0,
         "grid-colour": "#333333"
       },
       "y_axis": {
         "labels":[],
         "min": 0,
         "max": 1,
         "stroke": 0,
         "offset": 0,
         "grid-colour": "#333333"
       }
     });
   },
   
   draw_chart:function(){
     findSWF("chart").load(this.get_chart_data());
   },
   
   hide_meter:function(e){
     var vis = $("chart_container").toggle().visible();
     Event.element(e).update(vis ? "hide" : "show");
   },
    
   // ==== Player =====
   addListeners:function(){
     if(this.listeners_added) return
     this.jw = $(this.container.id);
     this.jw.addModelListener("TIME","Players["+this.player_index+"].setTime");
     this.jw.addViewListener("PLAY","Players["+this.player_index+"].toggle");
     this.jw.addControllerListener("STOP","Players["+this.player_index+"].stop");
     this.jw.addModelListener("STATE","Players["+this.player_index+"].state");
     this.listeners_added = true;
   },
   setTime:function(obj){
     this.time = obj.position;
     if(this.time % (1 / this.sampleRate) == 0) this.sample();
   },
   toggle:function(obj){
     this.playing = !this.playing; 
     if(this.playing) this.start();
     else this.stop();
   },
   state:function(obj){
     switch(obj.newstate){
       case "COMPLETED": 
        this.stop();
        this.next();
     }
   },
   seek:function(t){
     if(!this.playing) $(this.container.id).sendEvent("PLAY");
     ((function(){$(this.container.id).sendEvent("SEEK",t)}).bind(this)).delay(0.1);
   },
   
   play:function(){
     this.jw.sendEvent("PLAY","true");
   },
   pause:function(){
     this.jw.sendEvent("PLAY","STOP");
   },
   
   // ==== Sampler =====
   sampleRate:2, 
   time:0,
   start:function(){
     if(this.opts.onPlay) this.opts.onPlay();
   },
   stop:function(){
     this.playing = false;
     if(this.handle) this.handle.setStyle({left:this.handle_offset}); //needs to use this.width;
     if(this.effect) this.effect.cancel();
   },
   next:function(){
     
     if(this.opts.onDone) this.opts.onDone();
          
     try{
       var tar = ($(Playlist.current).next('.reels_results_item') ? 
          $(Playlist.current).next('.reels_results_item') : $(Playlist.list.first()));
       var next_id = tar.down('input[type="hidden"]').value;
       
       Playlist.start_next_countdown(next_id);       
     } catch(err){
       //no playlist do nothing
     }
   },
   sample:function(){
     if(this.time == 0) return;
     
     // use Effect.Slider's built in method to translate an offset to a value
     var value = parseFloat(this.slider.translateToValue(parseInt(this.handle.style.left)).toFixed(3));
   
     // only record sample if different from the last
     if(value != this.uniqueSamples.last()[1]) this.uniqueSamples.push([this.time, value]);
     
     for (var i=0; i < this.samples.length; i++) {
       if(this.samples[i][0] == this.time){
         this.samples[i][1] = value;
         break;
       } else if(this.samples[i][0] > this.time || i == this.samples.length - 1) {
         this.samples = this.samples.insert(i,[this.time,value]);
         break;
       } 
     }
     
     this.sample_values = this.samples.sortBy(function(s){return s[0]}).map(function(s){return {"x":s[0],"y":s[1]}});
     
     this.draw_chart();
   },
   
   save_meter:function(){
     var save_btn_value = this.save_btn.value;
     this.save_btn.value = "saving...";
     this.save_btn.disabled = true;
     new Ajax.Request(this.rate_url, {parameters:{samples:this.uniqueSamples.inspect(), authenticity_token:AUTHENTICITY_TOKEN}, onComplete:(function(){
       this.save_btn.value = save_btn_value;
       this.save_btn.disabled = false;
      }).bind(this)});
   },
   neutralize:function(){
    this.effect = new Effect.Morph(this.handle, {
      style:{left:this.handle_offset}, 
      duration:5,
      transition:function(pos) {
        return (-Math.cos(pos*Math.PI)/2) + 0.5;
      }
    });
   }
});

function playerReady(obj){
  Players.each(function(p){p.addListeners()});
  // $(obj.id).addListeners();
}

// OFC2 callbacks
function ofc_ready(){Players.first().init_chart()}
function open_flash_chart_data(){return Players.first().get_chart_data()}

function findSWF(movieName) {
  if (navigator.appName.indexOf("Microsoft")!= -1) {
    return window[movieName];
  } else {
    return document[movieName];
  }
}

Object.extend(Array.prototype, {
  insert: function(index) {
    this.length = (index > this.length) ? index : this.length;
    index = (index < 0) ? this.length : index;

    this.splice.apply(this, [index, 0].concat(Array.slice(arguments, 1)));
    return this;
  }
});