/*******************************************************************************
* video player handling
* Copyright 2008 Daniel DeLorme & Anime News Network
*/

var Video = {
  handler_for_segment: {},
  scheduled_segment: null,
  currently_visible: null,
  
  init_player: function(vid){ Video.trace('Video.init_player');
    this.init_player = null;//only call once
    this.initialized = true;
    this.splash_image = $('splash-image');
    if (this.flash_is_ok()){
      if (this.parse_autoplay_value()){
        this.play_scheduled_segment();
      }
      else if (vid){
        vid.create_swf();
        this.show(vid);
      }
      else{
        this.show(this.splash_image);
      }
    }
  },
  
  show: function(elem){ Video.trace('Video.show');
    if (!elem) return false;
    if (Video.currently_visible)//may be a Video.Handler or splash_image
      if (Video.currently_visible != elem)
        if (Video.currently_visible.hide() == 'uninterruptible')
          return false;
    elem.show();
    Video.currently_visible = elem;
    return true;
  },
  
  parse_autoplay_value: function(){ Video.trace('Video.parse_autoplay_value');
    var m = document.location.hash.match(/play-(\d+)/);
    if (m && this.handler_for_segment[m[1]]){
      this.scheduled_segment = parseInt(m[1],10);
      Video.debug("AUTOPLAY: "+this.scheduled_segment);
    }
    
    return this.scheduled_segment != null;
  },
  
  flash_is_ok: function(){ Video.trace('Video.flash_is_ok');
    UFO.getFlashVersion();
    if (!UFO.hasFlashVersion(9,115)) {
      if (UFO.fv[0] > 0) $('bad-flash').innerHTML = 'It appears that you currently have only version '+UFO.fv[0]+'.0.'+UFO.fv[1]+'.0 of the Flash Player. Click the button below to upgrade it.';
      $('flash-required-message').show();
      return false;
    }
    $('flash-required-message').hide();
    return true;
  },
  
  play_scheduled_segment: function(num){ Video.trace('Video.play_scheduled_segment');
    if (num == undefined){
      if (this.currently_visible && this.currently_visible.current_segment == this.scheduled_segment){
        Video.debug("already current");
        return;
      }
      num = this.scheduled_segment;
    }
    var handler = this.handler_for_segment[num];
    if (handler){
      handler.schedule_play(num);
    }
    else{
      Video.debug('no handler for segment #'+num);
      this.stop();
    }
  },
  
  stop: function(){ Video.trace('Video.stop');
    this.scheduled_segment = null;
    return this.show(this.splash_image);
  },
  
  play: function(num){ Video.trace('Video.play');
    if (Video.initialized && Video.stop())
      this.play_scheduled_segment(num);
    else
      this.scheduled_segment = num;
  },
  
  pause: function(adclick){ Video.trace('Video.pause');
    var h = Video.currently_visible;
    if (h && h.jwplayer){
      if (h.state == 'playing' && adclick){
        h.jwplayer.sendEvent('playpause');
        window.open(this.ad_url);
      }
      else{
        h.jwplayer.sendEvent('playpause');
      }
    }
  },

  debug_event: function(typ,pr1,pr2,num) {
    var obj, str;
    if (true){
      if (obj = $('debug-'+typ)){
        obj.innerHTML = Object.isHash(pr1) ? pr1.values().join(' ') : pr1;
        if (pr2 != undefined) obj.innerHTML += ' '+pr2;
      }
      if (typ != 'time' || pr1 == 0 || pr2 == 0){
        if (!Object.isHash(pr1))
          str = typ+' '+pr1;
        else
        { str = typ;
          pr1.each(function(pair){ str+=' '+pair.key+'='+pair.value; });
        }
        if (str == "buffer percentage=0") return;
        if (num != undefined) str = num+'.'+str;
        if (pr2 != undefined) str += ' '+pr2;
        str = '[ '+str+' ]';
        if (this.scheduled_segment != num)
          str += ' <small>(sched:'+this.scheduled_segment+')</small>';
        if (typ == 'item') str = '<b>'+str+'</b>';
        Video.raw_debug(str+'<br>');
      }
    }
  },
  
  debug_canvas: '',
  debug: function(str) {
    this.raw_debug(str.gsub('<','&lt;')+'<br>');
  },
  raw_debug: function(str) {
    if (Video.debug_canvas != null)
      Video.debug_canvas += str;
    if (out = $('debug-output')){
      if (Video.debug_canvas){
        out.innerHTML += Video.debug_canvas;
        Video.debug_canvas = null
      }
      else{
        out.insert(str);
      }
    }
  },
  
  trace: function(str){
    this.raw_debug('<small class=ESTAFF>'+str+'<br></small>');
  }
  
};

/******************************************************************************/

