// JavaScript Document
/* A slightly edited version of a WebSRT parser written by Philip JÃ¤genstedt (@foolip):
 * http://people.opera.com/philipj/2010/07/21/html5-video-webinar/demos/track.html
 * 
 * A more thorough parser, requiring the MooTools library, is here:
 * http://www.storiesinflight.com/js_videosub/
 * 
 * I plan to upload this to Github eventually, but it doesn't yet support the 'web' part of 'websrt'
 * @eddhannay
 */


(function($){  
 $.fn.WebSRT = function(options) {
  
  var defaults = {  
    subtitles: false,  
    callback: false,  
    now: 0,
    debug: false,
    tScale: 1,
    tOffset: 0,
    tMargin: 0.2,
    captionContainerId: 'websrt-caption-container'
  };  

  var options = $.extend(defaults, options);
  
  function SetTimeoutObj(o, t, f, a) {
    return setTimeout(function() {
      f.apply(o,a);
    }, t);
  }
    
  function updateLoop() {
    options.now = this.currentTime;
    updateSubtitles();
    if (!this.paused)
      SetTimeoutObj(this,10,updateLoop,[]);
  };
  
    function log(output){
      if (options.debug)
        console.log(output);
    }
  
    /* Parses a WebSRT file in to an array
     * [
     *  {
     *   'id'    : the index of the sub in the file
     *   'start' : the start time of the subtitle 
     *   'stop'  : the end time for the subtitle
     *   'text'  : text content for the subtitle
     *  },....
     * ]
     * Based on: http://people.opera.com/danield/html5/websrt/
     */
    function parseSrt(srtText) {
      var regex = /^(\d+)[\n]+(\d\d|\d):(\d\d):(\d\d),(\d{3}) --\> (\d\d|\d):(\d\d):(\d\d),(\d{3})(.*)\n([\s\S]*)/m; 
      var subtitles = [];

      var srtText = srtText.replace(/\r/g, "");
      var srtGroups = srtText.split(/\n\n/);

      for(var i=0 in srtGroups){
        var srt = srtGroups[i];
        t = regex.exec(srt);
        if (t){
          var tStart = 3600*t[2] + 60*t[3] + 1*t[4] + parseFloat('.'+t[5]);
          var tStop = 3600*t[6] + 60*t[7] + 1*t[8] + parseFloat('.'+t[9]);
          subtitles.push({'id':t[1],
                         'start': options.tScale*(tStart + options.tOffset),
                         'stop': options.tScale*(tStop + options.tOffset) - options.tMargin, /* tMargin allows for transitions (fade in/out, etc.) ,*/
                         'text': t[11],
                         'shown':false,
                         'commands':t[10]});

        } else {
          log('Parsing failed: '+srt);
        }
      }
        
      
          /*
          d:vertical,vertical-lr (direction)
          l:93% (line position)
          l:-2 (line position)
          t:900% (text position)
          s:900% (text size)
          a:start,middle,end
          <voice> */

      log('Loaded and parsed '+subtitles.length+' subtitles');
      options.subtitles = subtitles;
      dispatchEvent('loaded');
      return this;
    }
  
    function dispatchEvent(eventType,subtitle){
      switch(eventType){
        case 'show' : 
          (options.callback)?options.callback.showCaption(subtitle):showCaption(subtitle);
          break;
        case 'hide' :
          (options.callback)?options.callback.hideCaption(subtitle):hideCaption(subtitle);
          break;
        case 'loaded' :
          (options.callback)?options.callback.loadedSubtitles(options.targetElement):loadedSubtitles(options.targetElement);
         break;
      }
    }
    
    function updateSubtitles(){
      var currentText = null;
      for (var i = 0, caplen = options.subtitles.length; i < caplen; i++) {
        if (options.now >= options.subtitles[i].start && options.now <= options.subtitles[i].stop) {
          if(options.subtitles[i].shown==false){
            dispatchEvent('show',options.subtitles[i]);
            options.subtitles[i].shown=true;
          }
        } else if(options.subtitles[i].shown==true && options.now > options.subtitles[i].stop) {
          dispatchEvent('hide',options.subtitles[i]);
          options.subtitles.splice(i,1);
          caplen--;
          log('Removing '+i);
        } else {
//          log('Broke on ');
//          break;
        }
      }
      return this;
    }
  
  
    // If this is called, we're rendering the subtitles ourselves. Let's make a div for it
    function loadedSubtitles(element){
      log("Loaded :()");
      $(element).wrap($('<div></div>',{'id':options.captionContainerId,'style':'position: relative;text-align: center'}));
      $(element).after($('<div></div>',{'class':'websrt-subtitles'}));
      $('#'+options.captionContainerId+' .websrt-subtitles').css('position','absolute').css('bottom','3em').css('width','100%').css('z-index',100).css('margin','0 auto').css('color','#fff').css('font-family','Helvetica, Arial, sans-serif').css('font-weight','bold').css('text-shadow','#000000 1px 1px 0px');
      return this;
    }
  
    // Probably overridden in callback
    function showCaption(subtitle){
      log('Showing caption:'+subtitle.text);
      $('#'+options.captionContainerId+' .websrt-subtitles').html(subtitle.text);
      return this;
    }
    
    // Remove current caption
    function hideCaption(subtitle){
      return this;
    }
    
    
    return this.each(function(){
      options.targetElement = this;
      obj = $(this);
      if (true) { //TODO : fix //!document.createElement('track').track)
        log('Fetching '+obj.find('track').attr('src'));
        
        $.ajax({
          url: obj.find('track').attr('src'),
          dataType: 'text',
          success: parseSrt
        });
        
        $.extend(true,this,options.callback);
        

        // TODO: if subtitles
        this.addEventListener('play', updateLoop, false);
        this.addEventListener('seeked', updateSubtitles, false);
        return this;
      } else {
        log('Track supported natively. Doing nothing');
        
      }
  });
  
  
};})(jQuery);

