/*

STEPS
- passing all needded vars to the flash via flash vars
	- loading a working flash with two styles
	
- making below-the-fold flash appear in safari
- getting all styles to flash including link states (see javastyles.js)

- cleaning up code

*/




/* ------------------------------------------------------------------------------------------------------------------------- */

var aTags = new Array();					// Holds information on each Header Tag, Array is Global

function hsParseTags () {
	
	aTags['element']	= new Array();	// The Header Tag Object
	aTags['node']		= new Array();	// The Header Tag Node Name. Ex: "h1"
	aTags['width']		= new Array();	// The Width of the original Element
	aTags['height']		= new Array();	// The Height of the original Element
	aTags['innerHTML']	= new Array();	// The original contents of the current Element
	aTags['text']		= new Array(); // The original display text contained in the element
	aTags['swfText']	= new Array(); // Formatted text for sending to Flash
	aTags['isLink']		= new Array();	// Does the Header Tag contain an Anchor Tag
	aTags['href']		= new Array();	// Anchor Tag's href property value
	aTags['target']		= new Array();	// Anchor Tag's target property value
	aTags['title']		= new Array();	// Anchor Tag's title property value
	aTags['font']		= new Array(); // The original CSS font-family value (perhaps not needed)
	aTags['styles']		= new Array(); // An NVP Array of styles which Flash will parse
	aTags['noFlash']	= new Array();	// The content to display when Flash is not supported
	
	// Get Properties of all tags containing text to be replaced
	
	for ( var i = 1; i <= 6; i++ ) {
		
		/* =============== Header Tags (Assumes there may be more than one each of a particular tag - such as two <h1> tags) ================== */
		
			// Get array containing each Header Tags of the same type (depending on the current value of 'i')
			
			var myElems = document.getElementsByTagName('h'+i);
			
			// Loop thru each Header Tag where there are more than one of the same type - Multiple H1 Tags
			
			for ( var j = 0; j < myElems.length; j++ ) {
				
				e = myElems[j]; // The current Element
				
				// Test for Existence of Anchor tag and get its properties -----------------------------------
				
				var c = e.childNodes;
				// Loop Child Elements of each Header Tag
				for ( var k = 0; k < 1; k++ ) { // Child Element Length limited to 1 - Allows 'isLink' to be conditional
					if ( c[k].nodeName == "A" ) {
						aTags['text'].push( text = c[k].innerHTML); // Define Text for later parsing as 'swfText'
						aTags['isLink'].push( isLink = 1);
						
						// Explicitly define Anchor attributes so if one is not present, an empty string can be used.
						
						if ( c[k].attributes['href']) {
							aTags['href'].push( c[k].attributes['href'].value);
						} else {
							aTags['href'].push( "");
						}
						
						if ( c[k].attributes['target']) {
							aTags['target'].push( c[k].attributes['target'].value);
						} else {
							aTags['target'].push( "");
						}
						
						if ( c[k].attributes['title']) {
							aTags['title'].push( c[k].attributes['title'].value);
						} else {
							aTags['title'].push( "");
						}

					} else if ( c[k].nodeName == "#text" ) {
						// There is no Anchor, Do not overwrite 'innerHTML', 'isLink' = 0, Attributes = blank
						aTags['text'].push( text =  e.innerHTML);
						aTags['isLink'].push( isLink = 0);
						aTags['href'].push("");
						aTags['target'].push("");
						aTags['title'].push("");
					} // if Anchor
				} // for k
				
				
				// Get the remaining information for the current element
				
				aTags['element'].push( e);
				aTags['node'].push( node = e.nodeName.toLowerCase());
				aTags['width'].push( width = e.offsetWidth);
				aTags['height'].push( height = e.offsetHeight);
				aTags['innerHTML'].push( innerHTML = e.innerHTML);
				aTags['swfText'].push( escape( text));
				aTags['font'].push( $(node).css('fontFamily'));
				//aTags['styles'].push( "h=fontFamily:GillSansUltraBold;");
				aTags['styles'].push( getStyles( node, isLink));
				aTags['noFlash'].push( e.innerHTML);
				
				//window.alert(swfFont);
				
			} // for j
		} // for i
	
	/* =============== Tags Specified By ID ================== */
	
		// ---- Purge non-existant elements from the array ------------------------------------
		
			for ( var j = 0; j < aReplace.length; j++ ) {
				if ( $(aReplace[j]).html() == undefined ) {
					aReplace.splice( j, 1);
					j--;
				}
			}
			
		// ---- Get element info -------------------------------------------------------------

		for ( var j = 0; j < aReplace.length; j++ ) {
			
			e = $(aReplace[j]); // The current Element
			
			// Test for Existence of Anchor tag and get its properties -----------------------------------
			
				if ( e.find( 'a').html() == undefined) {
					// No Anchor
					aTags['text'].push( text = e.html());
					aTags['isLink'].push( isLink = 0);
					aTags['href'].push("");
					aTags['target'].push("");
					aTags['title'].push("");
				} else {
					// Anchor is present
					aTags['text'].push( text = e.find( 'a').html()); // Define Text for later parsing as 'swfText'
					aTags['isLink'].push( isLink = 1);
					aTags['href'].push( e.find( 'a').attr( 'href'));
					aTags['target'].push( e.find( 'a').attr( 'target'));
					aTags['title'].push( e.find( 'a').attr( 'title'));
				}
				
				// Get the remaining information for the current element
				
				aTags['element'].push( e);
				aTags['node'].push( node = document.getElementById(aReplace[j].replace('#','')).nodeName.toLowerCase());
				aTags['width'].push( e.width());
				aTags['height'].push( e.height());
				aTags['innerHTML'].push( innerHTML = e.html());
				aTags['swfText'].push( swfText = escape( text));
				aTags['font'].push( e.css('fontFamily'));
				aTags['styles'].push( getStyles(aReplace[j], isLink));
				aTags['noFlash'].push( noflash = e.html() );
		}
		
	// --- Do The replacements for each item in [element] array
	
	//$('p#output').append( '<br />'+aTags['element'].length);
	
	for ( var j = 0; j < aTags['element'].length; j++ ) {
		//$('p#output').append( '<br />Round:'+j);
		hsReplace ( aTags['element'][j], j);
		////$('p#output').append( '<b>'+j+'</b> '+aTags['node'][j]);
	}
	
} // hsParseTags()