Video.Handler = Class.create({
  default_options: {
    movie:"/video/mediaplayer.swf",
    name:"video-jwplayer",
    id:"video-jwplayer",
    width:"480",
    height:"360",
    majorversion:"9",
    build:"115",
    bgcolor:"#000000",
    allowscriptaccess: "always",
    allowfullscreen:"true"
  },
  javascript_autoplay: false,
  container_id: 'video-swf-container',
  
  initialize: function(segment_to_index){ Video.trace('Video.Handler.initialize');
    this.flash = Object.extend({}, this.default_options);
    this.flashvars = {};
    if (Video.width) this.flash.width = this.flashvars.width = Video.width;
    if (Video.height) this.flash.height = this.flashvars.height = Video.height;
    this.segment_to_index = segment_to_index;
    this.segment_logged = {};
    for (var segment in segment_to_index){
      Video.handler_for_segment[segment] = this;
    }
    this.set_state('handler created', 'waiting for SWF');
  },
  
  create_swf: function(){ Video.trace('Video.Handler.create_swf');
    if (this.state == 'waiting for SWF'){
      //create support elements
      this.container = $(this.container_id);
      if (!this.container){
        $('video-player-area').insert('<span id="'+this.container_id+'"></span>');
        this.container = $(this.container_id);
      }
      this.container.style.position = 'absolute';
      
      //create the flash object
      this.flash.flashvars = $H(this.flashvars).toQueryString();
      this.created_at = new Date();
      UFO.create(this.flash, this.container_id);
      this.jwplayer = $(this.flash.id);
      if (!this.jwplayer) debug_alert('no jwplayer!');
      
      //final initialization
      this.container.style.visibility = 'hidden';
      if (this.flashvars["dart.ad.position"] == "post") this.post_roll = 'dart';
      if (this.flashvars["plugins"] == "ltas") this.post_roll = 'longtail';
      this.jwplayer.handler = this;
      this.set_current_segment(0);
      this.set_state('flash object created', 'jw_player initializing');
      return true;
    }
    return false;
  },

  hide: function(){ Video.trace('Video.Handler.hide');
    if (!this.interactive()) return 'uninterruptible';
    this.container.style.visibility = 'hidden';
    if (this.current_segment == Video.scheduled_segment) Video.scheduled_segment = null;
    this.stop();
  },
  
  show: function(){ Video.trace('Video.Handler.show');
    this.container.style.visibility = 'visible';
  },
  
  schedule_play: function(num){ Video.trace('Video.Handler.schedule_play');
    var index = this.segment_to_index[num];
    if (index != null){
      Video.scheduled_segment = num;
      this.create_swf();
      if (this.interactive()){
        if (!this.already_playing(num)){
          this.jw_play_item(index)
        }
      }
      Video.show(this);
    }
  },
  
  already_playing: function(num){ Video.trace('Video.Handler.already_playing');
    return this.current_segment == num && this.state == 'playing';
  },
  
  set_current_segment: function(index){ Video.trace('Video.Handler.set_current_segment('+index+')');
    for (var key in this.segment_to_index)
    {
      if (this.segment_to_index[key] == index)
      {
        //the segment change was voluntarily triggered by the user
        if (this.interactive() && this.container.style.visibility == 'visible')
          Video.scheduled_segment = parseInt(key,10);
        
        this.current_index = index;
        return this.current_segment = parseInt(key,10);
      }
    }
    this.current_index = index;
  },

  log_current_segment: function(time){
    if (!this.segment_logged[this.current_segment]){
      if (time >= 20 && this.interactive()){
        this.segment_logged[this.current_segment] = true;
        Video.debug("LOGGING SEGMENT "+this.current_segment);
        var params = 'segment='+this.current_segment;
        if (this.campaign_id) params += '&campaign_id='+this.campaign_id;
        new Ajax.Request('viewcount.ajax', { asynchronous: true, parameters: params });
      }
    }
  }
  
});

/******************************************************************************/

Video.JW3 = Class.create(Video.Handler, {

  initialize: function($super, segment_to_index) { Video.trace('Video.JW4.initialize');
    $super(segment_to_index);
    this.flash.movie = "/video/mediaplayer-3.16.swf";
    this.flashvars.config = '/video/config.xml';
    this.flashvars.javascriptid = this.flash.id;
  },
  
  jw_play_item: function(index){ Video.trace('Video.JW3.jw_play_item '+index);
    this.jwplayer.sendEvent('playitem', index);
  },

  stop: function(){ Video.trace('Video.JW3.stop');
    this.jwplayer.sendEvent('stop');
  },
  
  interactive: function(){ Video.trace('Video.JW3.interactive');
    var ret = false;
    if (this.state=='playing' || this.state=='stopped'){
      var data = this.jwplayer.itemData(this.current_index || 0);
      ret = !(data.category == 'commercial' || data.file.match(/1_frame_slug/));
    }
    Video.debug("interactive = "+ret);
    return ret;
  },
  
  jw_event: function(typ,pr1,pr2) { //Video.trace('Video.JW3.jw_event');
    try{
      if (typ == 'item') this.set_current_segment(pr1);
      Video.debug_event(typ, pr1, pr2, this.current_segment);
      this['state:'+this.state](typ,pr1,pr2);
    }
    catch(e){
      Video.debug('error: '+e.message);
    }
  },
  
  set_state: function(descr, newvalue){ Video.trace('Video.JW3.set_state');
    this.state = newvalue;
    Video.debug(descr+', state => '+newvalue);
    //when state changes to interactive, activate the scheduled_segment
    if (Video.scheduled_segment)
      if (Video.scheduled_segment != this.current_segment)
        if (this.interactive())
          Video.play_scheduled_segment();
  },
  
 'state:jw_player initializing': function(typ,pr1,pr2)
  {
    if (typ == 'state'){
      if (pr1 == 0){
        //when player loaded with autostart=false
        if (this.javascript_autoplay){
          this.set_state('jwplayer initialized', 'stopped');
          this.schedule_play();
        }
        else{
          this.set_state('jwplayer initialized', 'panache running');
        }
      }
      if (pr1 == 2){
        //when player loaded with autostart=true
        this.set_state('jwplayer initialized', 'playing');
      }
    }
  },
  
 'state:panache running': function(typ,pr1,pr2)
  {
    if (typ == 'load'){
      this.set_state('ad finished', 'playing');
    }
  },
  
 'state:playing': function(typ,pr1,pr2)
  {
    if (typ == 'state'){
      switch(pr1){
        case 0: this.set_state('video pause', 'stopped'); break;
        case 3: this.set_state('end of segment', 'stopped'); break;
      }
    }
    if (typ == 'time'){
      this.log_current_segment(pr1);
    }
  },
  
 'state:stopped': function(typ,pr1,pr2)
  {
    if (typ == 'time' && pr1 > 0){
      this.set_state('video in progress', 'playing');
    }
  }
  
});


