﻿//iframe communicator

function ifc() {
	//writes the iframes that we will use for communications
	var this_url = window.location.href;
	var protocol = (this_url.indexOf("https") > -1) ? "https://" : "http://";
	var this_domain = window.location.host;
	
	var i, id;
	for (i = 0; i <= this.max_threads; i++) {
		id = "_" + i + this.ifc_id; //ensure we don't lead with a number and the numeric id is in position 2
		document.write("<iframe id=\"" + id +
			"\" name=\"" + id +
			"\" src=\"" + protocol + this_domain + "/javascript_includes/_aj/blank.htm\" style=\"visibility:hidden;display:none;\" " +
			"onload=\"IFC.executeComplete(this)\">" +
			"</iframe>");
	}
}

ifc.prototype.ifc_id = "__ifc_iframe_id";
ifc.prototype.max_threads = 8;
ifc.prototype.active_threads = ".";
ifc.prototype.thread = new Array();
ifc.prototype.seprator = "#xx#";
ifc.prototype.queue = "";
ifc.prototype.intervalId = 0;
ifc.prototype.syncProcessRunning = false;

ifc.prototype.sync = function(s, callback) {
	this.init_threads();

	//add the request to the queue
	var entry = s + this.seprator + callback + "\n";
	this.queue = this.queue + entry;

	//if the process isn't running the start it
	if (this.syncProcessRunning == false) {
		this.syncProcessor();
	}
}

ifc.prototype.syncProcessor = function() {
	this.queue = this.ltrim(this.queue);
	if (this.queue == "" || this.syncProcessRunning) return;
	this.syncProcessRunning = true;

	//get the url and callback function from the queue
	var arr = this.queue.split("\n");
	var parts = arr[0].split(this.seprator);
	var s = parts[0];
	var callback = parts[1];

	//remove the entry that we are sending
	arr[0] = "";
	this.queue = arr.join("\n");

	//call the iframe
	this.callIframe(this.thread[0], s, callback);
}

ifc.prototype.async = function(s, callback) {
	this.init_threads();
	var ifc_iframe = this.findFreeThread();

	this.callIframe(ifc_iframe, s, callback);

	return void (0);
}


ifc.prototype.init_threads = function() {
	if (this.thread[0] == null) { //check to see if iframes have been loaded in the threads array
		var i, id, iframeObj;
		for (i = 0; i < this.max_threads; i++) {
			id = "_" + i + this.ifc_id; //because we don't lead with a number and the numeric id is in position 2
			iframeObj = document.getElementById(id);
			iframeObj.getContent = function() {
				//the use of 'this' here will be the iFrame when it is called from the callback function
				var body;
				if (this.contentDocument) {
					body = this.contentDocument.documentElement.getElementsByTagName("body")[0];
				} else {
					//IE 7
					body = this.contentWindow.document.documentElement.getElementsByTagName("body")[0];
				}

				return body.innerHTML;

			};
			this.thread[i] = iframeObj;
		}
	}
}

ifc.prototype.findFreeThread = function() {
	var i, id;
	for (i = 1; i < this.max_threads; i++) {//always save thread 0 for syncronous 
		id = this.thread[i].id;

		if (this.active_threads.indexOf(id) == -1) {
			this.active_threads += id;
			return this.thread[i];
		}
	}
}


ifc.prototype.callIframe = function(ifc_iframe, s, callback) {
	s = s + ((s.indexOf("?") > -1) ? "&" : "?") + "_cb=" + Date().toString().replace(/ /gi, ""); //add a cache buster
	if (callback != null && callback != "" && callback != "undefined") {//add the call back function if it exists
		ifc_iframe._callback = function(t) { eval(callback + "(t);"); };
	}
	ifc_iframe.src = s;
}

ifc.prototype.executeComplete = function(t) {
	var src = t.src;
	if (src == "about:blank") return;

	//check for a call back and run
	if (t._callback) {
		t._callback(t);
		t._callback = null;
	}

	var id = t.id;
	var threadId = id.substr(1, 1);

	if (threadId == "0") {
		//special handler for sync processor
		this.syncProcessRunning = false;
		this.syncProcessor();
	} else {
		//remove from async active thread list
		var match = new RegExp(id, 'gi');
		this.active_threads = this.active_threads.replace(match, "");
	}
}

ifc.prototype.ltrim = function(str) {
	if (!str) return str;
	var chars = "\\s";
	str = str.replace(new RegExp("^[" + chars + "]+", "g"), ""); //trims left
	return str;
}





var IFC = new ifc;


