function getElementsByClassName(classname,node){
	var a=[];
	if(node.getElementsByClassName){ //use HTML5 selector if available
		a = Array.prototype.slice.call(node.getElementsByClassName(classname)); //dump the HTMLCollection into an Array so the returned object is consistent
	}else{ // ...or do it the long way
		var re=new RegExp('(^| )'+classname+'( |$)');
		var els=node.getElementsByTagName("*");
		for(var i=0,j=els.length;i<j;i++)if(re.test(els[i].className))a.push(els[i]);
	}
	return a;
}

function zTglc(obj,c){
	if(obj.className) {
		if(obj.className==c) {
			obj.className='';
		} else {
			if(obj.className.match(' '+c)) {
				obj.className=obj.className.replace(' '+c,'');
			} else {
				obj.className=obj.className+' '+c;
			}
		}
	} else {
		obj.className=c;
	}
}

function zCi(){
	if (!("placeholder" in document.createElement("input"))) { //skip all this crap if the browser natively supports the 'placeholder' attribute
		var input=document.body.getElementsByTagName("input");
		for(var i=0;i<input.length;i++){
			if(input[i].type=='text'){
				if(!input[i].getAttribute('placeholder')) continue;
				input[i].value=input[i].getAttribute('placeholder');
				input[i].onfocus=function(){
					if(this.value==this.getAttribute('placeholder')){this.value='';}
				}
				input[i].onblur=function(){
					if(this.value==''){
						this.value=this.getAttribute('placeholder');
					}
				}
			}
		}
	}
}

/*
Documentation for form attributes are at http://trac.ops.about.com/index.cgi/infoarch/wiki/Form%20Validation
*/
var validationFunctions=new Object();
	validationFunctions["required"]=isReq;
	validationFunctions["pattern"]=isPat;
	validationFunctions["numeric"]=isNum;
	validationFunctions["email"]=isEmail;
	validationFunctions["match"]=isMatch;
	validationFunctions["minmax"]=isMinMax;
	
var errorMessages=new Object();
	errorMessages["required"]="This field is required.";
	errorMessages["pattern"]="This field is required.";
	errorMessages["numeric"]="Please enter only numbers into this field.";
	errorMessages["email"]="Please enter a valid email address.";
	errorMessages["match"]="This field must match its counterpart.";
	errorMessages["minmax"]="Please answer within the specified range of characters.";

function isReq(formField){
	switch(formField.type){
		case'file':
		case'hidden':
		case'text':
		case'textarea':
		case'select-one':
			if(formField.value) return true;
			return false;
		case'radio':
			var radios=formField.form[formField.name];
			for(var i=0;i<radios.length;i++){if(radios[i].checked)return true;}
			return false;
		case'checkbox':
			return formField.checked;
	}
}

function isPat(formField,pattern){
	var pattern=pattern||formField.getAttribute('pattern');
	var regExp=new RegExp("^"+pattern+"$","");
	var correct=regExp.test(formField.value);
	if(!correct&&formField.getAttribute('patternDesc'))correct=formField.getAttribute('patternDesc');
	return correct;
}

function isNum(formField){return isPat(formField,"\\d+");}

function isEmail(formField){return isPat(formField,"[\\d\\w._%+-]+@[\\d\\w.-]+\\.[\\w]{2,4}");}

function isMatch(formField){
	var twin = formField.getAttribute("twin");	
	var p = formField.parentNode;
	while(p.nodeName!='FORM'){
		var p = p.parentNode;
	}
	var x = p.elements;
	for(var i=0;i<x.length;i++){
		if(x[i].name==twin){
			if(x[i].value==formField.value){
				return true;
			} else {
				return false;
			}
			break;
		}
	}
}

function isMinMax(formField){
	var range = formField.getAttribute("range");
	range = range.split(",");
	errorMessages["minmax"]="Your entry must be between "+range[0]+" and "+range[1]+" characters.";
	return isPat(formField,"(.|\n|\r|\t){"+range[0]+","+range[1]+"}");
}

