// we're storing each youtube object (video) in an array, and passing the array key into the class, so the class instance can refer to itself externally
// this is necessary for two reasons
// first, the event listener function we pass to Youtube has to be globally accessible, so passing "this.blah" doesn't work
// it has to be passed as a string also, so putting "this" in quotes makes it lose its special meaning
// second, when we create timeout functions, the meaning of "this" inside that function loses its scope, so we have to refer to the class externally from there too.


// _yt is the global youtube array that stores each youtube object. yti is the array key, incremented automatically for each new object created
var _yt = [], _yti = 0;


// this is the function the youtube player calls once it's loaded. 
// each time it's called, it creates a new object in the global array, and passes the array key into the class so the class can refer to itself externally
function onYouTubePlayerReady( id ) {
  _yti++;
  _yt[ _yti ] = new _yto( id, _yti );
}


function _yto( id, i ) {
  
  if( !id || !i ) return;
  
  this.id = id;
  this.mytime;
  this.scrubTimer;
  this.startTimer;
  this.last = 'none';
  this.scrubbing = false;
  
  this.o = document.getElementById( this.id );
  this.o.addEventListener("onStateChange", "_yt["+i+"].onPlayerStateChange" );
  
  this.onPlayerStateChange = function( newState ) {
    
    // some events rely on a timer to determine what action was performed, we clear it on every state change.
    if( this.myTime != undefined ) clearTimeout( this.myTime );
    
    // pause - happens when clicking pause, or seeking
    // that's why a timeout is used, so if we're seeking, once it starts playing again, we log it as a seek and kill the timer that would have logged the pause
    // we're only giving it 2 seconds to start playing again though. that should be enough for most users.
    // if we happen to log a pause during the seek - so be it.
    if( newState == '2' ) {
      this.myTime = setTimeout( function() {
        _yt[i].videoLog('pause');
        _yt[i].last = 'pause';
        _yt[i].scrubbing = false;
        }, 2000 );
      if( this.scrubbing == false ){
        this.last = 'pre-scrub';
        this.scrubbing = true;
      }
    }
    
    // play
    else if( newState == '1' ) {
      
      switch( this.last ) {
        
        case 'none':
          this.killTimers();
          this.startTimer = setInterval( this.startRun, 200 );
          break;
        
        case 'pause':
          // i dont think we need a timeout here?
          //this.myTime = setTimeout( function() {
            _yt[i].videoLog('play');
            _yt[i].last = 'play';
          //}, 2000 );
          break;
        
        case 'pre-scrub':
          this.killTimers();
          this.scrubTimer = setInterval( this.scrubRun, 2000 ); // give it a second to buffer
          break;
      }
    }
    
    // end
    else if( newState == '0' ) {
      this.last = 'none';
      this.videoLog('end');
    }
  }
  
  
  // have to use external calls here because these are set as timeouts, which makes "this" change context (apparently)
  this.scrubRun = function() {
    _yt[i].videoLog('seek');
    _yt[i].killTimers();
    _yt[i].last = 'scrub';
    _yt[i].scrubbing = false;
  }

  this.startRun = function() {
    _yt[i].videoLog('play');
    _yt[i].killTimers();
    _yt[i].last = 'start';
  }

  this.killTimers = function() {
    if( this.startTimer ) {
      clearInterval( this.startTimer );
      this.startTimer = null;
    }
    if( this.scrubTimer ){
      clearInterval( this.scrubTimer );
      this.scrubTimer = null;
    }
  }
  
  
  
  this.videoLog = function( action ) {
    if( window.videogoyes ) videogoyes( action, this.videoTime(), this.videoURL(), this.videoTitle());
  }
  
  this.videoTime = function() {
    return Math.round( this.o.getCurrentTime() );
  }
  
  this.videoURL = function() {
    return this.o.getVideoUrl().split('&')[0]; // remove any extra parameters - we just want the first one, which is the video ID.
  }
  
  this.videoTitle = function() {
    // titles have to be defined in an external object
    if( window._ytmeta && _ytmeta[ this.id ] ) return _ytmeta[ this.id ].title || '';
  }
}