Video.JW3.Panache = Class.create(Video.JW3, {
  
  initialize: function($super, num) { Video.trace('Video.JW3.Panache.initialize');
    obj = {};
    obj[num] = 0;
    $super(obj);
    this.flash.movie = "/video/mediaplayer-3.16-panache.swf";
    this.flash.name = this.flash.id = this.flashvars.javascriptid = 'video-jwplayer-'+num;
    this.container_id = 'video-segment-'+num;
  },
  
  create_swf: function($super){ Video.trace('Video.JW3.Panache.create_swf');
    if ($super()){
      if (this.need_navigation) this.add_skip_buttons();
      return true;
    }
    return false;
  },
  
  add_skip_buttons: function(){
    if (!this.jwplayer.addItem){
      var x = this;
      setTimeout(function(){x.addnav()},1);
      return;
    }
    Video.trace('Video.JW3.Panache.add_skip_buttons');
    var item = this.jwplayer.itemData(0);
    Video.debug($H(item).inspect());
    this.jwplayer.loadFile({file:'http://www.animenewsnetwork.com/video/1_frame_slug.flv'});
    this.jwplayer.addItem(item);
    this.jwplayer.addItem({file:'http://www.animenewsnetwork.com/video/1_frame_slug.flv'});
    this.segment_to_index[this.current_segment] = 1;
  },

  //this happened when using multi-segment panache video
  fix_false_starts: function(){
    if (this.current_segment != Video.scheduled_segment){
      Video.debug('false start for segment '+this.current_segment+' !');
      this.stop();
    }
  },
  
 'state:playing': function($super,typ,pr1,pr2)
  {
    $super(typ,pr1,pr2);
    if (typ == 'state' && pr1 == 3) Video.play_scheduled_segment(this.current_segment + 1);
    if (typ == 'load') this.fix_false_starts();
  },
  
 'state:stopped': function($super,typ,pr1,pr2)
  {
    $super(typ,pr1,pr2);
    if (typ == 'load') this.fix_false_starts();
  }
    
});


Video.JW3.Playlist = Class.create(Video.JW3, {
  initialize: function($super, segment_to_index) { Video.trace('Video.JW3.Playlist.initialize');
    $super(segment_to_index);
    this.flashvars.repeat = 'list';
    this.flashvars.linkfromdisplay = 'true';
    this.flashvars.linktarget = '_self';
  },
 'state:stopped': function($super,typ,pr1,pr2)
  {
    $super(typ,pr1,pr2);
    if (typ == 'state' && pr1 > 0){
      var data = this.jwplayer.itemData(this.current_index);
      if (data && data.category == 'eop'){
        this.hide();
        Video.stop();
      }
    }
  }
});


function getUpdate(typ,pr1,pr2,swf){ 
  if (swf = $(swf)) swf.handler.jw_event(typ,pr1,pr2);
}

/******************************************************************************/