function hsReplace(e, m)
{
	
	// Output all properties to browser for testing
	/*
	$("p").append( "<br /> <br />"+m+"<br />");
	$("p").append( "<br /> <b>node</b>:"+aTags['node'][m]);
	$("p").append( "<br /> <b>text</b>:"+aTags['text'][m]);
	$("p").append( "<br /> <b>swfText</b>:"+aTags['swfText'][m]);
	$("p").append( "<br /> <b>isLink</b>:"+aTags['isLink'][m]);
	$("p").append( "<br /> <b>href</b>:"+aTags['href'][m]);
	$("p").append( "<br /> <b>target</b>:"+aTags['target'][m]);
	$("p").append( "<br /> <b>title</b>:"+aTags['title'][m]);
	$("p").append( "<br /> <b>width</b>:"+aTags['width'][m]);
	$("p").append( "<br /> <b>height</b>:"+aTags['height'][m]);
	$("p").append( "<br /> <b>innerHTML</b>:"+aTags['innerHTML'][m]);
	$("p").append( "<br /> <b>font</b>:"+aTags['font'][m]);
	$("p").append( "<br /> <b>noFlash</b>:"+aTags['noFlash'][m]);
	*/
	
	// Make sure element exists to prevent breakage.
	/*
	if ( e.innerHTML == null ) {
		return false;
	}
	*/

	// Generate path to SWF Movie with NVP Variables
	
	data = 'hs_textreplacement_jquery_0_3_b/hr.swf?id='+m+'&tagname='+aTags['node'][m]+'&text='+aTags['swfText'][m]+'&islink='+aTags['isLink'][m]+'&href='+aTags['href'][m]+'&target='+aTags['target'][m]+'&'+aTags['styles'][m]+'&';
	
	////$('p#output').append( '<b>'+data+'</b>');
	
	// Generate the new HTML to insert into 'e'
	
	var html = '';
	
	//html += '<span>';
	html += '<object type="application/x-shockwave-flash" data="'+data+'" width="'+aTags['width'][m]+'" height="'+aTags['height'][m]+'"'+aTags['title'][m]+'>';
	html += '<param name="movie" value="'+data+'" />';
	html += '<param name="menu" value="false" />';
	html += '<param name="allowScriptAccess" value="always" />';
	html += '<param name="wmode" value="transparent" />';
	html += aTags['noFlash'][m];
	html += '</object>';
	//html += '</span>';
	
	if ( e.innerHTML == undefined) {
		e.html(html);
	} else {
		e.innerHTML = html;
	}
	
	// Veritical Align <object> to bottom as they do not align properly in <span>
	
	$('object').css({'vertical-align':'bottom'});
}

