/* LB.timeline.js Copyright 2010 LetterBlock LLC. All rights reserved. http://letterblock.com/. */

if(!window.LB) window.LB = {};
LB.timeline = (function($){
  var priv = {
    callbackProxy: function(funcs) {
      return function(){
        for(var i=0; i<funcs.length; i++) {
          var func = funcs[i];
          if(func) {
            func.call(this);
          }
        }
      };
    },
    createAnimationFunction: function(settings,time,callback) {
      var query = settings[0]
      var command = settings.slice(1);
      var method = 'animate';
      if('string' == typeof command[0]) {
        // simple string command like 'fadeIn'
        var method = command[0];
        var args = [time];
        var myCallback = callback;
        if(command.length==2) myCallback = priv.callbackProxy([command[1],callback]);
        if(myCallback) args.push(myCallback);
      } else if(command.length==2 && $.isPlainObject(command[1])) {
        // animate call with a property hash and a configuration hash
        if($.isFunction(command[1].complete)) {
          // already has a callback
          command[1].complete = priv.callbackProxy(command[1],callback);
        } else {
          command[1].complete = callback;
        }
        command[1].duration = time;
        var args = command;
      } else {
        // simple animate call
        if($.isFunction(command[command.length-1])) {
          // already has a callback
          command[command.length-1] = priv.callbackProxy([command[command.length-1],callback]);
        } else {
          command.push(callback);
        }
        command.unshift(command.shift(),time);
        var args = command;
      }
      return function(){
        $.fn[method].apply($(query),args);
      };
    },
    createWaitFunction: function(time,callback) {
      if(!callback) return null;
      return function(){ setTimeout(callback,time); }
    }
  };
  var pub = {
    perform: function(actions,timeline,wholeShowDuration) {
      // wholeShowDuration <= 100 will be understood as timeline chars per second instead 
      var maxFrames = 0;
      timeline = timeline.split(/[|\n]/);
      var functions = [];
      for(var i = timeline.length; i--;) {
        if(timeline[i].length > maxFrames) maxFrames = timeline[i].length;
      }
      if(wholeShowDuration <= 100) wholeShowDuration = maxFrames / wholeShowDuration * 1000;
      for(i = timeline.length; i--;) {
        var callback = null;
        // split line into chunks of repeating chars
        var line = timeline[i].match(/(.)\1{0,}/g);
        // then process from tail
        for(var j=line.length; j--;) {
          var segment = line[j];
          var key = segment.charAt(0);
          var time = segment.length / maxFrames * wholeShowDuration;
          var settings = actions[key];
          callback = settings
            ? priv.createAnimationFunction(settings,time,callback)
            : priv.createWaitFunction(time,callback);
        }
        if(callback) functions.push(callback);
      }
      for(i = functions.length; i--;) functions[i]();
    }
  };
  return pub;
})(jQuery);