Video.JW4 = Class.create(Video.Handler, {
  
  initialize: function($super, segment_to_index) { Video.trace('Video.JW4.initialize');
    $super(segment_to_index);
    this.flash.movie = "/video/mediaplayer-4.2.swf";
    this.flashvars.config = '/video/config4.xml';
    this.flashvars.id = this.flash.id;
    if (Video.JW4.instance) debug_alert('Video.JW4 should be singleton');
    Video.JW4.instance = this;
  },
  
  jw_play_item: function(index){ Video.trace('Video.JW4.jw_play_item '+index);
    this.jwplayer.sendEvent('ITEM', index);
    this.jwplayer.sendEvent('PLAY');
  },
  
  stop: function(){ Video.trace('Video.JW4.stop');
    this.jwplayer.sendEvent('STOP');
  },
  
  interactive: function(){ Video.trace('Video.JW4.interactive');
    var ret = (this.state=='playing' || this.state=='stopped');
    Video.debug("interactive = "+ret);
    return ret;
  },
  
  swf_created: function(){ Video.trace('Video.JW4.swf_created for '+this.jwplayer.id);
    this.jwplayer.addModelListener('ERROR','getJW4_ERROR');
    this.jwplayer.addControllerListener('PLAYLIST','getJW4_PLAYLIST');
    this.jwplayer.addControllerListener('ITEM','getJW4_ITEM');
    this.jwplayer.addControllerListener('PLAY','getJW4_PLAY');
    this.jwplayer.addControllerListener('SEEK','getJW4_SEEK');
    this.jwplayer.addControllerListener('STOP','getJW4_STOP');
    this.jwplayer.addModelListener('BUFFER','getJW4_BUFFER');
    this.jwplayer.addModelListener('LOADED','getJW4_LOADED');
    this.jwplayer.addModelListener('STATE','getJW4_STATE');
    this.jwplayer.addModelListener('TIME','getJW4_TIME');
  },
  
  log_error: function(arg) { Video.trace('Video.JW4.log_error');
    var streamer = this.flashvars["streamer"]+'';
    if (streamer.match(/^rtmp[e]?:/)){
      this.flashvars["streamer"] = streamer.sub('rtmp', 'rtmpt');
      this.container.childElements().each(Element.Methods.remove);
      this.rtmp_test = true;
      this.originally_created_at = this.created_at;
      this.set_state('attempting error recovery', 'waiting for SWF');
      this.schedule_play(Video.scheduled_segment);
      return;
    }
    this.error_notification(arg);
  },
  
  error_notification: function(arg) { Video.trace('Video.JW4.error_notification');
    arg.segment = this.current_segment;
    arg.occur_time = (new Date() - this.created_at) / 1000;
    if (this.originally_created_at){
      var t = (this.created_at - this.originally_created_at) / 1000;
      arg.occur_time = t+'+'+arg.occur_time;
    }
    arg.streamer = this.flashvars["streamer"];
    var params = $H(arg).toQueryString();
    new Ajax.Request('error_notification.ajax', { asynchronous: true, parameters: params });
  },
  
  jw_event: function(typ, arg) { //Video.trace('Video.JW4.jw_event');
    try{
      if (typ == 'item') this.set_current_segment(arg.index);
      var hash = $H(arg);
      hash.unset('version');
      hash.unset('client');
      hash.unset('id');
      hash.unset('oldstate');
      Video.debug_event(typ, hash, undefined, this.current_segment);
      this['state:'+this.state](typ, arg);
    }
    catch(e){
      Video.debug('error: '+e.message);
    }
  },

  set_state: function(descr, newvalue){ Video.trace('Video.JW4.set_state');
    this.state = newvalue;
    Video.debug(descr+', state => '+newvalue);
  },
  
 'state:jw_player initializing': function(typ, arg)
  {
    // the Javascript must be added *after* the SWF is created, otherwise 
    // playerReady() is not called. Even adding this after the call to 
    // UFO.create (in create_swf) is not enough. By adding it here it ensures
    // that the SWF object is well and truly created.
    if (this.load_js){
      $$('head')[0].insert('<script type="text/javascript" src="'+this.load_js+'">');
      this.load_js = null;
    }
    if (typ == 'playlist')
      this.set_state(this.flashvars["plugins"]+'/jwplayer initialized', 'waiting for start');
  },
  
 'state:waiting for start': function(typ, arg)
  {
    if (typ == 'item')
    {
      this.set_state('item selected', 'stopped');
      Video.play_scheduled_segment();
    }
  },
  
 'state:playing': function(typ, arg)
  {
    if (typ == 'state'){
      switch(arg.newstate){
        case 'IDLE': 
          this.set_state('video stop', 'stopped'); 
          Video.stop();//to display splash_image
          break;
        case 'COMPLETED':
          if (this.segment_to_index[this.current_segment + 1])
            this.set_state('end of segment', 'stopped');
          else{
            if (this.post_roll)
              this.set_state('end of video', 'postroll');
            else{
              this.set_state('end of video', 'stopped');
              Video.stop();
            }
          }
      }
    }
    if (typ == 'time'){
      if (this.rtmp_test && arg.position > 0){
        this.rtmp_test = false;
        document.cookie = 'rtmp_tunnel=true';
        Video.debug("SUCCESSFULLY SWITCHED TO RTMPT");
        this.error_notification(Object.extend({message:"recovered"}, arg));
      }
      this.log_current_segment(arg.position);
    }
  },
  
 'state:postroll': function(typ, arg)
  {
    this.set_state('end of postroll', 'stopped');
    if (this.post_roll == 'dart') Video.stop();
  },
  
 'state:stopped': function(typ, arg)
  {
    if (typ == 'state' && arg.newstate == 'PLAYING'){
      this.set_state('video start', 'playing');
    }
  }
 
});


Video.JW4.Plain = Class.create(Video.JW4, {});


Video.JW4.Longtail = Class.create(Video.JW4, {});


Video.JW4.AdSense = Class.create(Video.JW4, {});


Video.JW4.PreScript = Class.create(Video.JW4, {});


Video.JW4.DART = Class.create(Video.JW4, {

  show: function($super){ Video.trace('Video.JW4.DART.show');
    $super();
    Video.splash_image = this;
  },
  
 'state:stopped': function(typ, arg)
  {
    //with the DART plugin, the BUFFERING and PLAYING states tend to get 
    //triggered (erroneously) at the beginning of the ad, so we can't rely
    //on those to know that the video is playing.
    if (typ == 'time' && arg.position > 0){
      Video.debug('[ time '+arg.position+' ]');
      if (arg.position >= 0.35) this.set_state('video in progress', 'playing');
    }
  },
  
 'state:jw_player initializing': function(typ, arg)
  {
    if (typ == 'playlist'){
      this.set_state('DART/jwplayer initialized', 'stopped');
      this.schedule_play(Video.scheduled_segment);
    }    
  }
  
});


