/* ===============================================================================

   eConduit Pipeline Stub File
   Release 2.0rc1
   Copyright (c) 2010, Arc Worldwide

   Two configuation variables are listed below and should be set based on the 
   specifics of your deployment:

   * econduit_base_path - URL path to the root of the eConduit Pipeline directory, 
                          including the top-level "econduit" directory.
   * econduit_exclude_names - list of filenames for default pages, such as index.html

   NOTE: This is a pre-release version that includes code for logging debugging 
         messages to the Javascript console.  These will be removed in the final
         production release.
   
   =============================================================================== */

var econduit_base_path = "/_res/js/econduit/";
var econduit_debug = true;
var econduit_exclude_names = ["index.html", "index.htm", "index.php", "default.html", 
    "default.html", "index.shtml", "index.php", "index.php3", "index.php4", "default.asp",
    "default.aspx", "index.asp", "index.aspx"];

/* ===============================================================================
   END OF CONFIGURATION SECTION
   =============================================================================== */


/* http://benalman.com/projects/javascript-debug-console-log/ */
window.debug=(function(){var c=this,e=Array.prototype.slice,b=c.console,i={},f,g,j=9,d=["error","warn","info","debug","log"],m="assert clear count dir dirxml group groupEnd profile profileEnd time timeEnd trace".split(" "),k=m.length,a=[];while(--k>=0){(function(n){i[n]=function(){j!==0&&b&&b[n]&&b[n].apply(b,arguments)}})(m[k])}k=d.length;while(--k>=0){(function(n,o){i[o]=function(){var q=e.call(arguments),p=[o].concat(q);a.push(p);h(p);if(!b||!l(n)){return}b.firebug?b[o].apply(c,q):b[o]?b[o](q):b.log(q)}})(k,d[k])}function h(n){if(f&&(g||!b||!b.log)){f.apply(c,n)}}i.setLevel=function(n){j=typeof n==="number"?n:9};function l(n){return j>0?j>n:d.length+j<=n}i.setCallback=function(){var o=e.call(arguments),n=a.length,p=n;f=o.shift()||null;g=typeof o[0]==="boolean"?o.shift():false;p-=typeof o[0]==="number"?o.shift():n;while(p<n){h(a[p++])}};return i})();


