/*
* jquery-google-analytics plugin
*
* A jQuery plugin that makes it easier to implement Google Analytics tracking,
* including event and link tracking.
*
* Adds the following methods to jQuery:
*   - $.trackPage() - Adds Google Analytics tracking on the page from which
*     it's called.
*   - $.trackEvent() - Tracks an event using the given parameters.
*   - $('a').track() - Adds event tracking to element(s).
*   - $.timePageLoad() - Measures the time it takes  an event using the given parameters.
*
* Features:
*   - Improves page load time by loading Google Analytics code without blocking.
*   - Easy and extensible event and link tracking plugin for jQuery and Google Analytics
*   - Automatic internal/external link detection. Default behavior is to skip
*     tracking of internal links.
*   - Enforces that tracking event handler is added to an element only once.
*   - Configurable: custom event tracking, skip internal links, metadata
*     extraction using callbacks.
*
* Copyright (c) 2008-09 Christian Hellsten
*
* Plugin homepage:
*   http://aktagon.com/projects/jquery/google-analytics/
*   http://github.com/christianhellsten/jquery-google-analytics/
*
* Examples:
*   http://aktagon.com/projects/jquery/google-analytics/examples/
*   http://code.google.com/apis/analytics/docs/eventTrackerGuide.html
*
* Repository:
*   git://github.com/christianhellsten/jquery-google-analytics.git
*
* Version 1.1.2
*
* Tested with:
*   - Mac: Firefox 3, Safari 3
*   - Linux: Firefox 3
*   - Windows: Firefox 3, Internet Explorer 6
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Credits:
*   - http://google.com/analytics
*   - http://lyncd.com: 
*       Idea for trackPage method came from this blog post: http://lyncd.com/2009/03/better-google-analytics-javascript/
*/
(function($) {

  var pageTracker;

  /**
   * Enables Google Analytics tracking on the page from which it's called. 
   *
   * Usage:
   *  <script type="text/javascript">
   *    $.trackPage('UA-xxx-xxx', options);
   *  </script>
   *
   * Parameters:
   *   account_id - Your Google Analytics account ID.
   *   options - An object containing one or more optional parameters:
   *     - onload - boolean - If false, the Google Analytics code is loaded
   *       when this method is called instead of on window.onload.
   *     - status_code - The HTTP status code of the current server response.
   *       If this is set to something other than 200 then the page is tracked
   *       as an error page. For more details: http://www.google.com/support/analytics/bin/answer.py?hl=en&answer=86927
   *     - callback  - function to be executed after the Google Analytics code is laoded and initialized
   *
   */
  $.trackPage = function(account_id, options) {
    var host = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
    var script;

    // Use default options, if necessary
    var settings = $.extend({}, {onload: true, status_code: 200}, options);
    var src  = host + 'google-analytics.com/ga.js';

    function init_analytics() {
      if (typeof _gat != undefined) {
        debug('Google Analytics loaded');

        pageTracker = _gat._getTracker(account_id);
				
        if(settings.status_code == null || settings.status_code == 200) {
          pageTracker._trackPageview();
        } else {
          debug('Tracking error ' + settings.status_code);
          pageTracker._trackPageview("/" + settings.status_code + ".html?page=" + document.location.pathname + document.location.search + "&from=" + document.referrer);
        }
        if($.isFunction(settings.callback)){
          settings.callback();
        }
      }
      else { 
        throw "_gat is undefined"; // setInterval loading?
      }
    }

    load_script = function() {
      $.ajax({
        type: "GET",
        url: src,
        success: function() {          
          init_analytics(); 
        },
        dataType: "script",
        cache: true // We want the cached version
      });
    }
    
    // Enable tracking when called or on page load?
    if(settings.onload == true || settings.onload == null) {
      $(window).load(load_script);
    } else {
      load_script();
    }
  }

  /**
   * Tracks an event using the given parameters. 
   *
   * The trackEvent method takes four arguments:
   *
   *  category - required string used to group events
   *  action - required string used to define event type, eg. click, download
   *  label - optional label to attach to event, eg. buy
   *  value - optional numerical value to attach to event, eg. price
   *  skip_internal - optional boolean value. If true then internal links are not tracked.
   *
   */
  $.trackEvent = function(category, action, label, value) {
    if(typeof pageTracker == 'undefined') {
      debug('FATAL: pageTracker is not defined'); // blocked by whatever
    } else {
      pageTracker._trackEvent(category, action, label, value);
    }
  };

  /**
   * Adds click tracking to elements. Usage:
   *
   *  $('a').track()
   *
   */
  $.fn.track = function(options) {
    // Add event handler to all matching elements
    return this.each(function() {
      var element = $(this);

      // Prevent an element from being tracked multiple times.
      if (element.hasClass('tracked')) {
        return false;
      } else {
        element.addClass('tracked');
      } 

      // Use default options, if necessary
      var settings = $.extend({}, $.fn.track.defaults, options);

      // Merge custom options with defaults.
      var category = evaluate(element, settings.category);
      var action   = evaluate(element, settings.action);
      var label    = evaluate(element, settings.label);
      var value    = evaluate(element, settings.value);
      var event_name = evaluate(element, settings.event_name);
      
      var message = "category:'" + category + "' action:'" + action + "' label:'" + label + "' value:'" + value + "'";
      
      debug('Tracking ' + event_name + ' ' + message);

      // Bind the event to this element.
      element.bind(event_name + '.track', function() {       
        // Should we skip internal links? REFACTOR
        var skip = settings.skip_internal && (element[0].hostname == location.hostname);
      
        if(!skip) {
          $.trackEvent(category, action, label, value);
          debug('Tracked ' + message);
        } else {
          debug('Skipped ' + message);
        }

        return true;
      });
    });
    
    /**
     * Checks whether a setting value is a string or a function.
     * 
     * If second parameter is a string: returns the value of the second parameter.
     * If the second parameter is a function: passes the element to the function and returns function's return value.
     */
    function evaluate(element, text_or_function) {
      if(typeof text_or_function == 'function') {
        text_or_function = text_or_function(element);
      }
      return text_or_function;
    };
  };

  /**
   * Prints to Firebug console, if available. To enable:
   *   $.fn.track.defaults.debug = true;
   */
  function debug(message) {
    if (typeof console != 'undefined' && typeof console.debug != 'undefined' && $.fn.track.defaults.debug) {
      console.debug(message);
    }
  };

  /**
   * Default (overridable) settings.
   */
  $.fn.track.defaults = {
    category      : function(element) { return (element[0].hostname == location.hostname) ? 'internal':'external'; },
    action        : 'click',
    label         : function(element) { return element.attr('href'); },
    value         : null,
    skip_internal : true,
    event_name    : 'click',
    debug         : false
  };
})(jQuery);