Video.JW4.SpotXchange = Class.create(Video.JW4, {
  
 'state:stopped': function(typ, arg)
  {
    //with the DART plugin, the BUFFERING and PLAYING states tend to get 
    //triggered (erroneously) at the beginning of the ad, so we can't rely
    //on those to know that the video is playing.
    if (typ == 'time' && arg.position > 0){
      Video.debug('[ time '+arg.position+' ]');
      if (arg.position >= 0.35) this.set_state('video in progress', 'playing');
    }
  },
  
 'state:jw_player initializing': function(typ, arg)
  {
    if (typ == 'item')
      this.set_state('SpotXchange/jwplayer initialized', 'waiting for start');
  }
  
});


function playerReady(obj){ Video.JW4.instance.swf_created(); }
function getJW4_ERROR(obj){ Video.JW4.instance.log_error(obj); }
function getJW4_PLAYLIST(obj){ Video.JW4.instance.jw_event('playlist', obj); }
function getJW4_ITEM(obj){ Video.JW4.instance.jw_event('item', obj); }
function getJW4_PLAY(obj){ Video.JW4.instance.jw_event('play', obj); }
function getJW4_SEEK(obj){ Video.JW4.instance.jw_event('seek', obj); }
function getJW4_STOP(obj){ Video.JW4.instance.jw_event('stop', obj); }
function getJW4_BUFFER(obj){ Video.JW4.instance.jw_event('buffer', obj); }
function getJW4_LOADED(obj){ Video.JW4.instance.jw_event('loaded', obj); }
function getJW4_STATE(obj){ Video.JW4.instance.jw_event('state', obj); }
function getJW4_TIME(obj){ Video.JW4.instance.jw_event('time', obj); }



/*******************************************************************************
* video dhtml interface
*/

Event.observe(document, 'dom:loaded', video_init);

// Constants
var ENABLE_DIM			= false;
var TICK_MS				= 100;	// Time in milliseconds to periodically call tick()
var DIM_OPACITY			= 0.7;	// Target opacity (0=transparent) of dim blocks
var DIM_ITERS			= 150;	// Number of iterations before dimming

// Global variables
var mouseIdleIterations	= 0;		// Number of iterations in which the mouse has not moved
var mouseMoved			= false;	// If the mouse moved in the last iteration
var inFocus				= true;		// If the window is in focus
var dimmed				= false;	// If dimmed
var dimBlock			= null;		// Reference to dim block

// Functions
function video_init() {
	//in case video.js is loaded in other pages
	if (!$('video-playlist')) return;
	
	// scroll to active episode in the playlist
	$('video-playlist').makePositioned();
	scroll_playlist_to_active_video();
	
	// Attach a click event to all playlist rows
	var rows = $$("#video-playlist .row");
	
	for(i = 0; i < rows.length; i++)
	{
		Event.observe(rows[i], 'click', video_playlist_click);
	}
	
	// Dim events
	if(ENABLE_DIM) {
		Event.observe(document, 'mousemove', function() { mouseMoved = true; });
		Event.observe(document, 'mousedown', function() { mouseMoved = true; });
		Event.observe(window, 'focus', function() { inFocus = true; });
		Event.observe(window, 'blur', function() {
			inFocus = false;
			if(dimBlock != null) {
				document.body.removeChild(dimBlock);
				dimBlock = null;
				dimmed = false;
				mouseIdleIterations = 0;
			}
			});
		window.setInterval(video_tick, TICK_MS);
	}
}

function scroll_playlist_to_active_video(){
  var active = $$("#video-playlist .active")[0];
  if (active)
    $('video-playlist').scrollTop = active.offsetTop;
  else
    //some IE6 bug prevents the above from working when the video is auto-played
    setTimeout(scroll_playlist_to_active_video,10);
}

function video_playlist_click(e) {
	
	
	var targetDiv = $(Event.element(e)).up('.row');
	
	if(!targetDiv || targetDiv.className == "active row")
		return;
	
	var previousTarget = $$("#video-playlist .active")[0];
	var hidden  = previousTarget.down('span.hide');
	var visible = previousTarget.down('span.show');
	
	previousTarget.className = (previousTarget.id % 2 == 0) ? "even row" : "odd row";
	hidden.className  = 'show';
	visible.className = 'hide';
	
	targetDiv.className = "active row";
	
	hidden  = targetDiv.down('span.hide');
	visible = targetDiv.down('span.show');
	
	hidden.className  = 'show';
	visible.className = 'hide';
}

function video_synopsis_toggleCollapse(tag) {

	var span = tag.parentNode.previousSibling;
	
	if(span.className == 'expand')
	{
		span.className = 'collapse';
		tag.innerHTML  = 'more';
	}
	else
	{
		span.className = 'expand';
		tag.innerHTML  = 'less'
	}
}

