/****************************
Pulpit Poll related functions.
****************************/

// Dedicated placeholders for requests.
var poll_request;
var confidence_poll_request;
var related_link_request;
var confidence_entry_id;


// The mode that the pulpit poll is submitted in - submit or display.
var action;


// Checks for poll response cookie... if poll has been taken it shows poll results, if not it shows poll question. 
function pollToggle(cookie_name) {
	if ( getCookie(cookie_name) ) {
		submitPollResponse('display', cookie_name);
	} else {
		// Display the poll box (with borders) and the question box within.
		//alert(document.getElementById('pollfloater'));
		//document.getElementById('pollfloater').style.display = "block";
		document.getElementById('pollfloatercontent_question').style.display = "block";
	}
}


// Set a cookie.
// setCookie( 'mycookie', 'visited 9 times', 30, '/', '', '' );
function setCookie( name, value, expires, path, domain, secure ) {

	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );

	/*
	if the expires variable is set, make the correct 
	expires time, the current script below will set 
	it for x number of days, to make it for hours, 
	delete * 24, for minutes, delete * 60 * 24
	*/
	if ( expires ) {
		expires = expires * 1000 * 60 * 60 * 24;
		//alert(expires);
	}
	var expires_date = new Date( today.getTime() + (expires) );

	document.cookie = name + "=" + escape( value ) + ( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + ( ( path ) ? ";path=" + path : "" ) + ( ( domain ) ? ";domain=" + domain : "" ) + ( ( secure ) ? ";secure" : "" );

}


// Get a cookie, if it exists
// getCookie( 'your_cookie' )
function getCookie( name ) {
  
	var start = document.cookie.indexOf( name + "=" );
	//alert(name);
	var len = start + name.length + 1;
	if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
		return null;
	}
	if ( start == -1 ) {
		return null;
	}
	var end = document.cookie.indexOf( ";", len );
	if ( end == -1 ) {
		end = document.cookie.length;
	}
	return unescape( document.cookie.substring( len, end ) );
}


// Deletes a cookie.
// deleteCookie('cookie name', '/', '')
function deleteCookie( name, path, domain ) {

	if ( getCookie( name ) ) {
		document.cookie = name + "=" +
		( ( path ) ? ";path=" + path : "") +
		( ( domain ) ? ";domain=" + domain : "" ) +
		";expires=Thu, 01-Jan-1970 00:00:01 GMT";
	}
}