function createCounter(elem){
	var range = elem.getAttribute("range");
	range = range.split(",");
	var y = document.createTextNode(range[1]+'-character limit');
	var max = document.createElement('p');
	max.id = elem.id+"_max";
	max.className = "maxinfo alert";
	max.appendChild(y);
	elem.parentNode.insertBefore(max,elem.nextSibling);
	if(range[0]>1){
		var x = document.createTextNode(range[0]+'-character minimum');
		var min = document.createElement('p');
		min.id = elem.id+"_min";
		min.className = "mininfo alert";
		min.appendChild(x);
		elem.parentNode.insertBefore(min,elem.nextSibling);
	}
	
	elem.onkeypress = elem.onchange = function(){
		var range = this.getAttribute("range");
		range = range.split(",");
		if(this.value.length<range[1]){
			gEI(elem.id+"_max").innerHTML=(range[1]-this.value.length)+" characters left";
		}else{
			gEI(elem.id+"_max").innerHTML="You have reached the character limit";
			this.value=this.value.substring(0,range[1]);
		}
	};
	elem.removeAttribute('counter');
}

var W3CDOM=document.createElement&&document.getElementsByTagName;

function validateForms(){
	if(!W3CDOM) return;
	var forms=document.forms;
	for(var i=0;i<forms.length;i++){
		//add counters where necessary
		var els=forms[i].elements;
		for(var j=0;j<els.length;j++){
			if(els[j].getAttribute('counter')){
				createCounter(els[j]);
			}
		}
		if(!forms[i].onsubmit) forms[i].onsubmit = function(){return validate(this)};
	}
}

function validate(form){
	var t = form || this;
	var els=t.elements;
	var validForm=true;
	for(var i=0;i<els.length;i++){
		els[i].className=els[i].className.replace(/invalid/,'');
		var req=els[i].getAttribute('validate');
		if(!req || els[i].getAttribute('disabled')) continue;
		var OK=validationFunctions[req](els[i]);
		if(OK!=true){
			if(els[i].type == 'radio'){
				obj = els[i].parentNode;
				do {
					if (obj.nodeName == 'FIELDSET') {
						break;
					}
				} while (obj = obj.parentNode);
				obj.className+=' invalid';
			} else {
				els[i].className+=' invalid';
			}
			validForm=false;
			message=(els[i].getAttribute('alert'))?els[i].getAttribute('alert'):errorMessages[req];
			els[i].focus();
			break;
		}
	}
	if(!validForm){alert(message);}
	return validForm;
}

/* The concept behind the modal is that any links with a target of "modal" will have the linked URL open in an iFrame that is presented as a 'pop-over' unit. Unsupported browsers will just open the pop-up window. */

function check_modal(){ 
	var a = document.getElementsByTagName('a');
	for(var i=0;i < a.length;i++) {
		if(a[i].getAttribute('target') == "modal"){
			create_modal(a[i]);
		}
	}
	return;
}

function create_modal(a){ 
	a.setAttribute('data-url',a.getAttribute('href')); //replace href of modal links (this is to get around an About.com-specific bug in IE where "return false" doesn't stop a link from executing. (Has something to do with click-tracking code.)
	a.setAttribute('href','javascript:void(0)'); 
	a.setAttribute('target','');
	isIE6 = /msie|MSIE 6/.test(navigator.userAgent);
	if(a.getAttribute('data-type') == "pop" || isIE6) {
		a.onclick = function(){
			zpu(0,this.getAttribute('data-url'),404,300,"modal");
		}
	} else {
		a.onclick = function(){
			return prep_modal(this.getAttribute('data-url'),this.getAttribute('data-modclass'),this.getAttribute('data-overlayclass'),this.getAttribute('data-type'),this.getAttribute('data-uclick'));
		}
	}
}