/* ==================== GETTING STYLES =============================================*/

function getStyles(e,l)
{
	/*	e: element
		l:isLink */
	
	if ( ! l ) {
		
		// No anchor, get global styles (font-family, font-weight, text-align, letter-spacing, color, text-decoration)
		var s = 'g=';
	
		s += globalStyle( $(e).css('font-family'), 'font');
		s += globalStyle( $(e).css('font-size'), 'font-size');
		s += globalStyle( $(e).css('font-weight'), 'font-weight');
		s += globalStyle( $(e).css('text-align'), 'text-align');
		s += globalStyle( $(e).css('letter-spacing'), 'letter-spacing');
		
		s += globalStyle( $(e).css('color'), 'color');
		s += globalStyle( $(e).css('text-decoration'), 'text-decoration', l);
		
		
		
	} else {
		/*	g: link state/global
			h: hover state
			a: active state */
			
		// link/global
		s = 'g=';
		s += globalStyle( $(e+' a').css('font-family'), 'font', l, $(e).css('font-family'));
		s += globalStyle( $(e+' a').css('font-size'), 'font-size');
		s += globalStyle( $(e+' a').css('font-weight'), 'font-weight');
		s += globalStyle( $(e+' a').css('text-align'), 'text-align');
		s += globalStyle( $(e+' a').css('letter-spacing'), 'letter-spacing');
		
		s += globalStyle( $(e+' a').css('color'), 'color');
		s += globalStyle( $(e+' a').css('text-decoration'), 'text-decoration', l);
		s += globalStyle( $(e+' a').css('background-color'), 'background-color');
		
		// hover
		s += '&h=';
		s += anchorStyle( $(e+' a').css('font-family'), 'color', 'hover');
		s += anchorStyle( $(e+' a').css('font-family'), 'text-decoration', 'hover');
		s += anchorStyle( $(e+' a').css('font-family'), 'background-color', 'hover');
		
		// active
		s += '&a=';
		s += anchorStyle( $(e+' a').css('font-family'), 'color', 'active');
		s += anchorStyle( $(e+' a').css('font-family'), 'text-decoration', 'active');
		s += anchorStyle( $(e+' a').css('font-family'), 'background-color', 'active');
	}
	
	s += getEffects(e, l);
	s += getConfig(e, l);
	
	//$('p#output').append('<br />'+s);
	return s;
}

