var fbg = new function()
{
	//private vars
	var self = this;
	var test_frequency = 20;		//how often (in ms) to check if test node has been styled with last custom font in list
	var giveup = 3000;				//number of ms before it stops checking (i.e., custom font style was not applied)
	var latency = 100;				//delay between test node being detected as styled and hidden nodes being exposed  

	//public vars
	this.rfu = null;				//user settings

	//private method declarations
	var init = null;
	var onWinLoad = null;

	//public method declarations
	this.hideFOUT = null;
	this.isFontFaceSupported = null;
	
	//public events (callbacks) -- to be defined by client code
	
	this.onFontFaceFailed = null;
	
	/****************************************************************************/

	//private method definitions:

	init = function()
	{
		//rfu
	};
	
	onWinLoad = function(callback)
	{
		if (window.addEventListener) addEventListener('load',callback,false);
		else attachEvent('onload',callback);
	};
	
	/****************************************************************************/

	//public method definitions:
		

	this.hideFOUT = function(when, delay)
	{
		//inventories custom fonts used on a page and selectively hides only DOM elements that would cause flash-of-unstyled-text
		//args:  when -- 'asap'|'domready'|'onload'	-- when hidden content will revert to visible (optimum varies by page and browser)
		
		if (navigator.appName != 'Microsoft Internet Explorer' && !/Firefox\/3/.test(navigator.userAgent))
			return;									//browser-specific test because IE and Firefox 3.x are those w/ FOUT problem
		
		delay = delay || latency;
		
		var fontnams = [];
		var fontruls = [];
		var selectrs = [];
		var iscompliant = true;
					
		//inventory all custom fonts declared through @font-face rules and make list of all non-in-line css style rules in page:
		for (var i = 0; i < document.styleSheets.length; i++)
		{
			var stylsheet = document.styleSheets[i];
			
			if (!stylsheet.cssRules) 
			{											//find @font-face rules "manually" for IE8, IE7, etc.
				iscompliant = false;
				var rls = stylsheet.cssText;
				rls.replace(/@font-face\s*\{([^\}]+)\}/ig, function(r, t){
					var fontnam = r.replace(/([\s\S]*)(font-family:\s*['"]?)([-_0-9a-zA-Z]+)([\s\S]*)/, "$3");
					fontnams.push(fontnam);
					return r;
				});
			}		
				
			var ffrules = stylsheet.cssRules || stylsheet.rules;
			
			for (var j = 0; j < ffrules.length; j++)
			{
				var rul = ffrules[j];
					
				if (iscompliant && rul instanceof CSSFontFaceRule)
				{
					var fontnam = rul.cssText.replace(/([\s\S]*)(font-family:\s*['"]?)([-_0-9a-zA-Z]+)([\s\S]*)/, "$3");
					fontnams.push(fontnam);
				}
				else  fontruls.push(rul);				//CSSStyleRule
			}
			
			//alert(fontnams);
			//alert(fontruls.length);
		}
		
		//make list of all style rules that use a custom font
		for (var i = 0; i < fontnams.length; i++)
		{
			for (var j = 0; j < fontruls.length; j++)
			{
				var csstxt = iscompliant ? fontruls[j].cssText : fontruls[j].style.cssText;
				if (csstxt.indexOf(fontnams[i]) != -1)
				{
					selectrs.push(fontruls[j].selectorText);
				}
			}
		}

	
		//create a span node to be used for measuring default-font-styled vs custom-font-styled
		//Note:  the span technique is modeled after code developed by Paul Irish (http://paulirish.com/2009/font-face-feature-detection)
		var body = document.body || document.documentElement;  //.appendChild(document.createElement('testhost'));
		var spn = document.createElement('span');
		spn.setAttribute('style','font:99px _,serif;position:absolute;visibility:hidden');
		spn.innerHTML = 'Hello World';
		spn.id = 'fonttest';
		body.appendChild(spn);
		
		//var wid = spn.offsetWidth;		//moved further down; even though innerHTML was already set above, this is too early for IE
		
		//create a new stylesheet to store new classes with visibility:hidden for all nodes with custom fonts 
		var stl1 = document.createElement('style');
		document.getElementsByTagName("head")[0].appendChild(stl1);
		var allhidden = '';
		for (var i = 0; i < selectrs.length; i++)
			allhidden += (selectrs[i] + (i < (selectrs.length - 1) ? ', ' : ' '));
		allhidden += '{visibility:hidden}';
		if (stl1.styleSheet) stl1.styleSheet.cssText = allhidden;						//IE8, IE7
		else stl1.textContent = allhidden;												//e.g., "h1,div.test{visibility:hidden}";
	
		spn.style.font = '99px "' + fontnams[fontnams.length-1] + '",_,serif';			//apply custom font to test node, e.g., 'URWGroteskT_LigNar'
	
		var wid = spn.offsetWidth;			//at this time, tests in newer browsers (not IE7/IE8) show this as still the width of the original default-font
		
		//alert('before: ' + spn.offsetWidth);											//test:  shows width for default font
		//setTimeout(function(){alert('after: ' + spn.offsetWidth);}, 1000);			//test:  shows width for custom font		
		
		var temp1 = '';
		var freq = test_frequency;
		
		var showHidden = function()
		{
			var fnttest = setInterval(function()
			{			
				if (!wid && document.body)												//for the benefit of IE7 and IE8
				{
					body.removeChild(spn);
					document.body.appendChild(spn);
					wid = spn.offsetWidth;
				}
				var nu_wid = spn.offsetWidth;
				temp1 += (nu_wid + '   ');												//temp1 is used for dev only
				giveup -= freq;
				if (wid != nu_wid || giveup <= 0)
				{	
					clearInterval(fnttest);
					setTimeout(function(){stl1.parentNode.removeChild(stl1);}, delay);	//even 'asap' needs a small delay
					if (giveup <= 0 && self.onFontFaceFailed) self.onFontFaceFailed();
					spn.parentNode.removeChild(spn);
				} 
			}, freq);
		}

		//decide when to start testing if custom font has been applied
		if (when == 'asap')	showHidden();
		//else if (when == 'domready') head.ready("dom", showHidden);		//'domready' requires head.js (temporarily not supported)
		else if (when == 'onload') onWinLoad(showHidden);
		else showHidden();													//default is same as ('asap',100)

		
		if (window.TESTCAPTURE)												//dev testing only (optional)
		{
			onWinLoad(function()
			{
				document.getElementById('hf_monitor_div').innerHTML = temp1;
				setTimeout(function(){ document.getElementById('hf_monitor_div').innerHTML += '<br>Final: ' + spn.offsetWidth; }, 1000);				
			});
		}
				
	};
	
	this.isFontFaceSupported = function()
	{
		//The code in this method was written by Diego Perini
		var 
		sheet, doc = document,
		head = doc.head || doc.getElementsByTagName('head')[0] || docElement,
		style = doc.createElement("style"),
		impl = doc.implementation || { hasFeature: function() { return false; } };
		 
		style.type = 'text/css';
		head.insertBefore(style, head.firstChild);
		sheet = style.sheet || style.styleSheet;
		 
		var supportAtRule = impl.hasFeature('CSS2', '') ?
		        function(rule) {
		            if (!(sheet && rule)) return false;
		            var result = false;
		            try {
		                sheet.insertRule(rule, 0);
		                result = !(/unknown/i).test(sheet.cssRules[0].cssText);
		                sheet.deleteRule(sheet.cssRules.length - 1);
		            } catch(e) { }
		            return result;
		        } :
		        function(rule) {
		            if (!(sheet && rule)) return false;
		            sheet.cssText = rule;
		 
		            return sheet.cssText.length !== 0 && !(/unknown/i).test(sheet.cssText) &&
		              sheet.cssText
		                    .replace(/\r+|\n+/g, '')
		                    .indexOf(rule.split(' ')[0]) === 0;
		        };
		 
		return supportAtRule('@font-face { font-family: "font"; src: "font.ttf"; }');		
	};


	/****************************************************************************/

	init();		//startup stuff

}();