function createOverlay(className){ //create a div that takes up the whole viewport... see stylesheet for specific styling
	var o=document.createElement('div');
	o.id='oL';
	if(className) o.className=className;
	o.style.height=window.document.body.scrollHeight+"px";
	zTglc(document.body,'mo');
	document.body.appendChild(o);
	return o;
}


function prep_modal(url,c,o,t,u,w,h){
	if(!url) return;
	if(u){dropPixel(u);}
	if(t == 'pop') {
		zpu(0,url,(w)?w:404,(h)?h:300,"modal");
	} else {
		//create background to put behind modal (normally styled as translucent)
		var o = createOverlay(o);
		//create loader div and put it on the page so user knows something is happening
		var d = document.createElement('div');
		d.id = "modc";
		if(c) d.className = c;
		var r = 1;
		document.body.appendChild(d);
		position_modal(d);
		d.innerHTML = '<iframe src="'+url+'" scrolling="no" frameborder="0" class="modf" name="modf" id="modf" onload="frameLoad(this,'+r+',1)"></iframe>'; //IE doesn't allow adding onload events to iframes unless you use innerHTML
		if(c!='static') o.onclick = function(){hide_modal()};
		return false;
	}
}

function position_modal(d){
	var c = gEI('articlebody') || gEI('abw');
	if(d.clientWidth > zIfw){
		d.style.left = "0px";
	}else if(d.clientWidth > c.clientWidth){
		d.style.left = ((zIfw/2)-((d.clientWidth+2)/2))+"px";
	} else {
		d.style.left = findPos(c)[0]+((c.clientWidth-d.clientWidth)/2)+"px";
	}
	d.style.top = (zIfh > d.clientHeight)?((zIfh/2)-((d.clientHeight+2)/2))+"px":0+"px";
	if(zIfw < d.clientWidth || zIfh < d.clientHeight){d.style.position ="absolute";}
}

var s;
var h=0;
function rotate(dir){ //this function rotates the images in the image pop-up for article documents
	h+=dir;
	if(h<0)h=s.length-1;
	if(h==s.length)h=0;
	for(var i=0;i<s.length;i++){
		(i==h)?s[i].className="":s[i].className="hide";
	}
	if(parent.frames['modf']){parent.setFrameHeight(parent.document.getElementById('modf'));}
}

function frameLoad(i,r,c){
	if(r) setFrameHeight(i,c);
	if(r) s = i.contentWindow.document.getElementsByTagName("dl"); //this is for the slideshow rotate script to work properly
	i.parentNode.className += " loaded";
	//i.contentWindow.focus();
}

function setFrameHeight(i,c) { //resize modal frame to fit iframe content and centers frame in the viewport
	if(!i) return;
	i.style.width = i.parentNode.style.width = i.contentWindow.document.body.offsetWidth + "px";
	i.style.height = i.parentNode.style.height = i.contentWindow.document.body.offsetHeight + "px";
	if(c){
		position_modal(i.parentNode);
	}
}

function hide_modal(i){ //clean-up time
	if(!i) i = gEI('modc');
	if(!i) return;
	zTglc(document.body,'mo');
	document.body.removeChild(gEI("oL"));
	document.body.removeChild(i);
}
	
function do_logout(A,P){
	var i = document.createElement('iframe');
	i.src = A;
	i.scrolling = "no";
	i.frameborder = "0";
	i.style.display = "none";
	document.body.appendChild(i);
	change_login_state('0',P);
	return false;
}