function eConduit() {

    this.initialized = false;
    this.has_qa = false;
    this.events = {};
    this.tools = {};
    this.event_queue = [];
    this.tool_cache = {};
    this.library_code = {};

    this.getToolCache = function(tool_name) {
        if (this.tool_cache[tool_name] == undefined) this.tool_cache[tool_name] = {};
	return this.tool_cache[tool_name]
    }

    this.initialize = function() {
	// Populates all internal data structures with page, library data and begins the tracking process
	this.initTools();
	this.initEvents();
	this.initQA();
	this.initialized = true;

        this.trackEvent("__pageload__");

	// Track any queued up events
	for (var e in this.event_queue) { var evt = this.event_queue[e]; this.trackEvent(evt); }

	if (econduit_debug) debug.log("At end of this.init method " + this.event_queue);
    }

    this.initEvents = function() { 
	/* Placeholder in case we need to do something here. */
    }

    this.initTools = function() {
	if (econduit_debug) debug.log("Beginning tool initiation");
	for (var tool_name in this.tools) {
	    try {
		if (econduit_debug) debug.log("Initializing " + tool_name);
		this.tools[tool_name]['init'](tool_name, this.tools[tool_name]['tool_parameter_values']);
	    } catch (e) {
		if (econduit_debug) debug.error("Exception in tool initiation: " + e);
	    }
	}

    }

    this.initQA = function() { 
	/* Placeholder until we build out the QA functionality */
    }

    this.registerEvent = function(event_name, tools, variables) { 
	/* Add an event to the known set of events for this page.
           - event_name is a text string that uniquely identifies the event
           - tools is a list of tool textkeys for the tools associated with this event
           - variables is a dictionary of variable name -> variable value mappings, i.e. 
             {uri: '/About_Us', content_group: 'about'}
           Currently doesn't support registering an event multiple times 
        */
	if (!this.events[event_name]) this.events[event_name] = {tools: tools, variables: variables};
    }

    this.registerTool = function(tool_textkey, init_func, track_func, tool_parameter_values, parameter_mapping) {
	/* Add this tool to the known set of tools for this page
           - init_func is a function that is called to setup the tool when the page loads
           - track_func is a function that is called to track each event, it is passed a dictionary that maps
             parameter names to values (i.e. {dcs_uri: '/About_Us', wt_cg: 'about'}
           - tool_parameter_values is a dict that maps tool parameters to their values
           - parameter_mapping is a dictionary that maps from general event variables to parameters that the
             tool is expecting to receive (i.e. {uri: 'dcs_uri', content_group: 'wt_cg'}
        */
	this.tools[tool_textkey] = {init: init_func, 
				    track: track_func,
                                    tool_parameter_values: tool_parameter_values,
				    parameter_mapping: parameter_mapping
				   };
    }

    this.trackEvent = function(event_name) {
	/* Coordinator method for tracking events.  If we're not yet initialized, just queue up for later */
	if (!this.initialized) {
	    if (econduit_debug) debug.log("Queuing tracking for event " + event_name);
	    this.event_queue.push(event_name);
	}
	if (this.initialized) {
	    
	    if (econduit_debug) debug.log("Tracking event " + event_name);
	    if (!this.events[event_name]) {
		if (econduit_debug) debug.error("No event found with name " + event_name);
		return; 
	    }
	    
	    var tools = this.events[event_name].tools;
	    var variables = this.events[event_name].variables;
	    if (econduit_debug) debug.log(DumpObjectIndented(variables, '  o '));
	    for (var t in tools) {
		try {
		    var tool = this.tools[tools[t]];
		    if (econduit_debug) debug.log("Tracking event " + event_name + " with tool " + tools[t]);
		    
		    // Build the parameter array
		    var params = {}
		    for (var p in tool.parameter_mapping) {
			params[p] = variables[tool.parameter_mapping[p]];
		    }

		    // Call the tracking
		    tool.track(tools[t], params);
		} catch(e) { if (econduit_debug) debug.error(e); }
		    
	    }
	}
    }

    this.bootstrap = function() {
	// Bootstrap method to request the library and page code dynamically from the eConduit Pipeline server

	if (econduit_debug) debug.log("At beginning of bootstrap function");
	var l = document.location;
	var path = l.pathname;

	// Strip off trailing page information if it's one of the default pages
	var path_pieces = path.split('/');
	var last_path_piece = path_pieces[path_pieces.length-1];
	for (i in econduit_exclude_names) {
	    if (last_path_piece == econduit_exclude_names[i]) {
		path_pieces.pop()
		break;
	    }
	}
	path = path_pieces.join('/')

	// Trim the trailing slash if it's present from the path and the base path
	if (path[path.length-1] == '/') path = path.substr(0, path.length-1);
	if (econduit_base_path[econduit_base_path.length-1] == '/')
	    econduit_base_path = econduit_base_path.substr(0, econduit_base_path.length-1);	    

	var page = econduit_base_path + path + "/__econduit_page.js";
	var default_page = econduit_base_path + path + "/__econduit_default_page.js";
	var library = econduit_base_path + "/__econduit_library.js";

	if (econduit_debug) debug.log("Loading library script for " + library);
	if (econduit_debug) debug.log("Loading page script for " + page);

	// Need to replace this with the actual URLs, once we're able to retrieve them
	this.loader.script(library).script(page).block(function() { eConduit.initialize(); });

	if (econduit_debug) debug.log("Completed bootstrap function");
    }
    
}
 
eConduit = new eConduit();


