// requires jquery.cookie.js
// http://plugins.jquery.com/project/Cookie


// Setup DS Namespace if not set up already
var undefined;
var DS = (DS == undefined) ? {} : DS;


// Analtyics and Cookies are built with the adapter pattern so that 
// both Google Analytics and Omniture (plus others) can be used as the analytics backend


// Analytics Adapters
// Must have the following public methods:
// .get_custom_variable(index)
  // @index : integer
// .set_custom_variable(index, key, value, scope, overwrite)
  // @index : integer
  // @key  : string
  // @value : string
  // @scope : integer
  // @overwrite : boolean (default true)

DS.GOOGLE_ANALYTICS_ADAPTER = function(analytics_object) {
  var $ = jQuery;
  var that = this;
  
  this.set_custom_variable = function(index, key, value, scope, overwrite) {
    var undefined;
    var overwritable = (overwrite != undefined) ? overwrite : true;

    function set_custom_variable() {
      return analytics_object._setCustomVar(index, key, $.truncate(value, 64 - key.length, true), scope);
    }
    if (overwritable) {
      return set_custom_variable();
    }
    else {
      return (that.get_custom_variable(index) == undefined || "") ? set_custom_variable() : true;
    }
  };
  
  this.get_custom_variable = function(index) {
    if (analytics_object._getVisitorCustomVar(index) != null) {
      return unescape(analytics_object._getVisitorCustomVar(index));
    }
    return analytics_object._getVisitorCustomVar(index);
  };
};


// Cookie adapters
// Must have the following public methods
// .keywords returns string
// .campaign returns string
// .source returns string
// .medium
// .ad_content

DS.GOOGLE_ANALYTICS_COOKIE_ADAPTER = function() {
  var $ = jQuery;
  var that = this;
  var cookies = {
    utmz : function() { return $.cookie('__utmz'); }
  };
  var on_ready_events = [];

  function find_cookie_value(key, string) {
     var keys = {
       source      : { match : /utmcsr=([^\|]+)/ },
       campaign    : { match : /utmccn=\((.*?)\)/ },
       medium      : { match : /utmcmd=([^\|]+)/ },
       keywords    : { match : /utmctr=([^\|]+)/ },
       ad_content  : { match : /utmcct=\((.*?)\)/ }
     };
     var match = keys[key]['match'];
     if (match.test(string)) {
       return string.match(match)[1];
     }
     else { return ""; }
   };
   
   function fire_ready_events_when_cookies_are_loaded() {
     var run_limit = 50;
     var runs = 0;
     var ready_check = setInterval(function() {
       if (runs >= run_limit) {
         clearInterval(ready_check);
       }
       else if ($.cookie('__utmz') != undefined) {
         clearInterval(ready_check);
         that.refresh();
         $.each(on_ready_events, function(index, on_ready_event) {
           on_ready_event();             
         });
       }
       else { 
         runs++;
        }
     }, 250);
   };

   function update_values_from_cookies() {
     that.keywords    = find_cookie_value('keywords', cookies.utmz());
     that.campaign    = find_cookie_value('campaign', cookies.utmz());
     that.source      = find_cookie_value('source', cookies.utmz());
     that.medium      = find_cookie_value('medium', cookies.utmz());
     that.ad_content  = find_cookie_value('ad_content', cookies.utmz());     
   };

   function init() {
     fire_ready_events_when_cookies_are_loaded();
     update_values_from_cookies();     
   }

   this.ready = function(on_ready_event) {
      on_ready_events.push(on_ready_event);
   };

   this.refresh = function() { update_values_from_cookies(); };

   init();
};


DS.CUSTOM_VARIABLE_PARSER = function(analytics_adapter, user_options) {
  var $ = jQuery;
  var options = {};
  $.extend(options, user_options);

  var that = this;
  var undefined;

  function load_custom_variables_as_methods() {
    $.each(options.custom_variables, function(index, cv) {
      var undefined;
      var custom_variable_value = analytics_adapter.get_custom_variable(cv.index);
      if ($.isArray(cv.members)) { 
        if (custom_variable_value != undefined) {
          var values = custom_variable_value.split(cv.delimiter);          
          $.each(cv.members, function(index, member) {
            that[member] = values[index];
          });
        }
        else {
          $.each(cv.members, function(index, member) {
            that[member] = "";
          });
        }
      }
      else if (cv.members == undefined) {
        that[cv.key] = cv.value;
      }
      else {
        that[cv.members] = cv.value;
      }
    });
    return true;
  }

  function init() {
    return load_custom_variables_as_methods();
  };
  
  init();

  this.refresh = function() { return load_custom_variables_as_methods(); };
};


DS.VISITOR = function(analytics_adapter, cookie_adapter, user_options) {
  var $ = jQuery;
  var options = {};
  $.extend(options, user_options);
  
  function init() {
    $.each(options.custom_variables, function(index, cv) {
      analytics_adapter.set_custom_variable(cv.index, cv.key, cv.value, cv.scope, false);  
    });
  };
  
  init();
  
  var cv_parser = new DS.CUSTOM_VARIABLE_PARSER(analytics_adapter, options);
  
  this.custom_variable_parser = cv_parser;
  this.analytics = analytics_adapter;  
  this.cookies = cookie_adapter;
  
};


(function(){
  $.truncate = function(string, length, escaped) {

    // @string (string)   : string to be truncated
    // @length (integer)  : maximum length of the outputted string
    // @escaped (boolean) : should the outputted length be based on an escaped string

    var escape_string = escaped || false;
    
    function get_length(string) {
      return (escape_string) ? escape(string).length : string.length;
    }
    
    if (string.length <= length) {
      return string;
    }
    else {
      var result = [];        
      $.each(string.split(/\s/), function(index, word) {
        if (get_length(result.join(' ') + word + '...') <= length) {
          result.push(word);
        }
        else {
          return false;
        }
      });
      return result.join(' ') + '...';
    }
  };
  
  $.fn.analytics_form = function(visitor, user_options) {
    var options = {};
    $.extend(options, user_options);

    return this.each(function() {
      var $form = $(this);
      
      function input_builder(options) {
        $form.append('<input type="' + options.input_type + '" name="' + options.name + '" id="' + options.id + '" value="' + options.value + '" />');
      }
      
      function build_input_name(name) {
        if (options.namespace) {
          return options.namespace + "[" + name + "]";
        }
        else {
          return name;
        }
      }

      $.each(['keywords', 'source', 'campaign'], function(index, element) {
        input_builder({
          name        : build_input_name("original_" + element),
          id          : "original_" + element,
          input_type  : "hidden",
          value       : visitor.custom_variable_parser[element]
        });
        input_builder({
          name        : build_input_name("current_" + element),
          id          : "current_" + element,
          input_type  : "hidden",
          value       : visitor.cookies[element]
        });
        
      });
    });
  };
  
})(jQuery);