/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the the SEOPosition library.
 *
 * The Initial Developer of the Original Code is
 * Andy Edmonds <andyed@gmail.com>
 *
 * Portions created by the Initial Developer are Copyright (C) 2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 * Jim MacKay <jim@jagvent.com> ; Generalized, Added More SEs, Google TLD,3LD,Images,Page,Position
 *
 * Learn more at http://alwaysbetesting.com/abtest/index.cfm/2009/4/22/Log-Your-Exact-Google-Rank-with-Google-Analytics
 * ***** END LICENSE BLOCK ***** */

var seoposition = {
		ref:  document.referrer.toString(),
		init: function () {

				/* Google Page */
				this.ssGetPageNum ("SEO Google Page",".google.","q=","start=",0,10);
				
				/* Google Position */
				this.ssGetPosition ("SEO Google Position",".google.com/url","q=","cd=");

				/* Yahoo */
				this.ssGetPageNum ("SEO Yahoo Page",".yahoo.","p=","b=",1,10);
				
				/* MSN */
				this.ssGetPageNum ("SEO MSN Page",".msn.","q=","first=",1,10);
				
				/* Live */
				this.ssGetPageNum ("SEO Live Page",".live.","q=","first=",1,10);
				
				/* Bing */
				this.ssGetPageNum ("SEO Bing Page",".bing.","q=","first=",1,10);
				
				/* AOL */
				this.ssGetPageNum ("SEO AOL Page",".aol.","query=","page=",1,1);		

				/* Google TLD */
				this.ssGetTld ("SEO Google TLD",".google.","q=","start=",0,10);

				/* Google 3LD */
				this.ssGet3ld ("SEO Google Site",".google.");
			
				/* Google Images */
				this.ssGetGoogleImages ("SEO Google Images","images.google.");
			
		}
}