// LAB.js (LABjs :: Loading And Blocking JavaScript) | v0.8 (c) Kyle Simpson | MIT License
(function(a){var d="undefined",m="string",j="head",h="body",n=true,k=false,i=a.document,c=a.setTimeout,g=function(p){return i.getElementsByTagName(p)},f={head:g(j),body:g(h)},b={};if(typeof f[j]!==d&&f[j]!==null&&f[j].length>0){f[j]=f[j][0]}else{f[j]=null}if(typeof f[h]!==d&&f[h]!==null&&f[h].length>0){f[h]=f[h][0]}else{f[h]=null}function e(p){return(typeof p===m&&p.length)?/^([^#?]*\/)?([^?\/#]*)(\?.*)?(#.*)?$/i.exec(p)[2]:""}function o(r){var p=g("script"),s=0,q;while(q=p[s++]){if(typeof q.src===m&&r===e(q.src)){return n}}return k}function l(w,t,A){w=!(!w);t=((typeof t===m)?t:j);var y=k,v=function(){},q=k,z=null,s={},r=[];function u(B){if((this.readyState&&this.readyState!=="complete"&&this.readyState!=="loaded")||B.done){return}this.onload=this.onreadystatechange=null;B.done=n;function C(){for(var D in s){if(s.hasOwnProperty(D)&&!(s[D].done)){return k}}return(y=n)}if(C()){v()}}function p(F){var E=F.src,D=F.type,G=F.charset,B=F.allowDup,C=e(E);if(typeof D!==m){D="text/javascript"}if(typeof G!==m){G=null}B=!(!B);if(!B&&(typeof b[C]!==d||o(C))){return}if(typeof s[C]===d){s[C]={done:k}}else{s[C].done=k}b[C]=n;q=n;(function(H){c(function(){var J=null;if(((J=f[H])===null)&&(typeof(J=g(H)[0])===d||J===null)){c(arguments.callee,25);return}var I=i.createElement("script");I.setAttribute("type",D);if(typeof G===m){I.setAttribute("charset",G)}I.onload=I.onreadystatechange=function(){u.call(I,s[C])};I.setAttribute("src",E);J.appendChild(I)},0)})(t)}function x(B){if(w){r.push(B)}else{B()}}z={script:function(){var B=arguments;x(function(){for(var C=0;C<B.length;C++){if(Object.prototype.toString.call(B[C])==="[object Array]"){arguments.callee.apply(null,B[C])}else{if(typeof B[C]==="object"){p(B[C])}else{if(typeof B[C]===m){p({src:B[C]})}}}}});return z},block:function(D){if(typeof D!=="function"){D=function(){}}var E=l(n,t),B=E.trigger,C=function(){try{D()}catch(F){}B()};delete E.trigger;x(function(){if(q&&!y){v=C}else{c(C,0)}});return E},toHEAD:function(){x(function(){t=j});return z},toBODY:function(){x(function(){t=h});return z}};if(w){z.trigger=function(){for(var B=0;B<r.length;B++){r[B]()}}}return z}a.eConduit.loader={script:function(){return l().script.apply(null,arguments)},block:function(){return l().block.apply(null,arguments)},toHEAD:function(){return l().toHEAD()},toBODY:function(){return l().toBODY()}}})(window);

eConduit.bootstrap();




/*======================================================================================================
  Utility methods for debugging, remove prior to final shipping version
  ======================================================================================================*/


function DumpObjectIndented(obj, indent)
{
    var result = "";
    if (indent == null) indent = "";

    for (var property in obj)
    {
	var value = obj[property];
	if (typeof value == 'string')
	    value = "'" + value + "'";
	else if (typeof value == 'object')
	{
	    if (value instanceof Array)
	    {
        // Just let JS convert the Array to a string!
		value = "[ " + value + " ]";
	    }
      else
	    {
        // Recursive dump
		// (replace "  " by "\t" or something else if you prefer)
		var od = DumpObjectIndented(value, indent + "  ");
		// If you like { on the same line as the key
				 //value = "{\n" + od + "\n" + indent + "}";
				 // If you prefer { and } to be aligned
				 value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
			       }
	    }
	    result += indent + "'" + property + "' : " + value + ",\n";
	}
	return result.replace(/,\n$/, "");
    }