function change_login_state(x,product){
	if(!gEI('lis')) return;
	if(!x){x = 1;}
	var label = gEI('lis').getElementsByTagName('label')[0];
	var info = gEI('m_login');
	var name = gEI('m_name');
	var id = gEI('guid');
	var mail = gEI('m_mail');
	if(readCookie('LK')){
		var c = readCookie('LK');
		var z = c.split('&');
		minfo = new Array();
		for(var i=0;i < z.length;i++) {
			var y = z[i].split('=');
			minfo[y[0]] = y[1];
		}
		if(x==1){
			label.innerHTML = 'Membername';
			info.innerHTML = '(If you\'re not <span>'+minfo['CN']+'</span>, <a href="http://membership.about.com/memreg?action=logoff&successurl='+window.location+'&surlanchor=%23lis&cob='+gs+'&product='+product+'" onclick="return do_logout(this.href,\''+product+'\');">click here</a>)';
			name.value = minfo['CN'];
			name.className = 'logged_in';
			name.readOnly = true;
			id.value = minfo['GUID'];
			if(mail){mail.value = minfo['mail'];mail.className = 'logged_in';}
		}
	}
	if(x==0){
		label.innerHTML = 'Guest Name<em title="Required field">*</em>';
		info.innerHTML = '<a href="http://www.about.com/gi/pages/login.htm" onclick="return prep_modal(this.href);">Login with Membername</a> or <a href="http://login.about.com/registration.htm?successurl='+window.location+'&surlanchor=%23lis&cob='+gs+'&product='+product+'">Register</a>';
		name.value = name.className = '';
		name.readOnly = false;
		if(mail){mail.value = mail.className = '';}
	}
	return;	
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/; domain=.about.com";
}

function splitList(obj,n){
	if(obj.nodeName != 'OL' && obj.nodeName != 'UL'){return;}
	if(!n){n=2;}
	var div = document.createElement('div');
	if(obj.id) div.id=obj.id;
	if(obj.className) div.className=obj.className;
	var lists=new Array();
	var li = obj.getElementsByTagName('li');
	var x = Math.ceil(li.length/n);
	for(var a=0;a<n;a++){
		var y = document.createElement(obj.nodeName);
		y.className = obj.className;
		if(obj.nodeName=='OL'){y.start=(a*x)+1}
		zTglc(y,'col'+(a+1));
		for(var b=0;b<x;b++){
			if(obj.getElementsByTagName('li')[(a*x)+b]){
				var z = obj.getElementsByTagName('li')[(a*x)+b].cloneNode(true);
				y.appendChild(z);
			}
		}
		lists.push(y);
	}
	for(var c=0;c<lists.length;c++){
		div.appendChild(lists[c]);
	}
	obj.parentNode.replaceChild(div,obj);
}

function splitLists(){
	var lists = getElementsByClassName("split", document),
		list, list_items, list_holder,
		list_count = lists.length + 0, n,
		column_count, items_per_column, c,
		list_template, new_list, new_list_length;
		
	while (lists.length) {
		list = lists.shift();
		
		if (list && (list.nodeName == "UL" || list.nodeName == "OL")) {
			column_count = parseInt(list.getAttribute("data-columns"), 10) || 2;
			
			list_holder = document.createElement("div");
			list_holder.className = list.className + " split-list";
			list_holder.id = list.id;
			list.parentNode.insertBefore(list_holder, list);
			
			list_items = list.cloneNode(true).getElementsByTagName("li");

			list_template = document.createElement(list.nodeName);

			items_per_column = Math.ceil(list_items.length / column_count);
			
			for (c = 0; c < column_count; c++) {
				new_list = list_template.cloneNode(false);
				new_list_length = Math.min(list_items.length, items_per_column);

				for (n = 0; n < new_list_length; n++) {
					new_list.appendChild(list_items[0]);
					new_list.className = "c"+(n+1);
					if(new_list.nodeName=='OL'){new_list.start=(n*items_per_column)+1}
				}
				
				list_holder.appendChild(new_list);
			}
			
			list.parentNode.removeChild(list);
		}
	}
}

function addEventSimple(obj,evt,fn){
	if(obj.addEventListener){
		obj.addEventListener(evt,fn,false);
	} else if(obj.attachEvent){
		obj.attachEvent('on'+evt,fn);
	}
}