function video_tick() {
	
	if(!inFocus) 
	{
		return;
	}	
	
	if(mouseMoved) {
		mouseIdleIterations = 0;	
		if(dimmed) 
		{
			document.body.removeChild(dimBlock);
			dimBlock = null;
			dimmed = false;
		}
	}
	else
	{
		mouseIdleIterations++;
	}
	
	if(mouseIdleIterations > DIM_ITERS && !dimmed)
	{
		dimBlock = new Element('div', { 'class': 'dim_block'});
		dimBlock.style.width = document.viewport.getWidth() + "px";
		dimBlock.style.height = (document.height !== undefined) ? document.height + "px" : document.body.offsetHeight + "px";
		dimBlock.setOpacity(0);
		dimBlock.style.top = 0;
		dimBlock.style.left = 0;
		dimBlock.style.zIndex = 1000;
		dimBlock.style.paddingTop = "280px";
		dimBlock.innerHTML = "Move your mouse outside the video area to undim. To disable this feature, go to myANN.";
		document.body.appendChild(dimBlock);
		dimmed = true;
	}
	
	if(dimmed && dimBlock.getOpacity() < DIM_OPACITY) {
		dimBlock.setOpacity(dimBlock.getOpacity() + 0.01);
	}
	
	mouseMoved = false;
}

function video_carousel_next() {
  var carousel = $$('#video-carousel .current')[0];
  if (carousel){
    var next = carousel.next();
    if (!next) next = carousel.previousSiblings().last();
    if (next){
      carousel.className = 'hide';
      next.className = 'current';
    }
  }
  var pager = $$('#video-carousel-page .current')[0];
  if (pager){
    var next = pager.next();
    if (!next) next = pager.previousSiblings().last();
    if (next){
      pager.className = '';
      next.className = 'current';
    }
  }
}

function video_carousel_previous() {
  var carousel = $$('#video-carousel .current')[0];
  if (carousel){
    var prev = carousel.previous();
    if (!prev) prev = carousel.nextSiblings().last();
    if (prev){
      carousel.className = 'hide';
      prev.className = 'current';
    }
  }
  var pager = $$('#video-carousel-page .current')[0];
  if (pager){
    var prev = pager.previous();
    if (!prev) prev = pager.nextSiblings().last();
    if (prev){
      pager.className = '';
      prev.className = 'current';
    }
  }
}

function product_dropdown(release, container)
{
  release = $(release);
  container = $(container);
  var loaded = container.immediateDescendants();
  loaded.each(Element.Methods.hide);
  for (var i=0; i<loaded.length; i++)
    if (loaded[i].getAttribute("prod") == release.value)
      return loaded[i].show();
  
  var products = document.createElement('span');
  products.setAttribute("prod", release.value);
  products.innerHTML = '[fetching prices, please wait...]';
  products.setStyle({cursor: 'wait'})
  container.insert(products);

  var url = '/compare-prices/'+release.value+'/products.ajax';
  new Ajax.Updater(products, url, {
    asynchronous:true,
    onComplete:function(){products.setStyle({cursor: null})}
  });
}


/*******************************************************************************
* Unobtrusive Flash Objects (UFO) v3.21 <http://www.bobbyvandersluis.com/ufo/>
* Copyright 2005, 2006 Bobby van der Sluis
* This software is licensed under the CC-GNU LGPL <http://creativecommons.org/licenses/LGPL/2.1/>
*/