// source = engine name for report
// domain = 2nd Level of Domain; i.e. "images.google." including the "."

seoposition.ssGetGoogleImages = function(source,domain) {
    	if(seoposition.ref.indexOf(domain) > -1) {  
		var ssImageNum = seoposition.ssGetParam("start",seoposition.ref);
		var ssKeyword = unescape(seoposition.ssGetParam("prev",seoposition.ref));
		ssKeyword = unescape(seoposition.ssGetParam("q",ssKeyword));
		ssKeyword = ssKeyword.replace(/\+/g, " ");
		if(pageTracker != 'undefined')  {
			pageTracker._trackEvent(source, ssKeyword, document.location.pathname, parseInt(ssImageNum));
		}
	}
}



// source = engine name for report
// domain = 2nd Level of Domain; i.e. ".google." including the "."

seoposition.ssGet3ld = function(source,domain) {
    	if(seoposition.ref.indexOf(domain) > -1) {  
		var ss3ld = seoposition.ref.slice(seoposition.ref.indexOf("//") + 2, seoposition.ref.indexOf(domain) + domain.length - 1);
		if(pageTracker != 'undefined')  pageTracker._trackEvent(source, ss3ld, document.location.pathname, 1);		
	}
}
		

// source = engine name for report
// domain = 2nd Level of Domain; i.e. ".google." including the "."
// qParam = query parameter name for the engine
// pParam = page parameter name for the engine
// offset & divisor are used to calculate page properly
//  so {page reported} = 1 + ( {pParam Value} - {offset} ) / {divisor}

seoposition.ssGetTld = function(source,domain,qParam,pParam,offset,divisor) {
    	if(seoposition.ref.indexOf(domain) > -1) {  
		var ssTld = seoposition.ref.substring(seoposition.ref.indexOf(domain) + domain.length - 1);
		ssTld = ssTld.substring(0,ssTld.indexOf("/"));
		var ssPage = seoposition.ssCalcPageNum(pParam,offset,divisor);
		if(pageTracker != 'undefined')  pageTracker._trackEvent(source, ssTld, document.location.pathname, ssPage);
	}
}



// source = engine name for report
// qParam = query parameter name for the engine
// pParam = page parameter name for the engine
// offset & divisor are used to calculate page properly
//  so {page reported} = 1 + ( {pParam Value} - {offset} ) / {divisor}

seoposition.ssGetPageNum = function (source,domain,qParam,pParam,offset,divisor) {
    	if(seoposition.ref.indexOf(domain) > -1  && seoposition.ref.indexOf(qParam) > -1 ) {
		var page = seoposition.ssCalcPageNum(pParam,offset,divisor);
		if(pageTracker != 'undefined') pageTracker._trackEvent(source, "Page" + page, document.location.pathname, page);
	}
}



// source = engine name for report
// qParam = query parameter name for the engine
// pParam = page parameter name for the engine
//  so {position reported} = {pParam Value}

seoposition.ssGetPosition = function (source,domain,qParam,pParam) {
    	if(seoposition.ref.indexOf(domain) > -1  && seoposition.ref.indexOf(qParam) && seoposition.ref.indexOf(pParam) > -1 ) {
		var position = seoposition.ssGetParam(pParam,seoposition.ref) * 1;
		var position_text = "Position-" + ((position < 10)?"0":"") + position;
		if(pageTracker != 'undefined')  pageTracker._trackEvent(source, position_text, document.location.pathname, position);
	}
}



// pParam = page parameter name for the engine
// offset & divisor are used to calculate page properly
//  so {page returned} = 1 + ( {pParam Value} - {offset} ) / {divisor}

seoposition.ssCalcPageNum = function (pParam,offset,divisor) {
	if(seoposition.ref.indexOf(pParam) > -1) {
		if(seoposition.ref.split("?").length) {					
			return 1+(seoposition.ssGetParam(pParam,seoposition.ref)-offset)/divisor;
		} 
	} else {
			return 1;
	}
}





// ssGetParam retreives a parameter value from a string

seoposition.ssGetParam = function (sParam,sString) {
	var arParams = sString.split("?")[1];							
	arParams = arParams.split("&");
	for(var i=0;i<arParams.length;i++) {
		if(arParams[i].indexOf(sParam) > -1 ) {
			return arParams[i].split("=")[1];
		}
	}
}