function globalStyle(v,s,l,o) {
	/*	e: The value of the original style as defined in CSS
		s: The the intended way to format the style (font, font-weight, text-align, letter-spacing / color, text-decoration)
		l: Optional; For 'font' only; isLink
		o: Optional; For 'font' only; Value of CSS font-family which should be inherited from if no special font is otherwise defined.
	*/
	
	//var v = String(v);
	
	switch (s) {
		
		case 'font': // Return the first value that does not contain a colon (:)
			////$('p#output').append('<br /><b>font-family=('+v+')');
			v = v.replaceAll('"', "");
			v = v.replaceAll("'", "");
			v = v.replaceAll(" ", "");
			v = v.split(",")[0];
			v = v.split(']');
			var r = '';
			for ( var i = 0; i < v.length; i++ ) {
				////$('p#output').append('<br /><b>search=('+v[i]+','+v.length+')</b>'+v[i].search("font"));
				if ( v[i].search('font') != -1 ) {
					v = v[i].replaceAll('font[', '');
					r += i == 0 ? String(v).trim() : ','+String(v).trim();
					break;
				}
			}
			if ( r == '' ) {
				if ( l ) {
					return globalStyle(o,s);
				} else {
					r = 'Arial';
				}
			}
			v = r;
			break;
			
		case "font-size": // Only numbers or are allowed; Remove any unit extension; Default to '0'; Allow decimals '.';
			v = v.replaceAll(" ", "");
			v = v.toLowerCase();
			v = v.replace(/[^\d.]/g, "");
			if ( v.length == 0 ) {
				v = '12';
			}
			break;
			
		case "font-weight": // Returns the Boldness Number (-400 to 400) formatted for Flash.
		////$('p#output').append('<br /><b>fontWeight(In): </b>'+v);
			if ( Number(v) ) {
				if ( Number(v) == 400 ) {
					v = 0;
				} else {
					v = Number( v - 500);
				}
			} else {
				switch ( v ) {
					case "bold":
						v = 200;
						break;
					case "bolder":
						v = 400;
						break;
					case "lighter":
						v = -100;
						break;
					case "normal":
						v = 0;
						break;
					default:
						v = 0;
				}
			}
			v = String(v).toLowerCase();
			////$('p#output').append('<br /><b>fontWeight(Out): </b>'+v);
			break;
			
		case "text-align": // Allowed 'center', 'justify', 'left', 'right'; Default 'left';
			v = v.toLowerCase();
			if ( v == 'center' || v == 'justify' || v == 'left' || v == 'right' ) {
				break;
			} else {
				v = 'left';
			}
			break;
			
		case "letter-spacing": // Only numbers or 'normal' are allowed; Remove any unit extension; Default to 'normal'; Preserve negative numbers '-'; Allow decimals '.';
			v = v.replaceAll(" ", "");
			v = v.toLowerCase();
			var n = v.match(/-/) ? true : false; // Preserve negative values
			if ( v == 'normal' ) {
				v = '0';
				break;
			}
			v = v.replace(/[^\d.]/g, ""); //  IE PC: Decimal and subsequent numbers get removed.
			if ( v.length == 0 ) {
				v = '0';
			}
			v = n ? '-'+v : v;
			break;
			
		case "color": // Convert RBG to hex - and removing '#'
			if ( v == '' ) { v = '000000'; break; };
			v = toHex(v);
			break;
			
		case "text-decoration": // Only allow values 'underline' and 'none'; Lowercase; Default others to 'none'. Convert to flash syntax (true, false)
			v = v.toLowerCase();
			if ( v == 'underline' ) {
				v = 'true';
			} else if ( v == 'none') {
				v = 'false';
			} else if ( l ) {
				v = 'true';
			} else {
				v = 'false';
			}
			break;
			
		case "background-color": // Remove '#' where exists; Convert RGB to hex w/o '#' when occurs.
			////$('p#output').append('<br/> bgColor:'+v);
			if ( v == '' ) { v = 'transparent'; break; };
			if ( v.toLowerCase() == "transparent" ) {
				v = v.toLowerCase();
				break;
			}
			v = toHex(v);
			break;
			
	} // switch
	
	////$('p#output').append( '<br />'+s+':'+v);
	return s.toCamelCase('-') + ':' + v + ';';

}

