/* 
 * sIFR Fallback for CSS @font-face
 *  by Weston Ruter, Shepherd Interactive <http://www.shepherd-interactive.com/>
 *
 * Requires sIFR 3
 * sIFR.webFonts must be populated with an object whose keys are font names (which
 * correspond to the same names used in the @font-face declarations) and whose member
 * properties are also objects with a src property whose value is the path to the
 * sIFR SWF. For example:
 * 
 *  sIFR.webFonts = {
 *      "A Charming Font Expanded" : {
 *          src:'./A-Charming-Font-Expanded.swf'
 *      }
 *  };
 *
 * Additionally, the property sIFR.webFontsClassName must be populated with the
 * class name that will tell sIFR which elements should be examined to see if
 * sIFR should be applied, as in:
 *  
 *  sIFR.webFontsClassName = "web-font";
 *
 * LICENSE:
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * $Id: sifr-config.js 12 2008-05-28 20:43:37Z westonruter $
 * Copyright 2008, Shepherd Interactive. All rights reserved.
 * 
 */


(function(){
if(typeof sIFR == 'undefined')
	throw Error("sIFR not already included");
if(typeof sIFR.webFonts == 'undefined')
	throw Error("sIFR.webFonts not populated with font names and locations to the sIFR SWF files.");
if(!sIFR.webFontsClassName)
	throw Error("sIFR.webFontsClassName not populated with class name for elements with custom web fonts.");


function init(){
	var sel = '.' + sIFR.webFontsClassName;
	if(window.Prototype){
		$$(sel).each(function(el){
			applySIFR(el);
		});
	}
	else if(window.jQuery){
		$(sel).each(function(){
			applySIFR(this);
		});
	}
	else if(document.getElementsByClassName){
		var els = document.getElementsByClassName(sIFR.webFontsClassName);
		for(var i = 0; i < els.length; i++)
			applySIFR(els[i]);
	}
	else {
		var hasClassName = new RegExp('\\b' + sIFR.webFontsClassName + '\\b');
		var els = document.getElementsByTagName('*');
		for(var i = 0; i < els.length; i++){
			if(hasClassName.test(els[i].className))
				applySIFR(els[i]);
		}
	}
}

function toColorPart(number){
	var hex = parseInt(number).toString(16);
	if(hex.length == 1)
		return '0' + hex;
	return hex;
}

function getStyle(node, prop){
	if(window.Prototype)
		return $(node).getStyle(prop);
	else if(window.jQuery)
		return $(node).css(prop);
	//What currently follows is considered bad, but MSIE won't be using it so it's ok (http://erik.eae.net/archives/2007/07/27/18.54.15/)
	else if(document.defaultView && document.defaultView.getComputedStyle)
		return document.defaultView.getComputedStyle(node, null)[prop];
	else if(node.currentStyle)
		return node.currentStyle[prop];
	else
		return node.style[prop];
	return null;
}


function applySIFR(el){
	var options = {
		css:{'.sIFR-root': {}},
		transparent:true,
		elements:[el]
	};
	
	//Determine the desired font
	var fontFamily = getStyle(el, 'fontFamily');
	var matches = fontFamily.match(/(["'])?(.+?)\1?\s*(,|$)/);
	//Skip if sIFR fallback mechanism doesn't exist for this font
	if(!matches || !sIFR.webFonts[matches[2]])
		return;
	fontFamily = matches[2];
	
	//This function is called immediately if the lack of font support is predetermined;
	//   otherwise, this is called after page-load if no font support is determined 
	var fallback = function(){
		//Pass the computed style to sIFR
		var color = getStyle(el, 'color');
		if(color){
			var _matches = color.match(/(\d+)\D+?(\d+)\D+?(\d+)/);
			if(_matches)
				options.css['.sIFR-root'].color = '#' + toColorPart(_matches[1]) + toColorPart(_matches[2]) + toColorPart(_matches[3]);
			else
				options.css['.sIFR-root'].color = color;
		}
		
		options.css['.sIFR-root']['text-transform'] = getStyle(el, 'textTransform');
		
		//NOTE: When text size is changed (e.g. with page zoom), the flash needs to be refreshed
		options.css['.sIFR-root']['font-size'] = getStyle(el, 'fontSize');
		
		options.css['.sIFR-root']['font-style'] = getStyle(el, 'fontStyle');
		var weight = getStyle(el, 'fontWeight');
		if(weight == 'bold')
			weight = 700;
		else if(weight == 'normal')
			weight = 400;
		options.css['.sIFR-root']['font-weight'] = weight < 500 ? 'normal' : 'bold';
		
		//Display desired Web Font using sIFR
		sIFR.replace(sIFR.webFonts[fontFamily], options);
	};
	
	var isSupported = isWebFontSupported(fontFamily, true);
	//If there is no history of whether this font is supported (i.e. this page has not yet been loaded before, so wait to do check until after onload)
	if(isSupported === undefined){
		var loadHandler = function(){
			if(!isWebFontSupported(fontFamily)){
				fallback();
			}
		};
		if(window.addEventListener)
			window.addEventListener('load', loadHandler, false);
		else if(attachEvent)
			window.attachEvent('onload', loadHandler);
	}
	//Lack of font support has already been determined, so do fallback
	else if(!isSupported){
		fallback();
	}
	
}


for(var fontName in sIFR.webFonts){
	sIFR.activate(sIFR.webFonts[fontName]);
}
//$H(sIFR.webFonts).values().each(function(font){
//	sIFR.activate(font);
//});


if(window.Prototype && document.observe)
	document.observe('dom:loaded', init);
else if(window.jQuery)
	$(document).ready(init);
else if(document.addEventListener){
	document.addEventListener('DOMContentLoaded', init, false);
	window.addEventListener('load', init, false);
}
else if(window.attachEvent){
	window.attachEvent('onload', init);
}

function serialize(obj){
	var pairs = [];
	for(var key in obj){
		pairs.push(key + '-' + (obj[key]?1:0));
	}
	return pairs.join('|');
}
function deserialize(str){
	var obj = {};
	var pairs = str.split('|');
	for(var i = 0; i < pairs.length; i++){
		var pair = pairs[i].split('-');
		obj[pair[0]] = !!parseInt(pair[1]);
	}
	return obj;
}


function isWebFontSupported(fontName, isBeforeOnLoad){
	//If the browser's font support has already been determined
	if(isBeforeOnLoad){
		return isWebFontSupported.history[fontName];
	}
	
	//Take two sets of measurments on text with a monospace font and with the requested font with the monospace as a fallback;
	//  if the two sets of measurements are the same (i.e. if monospace was used for both), then the font is not supported.
	//  The following must be called after page load, not DOM load, since Web Fonts loaded via CSS must complete
	//  Font detection technique inspired by Lalit Patel <http://ajaxian.com/archives/javascriptcss-font-detector>
	var body = (document.body || document.getElementsByTagName('body')[0]);
	var el = document.createElement('span');
	el.style.fontFamily = 'monospace';
	el.style.fontSize = "10px";
	el.style.lineHeight = "1em";
	el.innerHTML = "Ii";
	body.appendChild(el);
	
	var x1 = el.offsetWidth;
	var y1 = el.offsetHeight;
	
	el.style.fontFamily = '"' + fontName + '",monospace';
	var x2 = el.offsetWidth;
	var y2 = el.offsetHeight;
	
	el.parentNode.removeChild(el);
	
	//Determine and store if font is supported
	isWebFontSupported.history[fontName] = !(x1 == x2 && y1 == y2);
	
	//Update the history of font support
	document.cookie = "fonts=" + encodeURIComponent(serialize(isWebFontSupported.history)) + "&path=/";
	
	return isWebFontSupported.history[fontName];
}

//Load stored table of what fonts are supported
isWebFontSupported.history = {};
var _cookieMatch = document.cookie.match(/\bfonts=(.+?)(?=&|;|$)/);
if(_cookieMatch)
	isWebFontSupported.history = deserialize(decodeURIComponent(_cookieMatch[1]));

})();