// Creates a cross browser HTTP request.
function createRequest() {
  try {
    var request = new XMLHttpRequest();
    return request;
  } catch (trymicrosoft) {
    try {
      var request = new ActiveXObject("Msxml2.XMLHTTP");
      return request;
    } catch (othermicrosoft) {
      try {
	var request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (failed) {
	var request = false;
	return request;
      }
    }
  }

  if (!request)
    alert("Error initializing XMLHttpRequest!");

}


// Return the value of the radio button that is checked.
// Return an empty string if none are checked, or if
// there are no radio buttons.
function getCheckedValue(radioObj) {
  if(!radioObj) {
    return "";
  }
  var radioLength = radioObj.length;
  if(radioLength == undefined) {
    if(radioObj.checked) {
      return radioObj.value;
    }
    else {
      return "";
    }
  }
  for(var i = 0; i < radioLength; i++) {
    if(radioObj[i].checked) {
      return radioObj[i].value;
    }
  }
  return "";
}


// Sets poll cookie and displays poll results on the page.
function displayPollResults(response) {
  
	//alert(response);
	var blog_id;
	var entry_id;
	var answer_id;
	var answer_1_percentage;
	var answer_2_percentage;

	var pairs = response.split(';');

	for (var i=0; i<pairs.length; i++) {
	
		var bits = pairs[i].split(':');
		var key = bits[0];
		var value = bits[1];
		if (key == 'entry_id') {
			entry_id = value;
		}
		if (key == 'blog_id') {
			blog_id = value;
		}
		if (key == 'answer_id') {
			answer_id = value;
		}
		if (key == 'answer_1_percentage') {
			answer_1_percentage = value;
		}
		if (key == 'answer_2_percentage') {
			answer_2_percentage = value;
		}

	}
  
  
	// Set cookie so that we know this user agent has responded to this particular entries poll previously.
	if (action == 'submit') {
		setCookie( 'cringely_poll_' + blog_id + '_' + entry_id, answer_id, 30, '/cringely', '.pbs.org', '' );
	}


	// Swap the % values into the DOM. 
	document.getElementById('poll_results_answer_1').innerHTML = answer_1_percentage + ' %';
	document.getElementById('poll_results_answer_2').innerHTML = answer_2_percentage + ' %';


	// Determine what Cringely answered and set some defaults on img src attribute values that we can override later if we need to.
	var bobs_choice = 0;
	var not_bobs_choice = 0;
	if (document.getElementById('bob1')) {
		bobs_choice = 1;
		not_bobs_choice = 2;
		document.getElementById('bob1').src = '../images/icons/td_pollmini_bob_onred.gif';
		document.getElementById('you_2').src = '../images/icons/td_pollmini_noone.gif'; // This image allows the textual percentage to valign middle in the smaller bar.
	}
	if (document.getElementById('bob2')) {
		bobs_choice = 2;
		not_bobs_choice = 1;
		document.getElementById('bob2').src = '../images/icons/td_pollmini_bob_onred.gif';
		document.getElementById('you_1').src = '../images/icons/td_pollmini_noone.gif';
	}


	// Calculate width % limit for special case of tribaldudes / bob / text being too big to be contained by the smaller results bar. 
	var limit = 25;
	if (bobs_choice == answer_id) {
		limit = 35;
		if (answer_id == 1) {
			document.getElementById('you_2').src = '../images/icons/td_pollmini_noone.gif';
			document.getElementById('you_2').style.display = 'inline';
		}
		if (answer_id == 2) {
			document.getElementById('you_1').src = '../images/icons/td_pollmini_noone.gif';
			document.getElementById('you_1').style.display = 'inline';
		}
	}

	// Which answer has the smaller percentage and which has the larger?
	var smaller = 1;

	// Answer 1 has a smaller % than answer 2.
	if (answer_1_percentage < answer_2_percentage) {
		smaller = 1;
		smaller_percentage = answer_1_percentage;
		larger = 2;
	
	// Answer 2 has a smaller % than answer 1.
	} else if (answer_1_percentage > answer_2_percentage) {
		smaller = 2;
		smaller_percentage = answer_2_percentage;
		larger = 1;

	// 50/50 split. Bob breaks the tie.
	} else if (answer_1_percentage == answer_2_percentage) {
		if (bobs_choice == 1) {
			smaller = 2;
			smaller_percentage = answer_2_percentage;
			larger = 1;
		} else {
			smaller = 1;
			smaller_percentage = answer_1_percentage;
			larger = 2;
		}
	}


	// If you are with the majority, choose your "on red" image.
	if (answer_id == larger) {
		document.getElementById('you_' + larger).src = '../images/icons/td_pollmini_you_onred.gif';
	}

	
	// Which answer has the larger percentage and the smaller percentage is determined at runtime.
	// This use of smaller abd larger allows us to assign styles in one fell swoop instead of if/else forking ourselves to brain-death.
	document.getElementById('pollbar_answer' + smaller).className = 'pollbar_mini_smaller';
	document.getElementById('pollbar_answer' + larger).className = 'pollbar_mini_larger';
	document.getElementById('pollbar_answer' + smaller + '_content').className = 'pollbar_mini_smaller_content';
	document.getElementById('pollbar_answer' + larger + '_content').className = 'pollbar_mini_larger_content';
	document.getElementById('poll_results_answer_' + smaller).className = 'pollbar_mini_smaller_percentage';
	document.getElementById('poll_results_answer_' + larger).className = 'pollbar_mini_larger_percentage';

  	
	// Make the graph bars reflect the answer percentages.
	document.getElementById('pollbar_answer1').style.width = answer_1_percentage + '%';
  	document.getElementById('pollbar_answer2').style.width = answer_2_percentage + '%';

	
	// Handle smaller graph bar.
	// If the tribal dudes / bob / text are wider than the percentage allows, move them outside the graph bar by setting margin-left.
	// Also choose new img src values aliased to white instead of gray.
	if (smaller_percentage < limit) {
		if (bobs_choice == smaller) {
			document.getElementById('bob' + smaller).src = '../images/icons/td_pollmini_bob_offgray.gif';
		}
		document.getElementById('pollbar_answer' + smaller + '_content').style.marginLeft = smaller_percentage + '%';
		if (answer_id == smaller) {
			document.getElementById('you_' + smaller).src = '../images/icons/td_pollmini_you_offgray.gif';
		}
	} else {
		document.getElementById('poll_results_answer_' + smaller).style.color = '#fff';
		if (bobs_choice == smaller) {
			document.getElementById('bob' + smaller).src = '../images/icons/td_pollmini_bob_ongray.gif';
		}
		document.getElementById('pollbar_answer' + smaller + '_content').style.marginLeft = '0%';
		if (answer_id == smaller) {
			document.getElementById('you_' + smaller).src = '../images/icons/td_pollmini_you_ongray.gif';
		}
	}


	// Show user icon in appropriate results graph bar. 
	// If user skipped the poll, make sure to display the right "you" image. 
	// (the default img src just holds the text span open so the text can valign middle, and doesn't show any tribal dude.)
	if (answer_id == 1) {
		document.getElementById('you_1').style.display = 'inline';
	}
	if (answer_id == 2) {
		document.getElementById('you_2').style.display = 'inline';
	}
	if (answer_id == 'null') {
		document.getElementById('you_' + not_bobs_choice).style.display = 'inline';
	}
	document.getElementById('bob' + bobs_choice).style.display = 'inline';


	// Hide question, show answers.
	document.getElementById('pollfloatercontent_question').style.display = "none";
	document.getElementById('pollfloatercontent_results').style.display =  "block";
	//document.getElementById('pollfloater').style.display = 'block';

}


// The callback function called when the server is done processing a poll submission.
function pollDispatch() {
  if (poll_request.readyState == 4) {
    if (poll_request.status == 200) {
      var response = poll_request.responseText
      displayPollResults(response);
    }
    else if (poll_request.status == 404) {
      alert("Request URL does not exist");
    }
    else {
      alert("Error: status code is " + poll_request.status);
    }
  }
}



// Gathers poll response data and makes an asyncronous HTTP request to the polls backend.
function submitPollResponse(my_action, cookie_name) {
  
	action = my_action;
	poll_request = createRequest();
	var blog_id = document.getElementById('blog_id').value;
	var entry_id = document.getElementById('entry_id').value;
	var bobs = document.getElementById('bobs').value;
	var radioObj = document.getElementById('poll_form').answer_id;

	// If the user is submitting, grab the answer_id from the form control.
	var answer_id = getCheckedValue(radioObj);

	// If the user is returning, gra the answer_id from the cookie.
	if (my_action == 'display') {
		answer_id = getCookie(cookie_name);
	}

	// Removed this per Bob Kayne's request 12/12/07. Te reinstate, simply uncomment the next line and delete the line after that.
	//var why = document.getElementById('why').value; 
	var why = '';

	var url = "/cgi-registry/cringely/cringely_pulpit_poll.pl?action=" + my_action + ";blog_id=" + escape(blog_id) + ";entry_id=" + escape(entry_id) + ";bobs=" + bobs + ";answer_id=" + escape(answer_id) + ";why=" + escape(why);
	poll_request.open("GET", url, true);
	poll_request.onreadystatechange = pollDispatch;
	poll_request.send(null);

}



/****************************************
Pulpit Poll Interactive Related Functions
****************************************/


// Travel out from current element through the DOM summing the left offsets from the viewport edge.
function getLeft(e) {
	//alert(e);
	var left = 0;
	if (e.offsetParent) {
		while (e.offsetParent) {
			left += e.offsetLeft;
			e = e.offsetParent;
		} 
	} else if (e.x) { // For Netscape 4
		left += e.x;
	}
	return left;
}


// Travel out from current element through the DOM summing the top offsets from the viewport edge.
function getTop(e) {
	var top = 0;
	if (e.offsetParent) {
		while (e.offsetParent) {
			top += e.offsetTop;
			e = e.offsetParent;
		}
	} else if (e.y) {
		left += e.y;
	}
	return top;
}


function getCommentBoxId(o) {
	if (o == 'r') { 
		return 'floatingcommentboxcontainer_right';
	} else if (o == 'l') {
		return 'floatingcommentboxcontainer_left';
	}
}


function hideCommentBoxes() {
	document.getElementById('floatingcommentboxcontainer_right').style.visibility = 'hidden';
	document.getElementById('right_comment').innerHTML = '';
	document.getElementById('right_comment_date').innerHTML = '';
	document.getElementById('floatingcommentboxcontainer_right').style.visibility = 'hidden';
	document.getElementById('left_comment').innerHTML = '';
	document.getElementById('left_comment_date').innerHTML = '';
}


var poll_comment_o = '';
var confidence_poll_comment_date = '';
function displayPulpitPollComment(response) {

	var e = '';
	var d = '';
	if (poll_comment_o == 'r') {
		e = document.getElementById('right_comment');
		d = document.getElementById('right_comment_date');
	}
	if (poll_comment_o == 'l') {
		e = document.getElementById('left_comment');
		d = document.getElementById('left_comment_date');
	}
        if (response == '0') {
                response = '';
        }
	e.innerHTML = response;
	d.innerHTML = confidence_poll_comment_date;

}


function pulpitPollCommentDispatch() {
	// The callback function called when the server is done processing a pulpit poll interactive comment request.
	if (poll_request.readyState == 4) {
		if (poll_request.status == 200) {
			var response = poll_request.responseText
			displayPulpitPollComment(response);
		}
		else if (poll_request.status == 404) {
			alert("Request URL does not exist");
		}
		else {
			alert("Error: the status code is " + poll_request.status);
		}
	}
}


// AJAX to get comment text from database.
function getPulpitPollComment(response_id) {

	var url = '/cgi-registry/cringely/pulpit_poll_interactive_comments.pl?response_id=' + escape(response_id);
	poll_request = createRequest();
  	poll_request.open("GET", url, true);
  	poll_request.onreadystatechange = pulpitPollCommentDispatch;
  	poll_request.send(null);

}


// Takes id=dom element id and o=orientation (l, or r)
function showFloatingCommentBox(id, index, o) {

	// Hide the comment boxes.
	hideCommentBoxes();

	// Make the orientation globally available.
	poll_comment_o = o;

	// Get id for the appropriate comment box.
	var floating_comment_box_id = getCommentBoxId(o);

	var response_id = '';
	var comment_date = '';
	if (id == 'bob') {
		poll_request = '';
		if (o == 'l') {
			document.getElementById('left_comment').innerHTML = bobs_comment;
		}
		if (o == 'r') {
			document.getElementById('right_comment').innerHTML = bobs_comment;
		}
	} else {
		if (o == 'r') {
			response_id = answer_1_ids[index-1];
			comment_date = answer_1_dates[index-1];
		} 
		if (o == 'l') {
			response_id = answer_2_ids[index-1];
			comment_date = answer_2_dates[index-1];
		}
		getPulpitPollComment(response_id);
	}

	confidence_poll_comment_date = comment_date;

	// Get the positioning of the image that was mousedover.
	var i = document.getElementById(id);
	var width = i.clientWidth;
	var height = i.clientHeight;
	var top = getTop(i);
	var left = getLeft(i);

	// Get the comment box element from the DOM.
	var cb = document.getElementById(floating_comment_box_id);
	var cb_width = cb.clientWidth;
	//var cb_height = cb.clientHeight;

	// Reposition comment box.
	var new_top = top - 40;

	if (o == 'r') {
		var new_left = left + width - 5; 
	} else if (o == 'l') {
		var new_left = left - cb_width; 
	}

	cb.style.top = new_top + 'px';
	cb.style.left = new_left + 'px';

	// Turn visibility on.
	cb.style.visibility = 'visible';
}


function hideFloatingCommentBox(o) {

	// Get id for the appropriate comment box.
	var floating_comment_box_id = getCommentBoxId(o);

	// Get the comment box element from the DOM.
	var cb = document.getElementById(floating_comment_box_id);
	
	// Turn visibility off.
	cb.style.visibility = 'hidden';
}




/*****************************
Related Links related functions
******************************/


// Determines if the server returned a validation error, and if so displays error messaging. If the save to the database went ok, then the submission form is displayed once again.
function displayRelatedLinkResults(response) {

	if (response == 'ok') {
		// Show submission form
		document.getElementById('related_links_form').reset();
		document.getElementById('addlink').innerHTML = '<p class="ajax_confirm_inner">Thankyou. Your link was successfully submitted for review.</p>';
		//document.getElementById('addlink').style.display = 'none';
	} else {
		alert('Error: ' + response);
	}

}


// The callback function called when the server is done processing a related link submission.
function relatedLinkDispatch() {
	if (related_link_request.readyState == 4) {
		if (related_link_request.status == 200) {
			var response = related_link_request.responseText;
			displayRelatedLinkResults(response);
		}
		else if (related_link_request.status == 404) {
			alert("Request URL does not exist");
		}
		else {
			alert("Error: the status code is " + related_link_request.status);
		}
	}
}


// Submits a related link, shows errors from server side validation, shows submission form on success. 
function submitRelatedLink() {
  
	related_link_request = createRequest();
	var blog_id = document.getElementById('related_link_blog_id').value;
	var entry_id = document.getElementById('related_link_entry_id').value;
	var entry_permalink = document.getElementById('related_link_entry_permalink').value;
	var entry_title = document.getElementById('related_link_entry_title').value;
	var entry_date = document.getElementById('related_link_entry_date').value;
	var name = document.getElementById('related_link_name').value;
	var email = document.getElementById('related_link_email').value;
	var website = document.getElementById('related_link_website').value;
	var link_title = document.getElementById('related_link_title').value;
	var link_url = document.getElementById('related_link_url').value;
	var link_description = document.getElementById('related_link_description').value;

	var url = "/cgi-registry/cringely/tribe/related_links_save.pl?blog_id=" + escape(blog_id) + "&entry_id=" + escape(entry_id) + "&entry_permalink=" + escape(entry_permalink) + "&entry_title=" + escape(entry_title) + "&entry_date=" + escape(entry_date) + "&name=" + escape(name) + "&email=" + escape(email) + "&website=" + escape(website) + "&link_title=" + escape(link_title) + "&link_url=" + escape(link_url) + "&link_description=" + escape(link_description);
	//alert(url);

	related_link_request.open("GET", url, true);
	related_link_request.onreadystatechange = relatedLinkDispatch;
	related_link_request.send(null);

}


// Validate related links submission.
function clearRelatedLinksError() {

	var element = document.getElementById('error_msg');
	element.style.display = 'none';

	var field_ids = new Array('related_link_name_label', 'related_link_email_label', 'related_link_title_label', 'related_link_url_label', 'related_link_description_label');
	for (var i=0; i<field_ids.length; i++) {
		document.getElementById(field_ids[i]).className = '';
		//document.getElementById(field_ids[i]).style.color = 'black';
		//document.getElementById(field_ids[i]).style.fontWeight = 'normal';
	}

}

function showRelatedLinksError(field, error_msg) {

	var element = document.getElementById('error_msg');
	element.innerHTML = error_msg;
	element.style.display = 'block';

	document.getElementById(field).className = 'error_message';
	//alert(field);
	//document.getElementById(field).style.color = 'red';
	//document.getElementById(field).style.fontWeight = 'bold';

}

function validateRelatedLinks(form) {

	clearRelatedLinksError();
	var error = 0;
	var error_msg = 'Please fill out all required fields.';

	if (form.name.value == '') {
		showRelatedLinksError('related_link_name_label', error_msg);
		error = 1;
	}
	if (form.email.value == '') {
		showRelatedLinksError('related_link_email_label', error_msg);
		error = 1;
	}
	if (form.link_title.value == '') {
		showRelatedLinksError('related_link_title_label', error_msg);
		error = 1;
	}
	if (form.link_url.value == '') {
		showRelatedLinksError('related_link_url_label', error_msg);
		error = 1;
	}
	if (!form.link_url.value.match(/^http:\/\//)) {
		showRelatedLinksError('related_link_url_label', 'Your URL must start with "http://" to be accepted.');
		error = 1;
	}
	if (form.link_description.value == '') {
		showRelatedLinksError('related_link_description_label', error_msg);
		error = 1;
	}
	if (error == 1) {
		return false;
	}
	//alert(form); return false;

	submitRelatedLink();

}

/*************************
Comments related functions
*************************/

function commentPreview() {
  
  var t = document.getElementById('text');
  var h = document.getElementById('comment_preview_header');
  var p = document.getElementById('preview');

	// Hide the comment preview if the user empties the textarea.
	if (t.value == '') {
		//alert(t.value);
		p.style.display = 'none';
		h.style.display = 'none';
		return;
	}
  
  h.style.display = 'block';
  p.style.display = 'block';
  p.innerHTML = t.value;
  
  return true;

}

function keystrokes(form) {
	form.strokes.value = 1;
}



/*********************************
Confidence Poll related functions.
*********************************/


function displayConfidencePollResults(response) {

	//alert(confidence_entry_id); return;
	var e = document.getElementById('confidence_poll_container_' + confidence_entry_id);
	e.innerHTML = response;

}


// The callback function called when the server is done processing a poll submission.
function confidencePollDispatch() {

	if (confidence_poll_request.readyState == 4) {
		if (confidence_poll_request.status == 200) {
			var response = confidence_poll_request.responseText;
			displayConfidencePollResults(response);
		}
		else if (confidence_poll_request.status == 404) {
			alert('Request URL does not exist');
		}
		else {
			alert('Error: status code is ' + confidence_poll_request.status);
		}
	}
}


// Gathers confidence poll response data and makes an asyncronous HTTP request to the confidence poll backend.
function submitConfidencePollResponse(my_action, cookie_name, results_size, my_entry_id, year) {

        action = my_action;
	confidence_entry_id = my_entry_id;
	//alert(my_entry_id); return;
        confidence_poll_request = createRequest();
        var blog_id = document.getElementById('blog_id_' + my_entry_id).value;
        var entry_id = document.getElementById('entry_id_' + my_entry_id).value;
        var radioObj = document.getElementById('confidence_poll_form_' + my_entry_id).answer_id;

        // If the user is submitting, grab the answer_id from the form control.
        var answer_id = getCheckedValue(radioObj);

        var url = '/cgi-registry/cringely/cringely_confidence_poll.pl?blog_id=' + escape(blog_id) + ';entry_id=' + escape(entry_id) + ';answer_id=' + escape(answer_id) + ';size=' + escape(results_size) + ';ajax=1;year=' + escape(year);
        if (action == 'display') {
		url += ';display=1';
	}
	//alert(url);
        confidence_poll_request.open("GET", url, true);
        confidence_poll_request.onreadystatechange = confidencePollDispatch;
        confidence_poll_request.send(null);

}



// Changes a users vote.
function changeConfidencePollVote( blog_id, my_entry_id, destination, year ) {
	confidence_entry_id = my_entry_id;
	var url = '/cgi-registry/cringely/change_confidence_poll_vote.pl?ajax=1;year=' + escape(year) + ';blog_id=' + escape(blog_id) + ';entry_id=' + escape(my_entry_id) + ';destination=' + escape(destination) + '#poll';
	confidence_poll_request = createRequest();
        confidence_poll_request.open("GET", url, true);
        confidence_poll_request.onreadystatechange = confidencePollDispatch;
        //confidence_poll_request.onreadystatechange = confidencePollVoteChangeDispatch;
        confidence_poll_request.send(null);
}


// AJAX display.
function showConfidencePollSnapshot( snapshot, my_entry_id, year ) {
	
	confidence_entry_id = my_entry_id;
        confidence_poll_request = createRequest();

        var url = '/cgi-registry/cringely/cringely_confidence_poll.pl?size=large;snapshot=' + escape(snapshot) + ';entry_id=' + escape(my_entry_id) + ';year=' + escape(year);
        confidence_poll_request.open("GET", url, true);
        confidence_poll_request.onreadystatechange = confidencePollDispatch;
        confidence_poll_request.send(null);

}


/*******************************
External links related functions
*******************************/

function modExternalLinks() {
	var links_str = '';
	for (i=0; i<document.links.length; i++) {
		var hostname = document.links[i].hostname;
		var href = document.links[i].href;
		if (
			(!hostname.match(/pbs/)) && // PBS links should not open in a new window.
			(!hostname.match(/googlesyndication/)) && // Google adsense should not open in a new window.
			(!href.match(/javascript:/)) && // javascript pseudo urls should not open in a new window.
			(!href.match(/recaptcha/)) && // Do not change reCAPTCHA spam prevention code.
			(!href.match(/doubleclick/)) // Do not change doubleclick ad links.
		) {
			var parent = document.links[i].parentNode;
			var next = document.links[i].nextSibling;
			var span = document.createElement('span');
			span.innerHTML = '&nbsp;';
			var img = document.createElement('img');
			img.src = '/cringely/images/icons/icon_newwindow.gif';
			img.alt = 'External Link';
			document.links[i].target = 'new';
			parent.insertBefore(img, next);
			parent.insertBefore(span, img);
		}
	}
}