function anchorStyle(v,s,t,n) {
	/*	v: The value of font-family
		s: The style to return (color, text-decoration, background-color)
		t: The state which the style belongs to (link, hover, active)
		n: The style inheritance where no value exists
	*/
	
	var v = String(v);
	
	// Find the correct anchor style segment matching 't'
	
		v = v.replaceAll('"', "");
		v = v.replaceAll("'", "");
		v = v.replaceAll(" ", "");
		v = v.split("]");
		for ( var i = 0; i < v.length; i++ ) {
			if ( v[i].match( t) ) {
				v = v[i].replace( t+'[', '');
				v = v.replace( ']', '');
				v = v.trim();
				break;
			}
		}
		if ( typeof v != 'string') {
			v = '';
		}
		
	// Find the correct anchor style segment value matching 's'
	
		if ( v != '') {
			////$('p#output').append('<br /><b>matching</b>::'+v);
			v = v.split(";");
			for ( var i = 0; i < v.length; i++ ) {
				////$('p#output').append('<br /><b>split</b>::'+v[i]);
				if ( v[i].match(s)) {
					////$('p#output').append('<br /><b>match</b>::'+s+':'+v[i]);
					v = v[i].split(':');
					v = v[1].replace(';', '');
					v = v.trim();
					break;
				} else {
					////$('p#output').append('<br /><b>NOmatch</b>::'+s+':'+v[i]);
				}
			}
			if ( typeof v != 'string') {
				v = '';
			}
		}
		
		v = String(v);
	
	switch (s) {
		case "color": // Convert RGB to hex - and removing '#'
			if ( v == '' ) { v = '000000'; break; };
			////$('p#output').append('<br><b>Color: '+v+'</b>')
			v = toHex(v);
			break
			
		case "text-decoration": // Only allow values 'underline' and 'none'; Lowercase; Default others to 'none'. Convert to flash syntax (true, false)
			v = v.toLowerCase();
			if ( v == 'underline' ) {
				v = 'true';
			} else {
				v = 'false';
			}
			break;
			
		case "background-color": // Remove '#' where exists; Convert RGB to hex w/o '#' when occurs.
			if ( v == '' ) { v = 'transparent'; break;};
			if ( v.toLowerCase() == "transparent" ) {
				v = v.toLowerCase();
				break;
			}
			v = toHex(v);
			break;
	}
	
	////$('p#output').append( '<br />'+t+'::'+s+':'+v);
	return s.toCamelCase('-') + ':' + v + ';';
}

function getEffects(e,a){
	var v = a ? $(e+' a').css('font-family') : $(e).css('font-family');
	//$('p#output').append('<br /><b>Effect v: </b>'+v);
	// Find the correct anchor style segment matching 'effects'
	v = v.replaceAll('"', "");
	v = v.replaceAll("'", "");
	v = v.replaceAll(" ", "");
	v = v.split("]");
	for ( var i = 0; i < v.length; i++ ) {
		if ( v[i].match( 'effects') ) {
			v = String(v[i]).replace( 'effects[', '');
			//v = v.replace(']', '');
			v = v.replaceAll('true', '1');
			v = v.replaceAll('false', '0');
			v = v.trim();
			//$('p#output').append('<br /><b>Effects: </b>'+v);
			return '&e=' + v;
		}
	}
	if( a ) { return getEffects(e,false);};
	return '';
}

function getConfig(e,a){
	var v = a ? $(e+' a').css('font-family') : $(e).css('font-family');
	// Find the correct anchor style segment matching 'config'
	v = v.replaceAll('"', "");
	v = v.replaceAll("'", "");
	v = v.replaceAll(" ", "");
	v = v.split("]");
	for ( var i = 0; i < v.length; i++ ) {
		if ( v[i].match( 'config') ) {
			v = v[i].replace( 'config[', '');
			//v = v.replace(']', '');
			v = v.replaceAll('true', '1');
			v = v.replaceAll('false', '0');
			v = v.trim();
			//$('p#output').append('<br /><b>Config: </b>'+v);
			return '&c=' + v;
		}
	}
	if( a ) { return getConfig(e,false);};
	return '';
}