function removeEventSimple(obj,evt,fn) {
	if (obj.removeEventListener)
		obj.removeEventListener(evt,fn,false);
	else if (obj.detachEvent)
		obj.detachEvent('on'+evt,fn);
}

function findPos(obj) { // find the absolute x,y positioning of an element
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}

/* Finds the form that 'fbbox' is contained in, then adds a hidden input with the value of the OA token & adds a query string value to the successurl. */
function oauth(token){
	var i = gEI('fbbox');
	if(!token){ i.checked = false; return false; }
	else{
		i.checked = true;
		var p = i.parentNode;
		p.className += ' auth';
		if (p.nodeName != 'FORM') {
			do {
				p = p.parentNode;
			} while (p.nodeName != 'FORM');
		}
		for(var x=0;x<p.elements.length;x++){
			if(p.elements[x].name == 'successurl'){
				if(p.elements[x].value.indexOf('fb=1')<0) p.elements[x].value = p.elements[x].value.replace('success=1','success=1&fb=1');
			}
		}
		h = document.createElement('input');
		h.type = 'hidden';
		h.name = 'oat';
		h.value = token;
		p.appendChild(h);
		fb_warn_user(token);
	}
	return true;
}

/* removes OA token hidden input & successurl query string value */
function de_oauth(){
	i = gEI('fbbox');
	i.checked = false;
	var p = i.parentNode;
	p.className = 'fbbx';
	gEI('fb_badge').parentNode.removeChild(gEI('fb_badge'));
	if (p.nodeName != 'FORM') {
		do {
			p = p.parentNode;
		} while (p.nodeName != 'FORM');
	}
	for(var x=0;x<p.elements.length;x++){
		if(p.elements[x].name == 'oat'){
			p.removeChild(p.elements[x]);
		} else if(p.elements[x].name == 'successurl'){
			p.elements[x].value = p.elements[x].value.replace('&fb=1','');
		}
	}
}

/* Shows the user what facebook profile is being authorized; allows them to take action if it's not their profile */
function fb_warn_user(token){
	if(!token){ return false; }
	if(!FB.getAuthResponse()){
		fb_init();
	}
	FB.api('/me?access_token='+token, function(response) {
		var user = response;
		var img = document.createElement('img');
		img.src = 'https://graph.facebook.com/me/picture?access_token='+token;
		img.alt = user.name;
		var p = document.createElement('p');
		p.innerHTML = 'This response will be published to <a href="'+user.link+'">'+user.name+'</a>\'s Facebook Wall when it is approved. If this is not you, please <span class="a" onclick="fb_log_out();">log out</span>.';
		var div = document.createElement('div');
		div.id = 'fb_badge';
		div.appendChild(img);
		div.appendChild(p);
		gEI('fbbox').parentNode.appendChild(div);
	});
}

function fb_init(){
	FB.init({
		appId  : '121030274606741',
		status : false, // check login status
		cookie : false, // enable cookies to allow the server to access the session
		xfbml  : false  // parse XFBML
	});
}

function fb_log_out(){
	FB.logout(function(response) {
		de_oauth();
	});
}

function dropPixel(u){
	if(!u) return;
	var i=new Image();
	i.src='http://clk.about.com?zi='+u+'&zTi=1&sdn='+gs+'&cdn='+ch+'&tt='+zTt+'&bt='+zBT+'&bts='+zBTS;
	return i;
}
				
function convertImageSize(src,s){
	return (src.indexOf('.about.com') < 0 && src.indexOf('.tqn.com') < 0)?src:src.replace(/\.com\/(.{1})\/([\w\d]*)\/(.{1})\/.{1}/, '.com/$1/$2/$3/'+s);
}

var zIfw=self.innerWidth?self.innerWidth:(document.documentElement&&document.documentElement.clientWidth?document.documentElement.clientWidth:(document.body?document.body.clientWidth:0));
var thin=0;