var UFO = {
	req: ["movie", "width", "height", "majorversion", "build"],
	opt: ["play", "loop", "menu", "quality", "scale", "salign", "wmode", "bgcolor", "base", "flashvars", "devicefont", "allowscriptaccess", "seamlesstabbing", "allowfullscreen", "allownetworking"],
	optAtt: ["id", "name", "align"],
	optExc: ["swliveconnect"],
	ximovie: "ufo.swf",
	xiwidth: "215",
	xiheight: "138",
	ua: navigator.userAgent.toLowerCase(),
	pluginType: "",
	fv: [0,0],
	foList: [],
		
	create: function(FO, id) {
		if (!UFO.uaHas("w3cdom") || UFO.uaHas("ieMac")) return;
		UFO.getFlashVersion();
		UFO.foList[id] = UFO.updateFO(FO);
		UFO.createCSS("#" + id, "visibility:hidden;");
		UFO.domLoad(id);
	},

	updateFO: function(FO) {
		if (typeof FO.xi != "undefined" && FO.xi == "true") {
			if (typeof FO.ximovie == "undefined") FO.ximovie = UFO.ximovie;
			if (typeof FO.xiwidth == "undefined") FO.xiwidth = UFO.xiwidth;
			if (typeof FO.xiheight == "undefined") FO.xiheight = UFO.xiheight;
		}
		FO.mainCalled = false;
		return FO;
	},

	domLoaded: function(id) {
		return (document.getElementsByTagName("body")[0] != null || document.body != null) && document.getElementById(id) != null;
	},
	
	domLoad: function(id) {
		if (UFO.domLoaded(id)) return UFO.main(id);
		var _t = setInterval(function() {
			if (UFO.domLoaded(id)) {
				UFO.main(id);
				clearInterval(_t);
			}
		}, 250);
		if (typeof document.addEventListener != "undefined") {
			document.addEventListener("DOMContentLoaded", function() { UFO.main(id); clearInterval(_t); } , null); // Gecko, Opera 9+
		}
	},

	main: function(id) {
		var _fo = UFO.foList[id];
		if (_fo.mainCalled) return;
		UFO.foList[id].mainCalled = true;
		document.getElementById(id).style.visibility = "hidden";
		if (UFO.hasRequired(id)) {
			if (UFO.hasFlashVersion(parseInt(_fo.majorversion, 10), parseInt(_fo.build, 10))) {
				if (typeof _fo.setcontainercss != "undefined" && _fo.setcontainercss == "true") UFO.setContainerCSS(id);
				UFO.writeSWF(id);
			}
			else if (_fo.xi == "true" && UFO.hasFlashVersion(6, 65)) {
				UFO.createDialog(id);
			}
		}
		document.getElementById(id).style.visibility = "visible";
	},
	
	createCSS: function(selector, declaration) {
		var _h = document.getElementsByTagName("head")[0]; 
		var _s = UFO.createElement("style");
		if (!UFO.uaHas("ieWin")) _s.appendChild(document.createTextNode(selector + " {" + declaration + "}")); // bugs in IE/Win
		_s.setAttribute("type", "text/css");
		_s.setAttribute("media", "screen"); 
		_h.appendChild(_s);
		if (UFO.uaHas("ieWin") && document.styleSheets && document.styleSheets.length > 0) {
			var _ls = document.styleSheets[document.styleSheets.length - 1];
			if (typeof _ls.addRule == "object") _ls.addRule(selector, declaration);
		}
	},
	
	setContainerCSS: function(id) {
		var _fo = UFO.foList[id];
		var _w = /%/.test(_fo.width) ? "" : "px";
		var _h = /%/.test(_fo.height) ? "" : "px";
		UFO.createCSS("#" + id, "width:" + _fo.width + _w +"; height:" + _fo.height + _h +";");
		if (_fo.width == "100%") {
			UFO.createCSS("body", "margin-left:0; margin-right:0; padding-left:0; padding-right:0;");
		}
		if (_fo.height == "100%") {
			UFO.createCSS("html", "height:100%; overflow:hidden;");
			UFO.createCSS("body", "margin-top:0; margin-bottom:0; padding-top:0; padding-bottom:0; height:100%;");
		}
	},

	createElement: function(el) {
		return (UFO.uaHas("xml") && typeof document.createElementNS != "undefined") ?  document.createElementNS("http://www.w3.org/1999/xhtml", el) : document.createElement(el);
	},

	createObjParam: function(el, aName, aValue) {
		var _p = UFO.createElement("param");
		_p.setAttribute("name", aName);	
		_p.setAttribute("value", aValue);
		el.appendChild(_p);
	},

	uaHas: function(ft) {
		var _u = UFO.ua;
		switch(ft) {
			case "w3cdom":
				return (typeof document.getElementById != "undefined" && typeof document.getElementsByTagName != "undefined" && (typeof document.createElement != "undefined" || typeof document.createElementNS != "undefined"));
			case "xml":
				var _m = document.getElementsByTagName("meta");
				var _l = _m.length;
				for (var i = 0; i < _l; i++) {
					if (/content-type/i.test(_m[i].getAttribute("http-equiv")) && /xml/i.test(_m[i].getAttribute("content"))) return true;
				}
				return false;
			case "ieMac":
				return /msie/.test(_u) && !/opera/.test(_u) && /mac/.test(_u);
			case "ieWin":
				return /msie/.test(_u) && !/opera/.test(_u) && /win/.test(_u);
			case "gecko":
				return /gecko/.test(_u) && !/applewebkit/.test(_u);
			case "opera":
				return /opera/.test(_u);
			case "safari":
				return /applewebkit/.test(_u);
			default:
				return false;
		}
	},
	
	getFlashVersion: function() {
		if (UFO.fv[0] != 0) return;  
		if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
			UFO.pluginType = "npapi";
			var _d = navigator.plugins["Shockwave Flash"].description;
			if (typeof _d != "undefined") {
				_d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
				var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
				var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
				UFO.fv = [_m, _r];
			}
		}
		else if (window.ActiveXObject) {
			UFO.pluginType = "ax";
			try { // avoid fp 6 crashes
				var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
			}
			catch(e) {
				try { 
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
					UFO.fv = [6, 0];
					_a.AllowScriptAccess = "always"; // throws if fp < 6.47 
				}
				catch(e) {
					if (UFO.fv[0] == 6) return;
				}
				try {
					var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
				}
				catch(e) {}
			}
			if (typeof _a == "object") {
				var _d = _a.GetVariable("$version"); // bugs in fp 6.21/6.23
				if (typeof _d != "undefined") {
					_d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
					UFO.fv = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
				}
			}
		}
	},

	hasRequired: function(id) {
		var _l = UFO.req.length;
		for (var i = 0; i < _l; i++) {
			if (typeof UFO.foList[id][UFO.req[i]] == "undefined") return false;
		}
		return true;
	},
	
	hasFlashVersion: function(major, release) {
		return (UFO.fv[0] > major || (UFO.fv[0] == major && UFO.fv[1] >= release)) ? true : false;
	},

	writeSWF: function(id) {
		var _fo = UFO.foList[id];
		var _e = document.getElementById(id);
		if (UFO.pluginType == "npapi") {
			if (UFO.uaHas("gecko") || UFO.uaHas("xml")) {
				while(_e.hasChildNodes()) {
					_e.removeChild(_e.firstChild);
				}
				var _obj = UFO.createElement("object");
				_obj.setAttribute("type", "application/x-shockwave-flash");
				_obj.setAttribute("data", _fo.movie);
				_obj.setAttribute("width", _fo.width);
				_obj.setAttribute("height", _fo.height);
				var _l = UFO.optAtt.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[UFO.optAtt[i]] != "undefined") _obj.setAttribute(UFO.optAtt[i], _fo[UFO.optAtt[i]]);
				}
				var _o = UFO.opt.concat(UFO.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") UFO.createObjParam(_obj, _o[i], _fo[_o[i]]);
				}
				_e.appendChild(_obj);
			}
			else {
				var _emb = "";
				var _o = UFO.opt.concat(UFO.optAtt).concat(UFO.optExc);
				var _l = _o.length;
				for (var i = 0; i < _l; i++) {
					if (typeof _fo[_o[i]] != "undefined") _emb += ' ' + _o[i] + '="' + _fo[_o[i]] + '"';
				}
				_e.innerHTML = '<embed type="application/x-shockwave-flash" src="' + _fo.movie + '" width="' + _fo.width + '" height="' + _fo.height + '" pluginspage="http://www.macromedia.com/go/getflashplayer"' + _emb + '></embed>';
			}
		}
		else if (UFO.pluginType == "ax") {
			var _objAtt = "";
			var _l = UFO.optAtt.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[UFO.optAtt[i]] != "undefined") _objAtt += ' ' + UFO.optAtt[i] + '="' + _fo[UFO.optAtt[i]] + '"';
			}
			var _objPar = "";
			var _l = UFO.opt.length;
			for (var i = 0; i < _l; i++) {
				if (typeof _fo[UFO.opt[i]] != "undefined") _objPar += '<param name="' + UFO.opt[i] + '" value="' + _fo[UFO.opt[i]] + '" />';
			}
			var _p = window.location.protocol == "https:" ? "https:" : "http:";
			_e.innerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + _objAtt + ' width="' + _fo.width + '" height="' + _fo.height + '" codebase="' + _p + '//download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=' + _fo.majorversion + ',0,' + _fo.build + ',0"><param name="movie" value="' + _fo.movie + '" />' + _objPar + '</object>';
		}
	},
		
	createDialog: function(id) {
		var _fo = UFO.foList[id];
		UFO.createCSS("html", "height:100%; overflow:hidden;");
		UFO.createCSS("body", "height:100%; overflow:hidden;");
		UFO.createCSS("#xi-con", "position:absolute; left:0; top:0; z-index:1000; width:100%; height:100%; background-color:#fff; filter:alpha(opacity:75); opacity:0.75;");
		UFO.createCSS("#xi-dia", "position:absolute; left:50%; top:50%; margin-left: -" + Math.round(parseInt(_fo.xiwidth, 10) / 2) + "px; margin-top: -" + Math.round(parseInt(_fo.xiheight, 10) / 2) + "px; width:" + _fo.xiwidth + "px; height:" + _fo.xiheight + "px;");
		var _b = document.getElementsByTagName("body")[0];
		var _c = UFO.createElement("div");
		_c.setAttribute("id", "xi-con");
		var _d = UFO.createElement("div");
		_d.setAttribute("id", "xi-dia");
		_c.appendChild(_d);
		_b.appendChild(_c);
		var _mmu = window.location;
		if (UFO.uaHas("xml") && UFO.uaHas("safari")) {
			var _mmd = document.getElementsByTagName("title")[0].firstChild.nodeValue = document.getElementsByTagName("title")[0].firstChild.nodeValue.slice(0, 47) + " - Flash Player Installation";
		}
		else {
			var _mmd = document.title = document.title.slice(0, 47) + " - Flash Player Installation";
		}
		var _mmp = UFO.pluginType == "ax" ? "ActiveX" : "PlugIn";
		var _uc = typeof _fo.xiurlcancel != "undefined" ? "&xiUrlCancel=" + _fo.xiurlcancel : "";
		var _uf = typeof _fo.xiurlfailed != "undefined" ? "&xiUrlFailed=" + _fo.xiurlfailed : "";
		UFO.foList["xi-dia"] = { movie:_fo.ximovie, width:_fo.xiwidth, height:_fo.xiheight, majorversion:"6", build:"65", flashvars:"MMredirectURL=" + _mmu + "&MMplayerType=" + _mmp + "&MMdoctitle=" + _mmd + _uc + _uf };
		UFO.writeSWF("xi-dia");
	},

	expressInstallCallback: function() {
		var _b = document.getElementsByTagName("body")[0];
		var _c = document.getElementById("xi-con");
		_b.removeChild(_c);
		UFO.createCSS("body", "height:auto; overflow:auto;");
		UFO.createCSS("html", "height:auto; overflow:auto;");
	},

	cleanupIELeaks: function() {
		var _o = document.getElementsByTagName("object");
		var _l = _o.length
		for (var i = 0; i < _l; i++) {
			_o[i].style.display = "none";
			for (var x in _o[i]) {
				if (typeof _o[i][x] == "function") {
					_o[i][x] = null;
				}
			}
		}
	}

};

if (typeof window.attachEvent != "undefined" && UFO.uaHas("ieWin")) {
	window.attachEvent("onunload", UFO.cleanupIELeaks);
}

// for slider control in /video/anime
function scrollHorizontal(value, element, slider) {
  element.scrollLeft = Math.round(value/slider.maximum*(element.scrollWidth-element.offsetWidth));
  if (!element.lazy_loaded){
    element.lazy_loaded = true;
    setTimeout(function(){load_lazy_images(element)},1);
  }
}

function load_lazy_images(container){
  var img = container.select('img');
  for (var i=0; i<img.length; i++){
    if (img[i].getAttribute("lazysrc")){
      img[i].src = img[i].getAttribute("lazysrc");
      img[i].removeAttribute("lazysrc");
    }
  }
}