function isLink (e)
{
	
	// Determine if an Anchor element is present within elem
	
	if ( $(e).find("a").attr("href") != undefined ) {
		
		return true;
		
	} else {
		
		return false;
		
	}
	
}

function getAnchorHREF (e)
{
	if ( isLink(e) ) {
		
		return $(e).find("a").attr("href");
		
	} else {
		
		return false;
		
	}
	
}

function getAnchorTarget (e)
{

	if ( $(e).find("a").attr("target") != undefined ) {
		return $(e).find("a").attr("target");
	} else {
		return '_self';
	}
	
}

function getAnchorTitle (e)
{

	if ( $(e).find("a").attr("title") != undefined ) {
		return ' title="'+$(e).find("a").attr("title")+'"';
	} else {
		return '';
	}
	
}

function getLinkState(e, state)
{
	// :hover, :active
}

function getText (e)
{
	
	if ( isLink(e) ) {
		return $(e).find("a").html();
	} else {
		return $(e).html();
	}
}

function getSWFFont (e)
{
	// Get CSS font-family value
	
	var f = $(e).css("fontFamily");
	
	// Format font string for parsing
	
	f = f.replaceAll('"', "");
	f = f.replaceAll("'", "");
	f = f.replaceAll(", ", ",");
	f = f.replaceAll(" ", "");
	f = f.split(",");
	
	// Parse string to get first font listed or default to Arial
	
	if ( f[0] ) {
		return f[0].trim();
	} else {
		return 'Arial';
	}
}

function getColor (e)
{
	return toHex( $(e).css("color"));
	
}

/*-----------------------------------------------------------
toHex(n)
	n - String which could be an rgb or hex format
Returns a string in hex format with 6 characters.
-----------------------------------------------------------*/
function toHex ( n ) {
	n = String(n).replaceAll("#", "");
	if ( n.length == 6 ) {
		return n.toUpperCase();
	}
	if ( n.length == 3 ) {
		n = n.split('');
		n = String(n[0]+n[0]+n[1]+n[1]+n[2]+n[2]);
		////$('p#output').append('<br /><b>Color Out: </b>'+n.toUpperCase());
		return n.toUpperCase();
	}
	n = n.replaceAll(" ", "");
	n = n.replaceAll("(", "");
	n = n.replaceAll(")", "");
	n = n.replaceAll("rgb", "");
	n = n.replaceAll("RGB", "");
	n = n.split(",");
	var p = "0123456789ABCDEF";
	var r = "";
	for ( i in n ) {
		r += p.charAt((n[i]-n[i]%16)/16) + p.charAt(n[i]%16);
	}
	return r;
}

/*---------------------------------------------------------
Removes spaces from beginning and end of string
---------------------------------------------------------*/
String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
/*---------------------------------------------------------
Replaces all occurances of a substring
---------------------------------------------------------*/
String.prototype.replaceAll = function(pcFrom, pcTo){
	var i = this.indexOf(pcFrom);
	var c = this;
	
	while (i > -1){
		c = c.replace(pcFrom, pcTo); 
		i = c.indexOf(pcFrom);
	}
	return c;
}
/*---------------------------------------------------------
Converts a string to camelCase format by removing a delimeter
---------------------------------------------------------*/
String.prototype.toCamelCase = function (s) {
	var str = this.trim();
	var a = str.split(s);
	str = a[0];
	for ( var i = 1; i < a.length; i++ ) {
		a[i] = a[i].substr(0, 1).toUpperCase() + a[i].substr(1);
		str += a[i];
	}
	return str;
}
