/** Trim whitespace from the beginning and end of this string.
 * @return {string} Trimmed string.
 */
String.prototype.trim = function(){
    return this.replace( /(^ *| *$)/ , "" );
};

/** Gets an HTML element by id, if <tt>e</tt> is a string, otherwise returns <tt>e</tt>.
 * @param {Object|string} e Element or element id to get.
 * @returns {Object} HTML element, if found.
 */
function getElement( e ){
    if ( typeof(e) == "string" )
        return document.getElementById( e );
    return e;
};

/** Sets an element's "display" style property to "block".
 * @param {Object|string} e Element or element id.
 */
function showElement( e ){
    e = getElement( e );
    e.style.display = "block";
}

/** Sets an element's "display" style property to "none".
 * @param {Object|string} e Element or element id.
 */
function hideElement( e ){
    e = getElement( e );
    e.style.display = "none";
}

/** Toggles an element's "display" style property between "block" and "none".
 * @param {Object|string} e Element or element id.
 */
function toggleElement ( e ) {
    var e = getElement( e );
	if ( e.style.display == "none" ) {
	  e.style.display = "block";
	} else {
	  e.style.display = "none";
	 }
}

/** Toggles an element's "visible" style property between "visible" and "hidden".
 * @param {Object|string} e Element or element id.
 */
function toggleVisibility ( e ) {
    var e = getElement( e );
	if ( e.style.visibility == "hidden" ) {
	  e.style.display = "visible";
	} else {
	  e.style.display = "hidden";
	 }
}

/** Style some part of an element.
 * @param {Object|string} e Element or element id.
 * @param {string} part Property to send with request.
 * @param {string} v Text Value to send with request.
 */
function styleElement ( e , part, v ) {
    var e = getElement( e );
	e.style[part] = v;
}

/** Gets the class of an element.
 * @param {Object|string} Element or element id to find.
 * @return {string} Class.
 */
function getCSSClass( e ){
    e = getElement( e );
    if ( e ){
        return e.className;
    }
    return null;
}

/** Sets the class of an element.
 * @param {Object|string} Element or element id to find.
 * @param {string} Class name.
 */
function setClass( e , c ){
    e = getElement( e );
    if ( e ){
        e.className = c;
    }
}

/** Adds a class to an element.
 * @param {Object|string} Element or element id to find.
 * @param {string} Class name.
 */
function addClass( e, c ){
	e = getElement( e );
	var cname = e.className;
	var classes = cname.split(/\s+/);
	for(var i = 0; i < classes.length; i++){
		if(classes[i] == c) return;
	}
	e.className = e.className + ' ' + c;
}

/** Removes a class from an element.
 * @param {Object|string} Element or element id to find.
 * @param {string} Class name.
 */
function removeClass( e, c ){
	e = getElement( e );
	var cname = e.className;
	var classes = cname.split(/\s+/);
	for(var i = 0; i < classes.length; i++){
		if(classes[i] == c){
			classes[i] = '';
			break;
		}
	}
	e.className = classes.join(' ');
}

function showHide( idname, idnum , numelements ) {
	// hide elements
	for (i = 1 ; i <= numelements ; i++) {
		if (i != idnum) {
			var temp = idname + "body" + i;
			var f = document.getElementById(temp);
			if (f.style.display != "none") {
				f.style.display = "none";
				removeClass( document.getElementById( idname + "tab" + i ) , "selected" );
				addClass( document.getElementById( idname + "tab" + i ) , "not-selected" );
			}
		}
	}

	var cell = document.getElementById( idname + "body" + idnum );

	// show element
	if (cell.style.display != "") {
		cell.style.display = "";
		removeClass( document.getElementById( idname + "tab" + idnum ) , "not-selected" );
		addClass( document.getElementById( idname + "tab" + idnum ) , "selected" );
	}
}

/** Sets a browser cookie.
 * @param {string} name Cookie name.
 * @param {string} value Cookie value.
 * @param {number} hours Hours from now cookie should expire.
 */
function setCookie( name , value , hours ) {
    var expires = "";

    if ( hours ) {
        var date = new Date();
        date.setTime( date.getTime() + ( hours * 60*60*1000 ) );
        expires = "; expires=" + date.toGMTString();
    }

    document.cookie = name + "=" + value + expires + "; path=/";
}

/** Gets a browser cookie.
 * @param {string} name Cookie name.
 */
function getCookie( 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;
}

/** Removes a browser cookie.
 * @param {string} name Cookie name.
 */
function clearCookie(name) {
    getCookie(name,"",-1);
}

// Change preferred text size
function changeFontSize ( clickedSize, selectIndex ) {
    var prefSize = clickedSize;
    var cookieExp = 365*24;
    $('.KonaBody').removeClass('small').removeClass('med').removeClass('large').addClass(clickedSize);
    setCookie ( 'bi_font_size', prefSize, cookieExp );
    var prefSize = getCookie ( "bi_font_size" );
}


// Load river image if scrollTop value is greater than distance from top of window to river image
var vert_pos = 1;
var scroll_height = $('#i-count' + vert_pos).offset().top - ($(window).height());
var long_desc;

function loadRiverImage() {
	// load as long as needed
	while (($(window).scrollTop() > (scroll_height - 146)) && $('#i-count'+vert_pos).length != 0) {	    
        long_desc = ($('#i-count' + vert_pos + ' img').attr('longdesc'));
        $('#i-count'+vert_pos+' img').attr('src', long_desc).fadeIn(300); 	 
        vert_pos++;	   
		scroll_height = $('#i-count' + vert_pos).offset().top - ($(window).height());
	} 
}

$(window).scroll(function() {
	// load images onScroll
	if (($(window).scrollTop() > scroll_height - 146) && $('#i-count'+vert_pos).length != 0) {
	    loadRiverImage();
	} 
});

// Embed 
function loadButton(button, info, html) {
    $('#' + button).click(function() {
		if (info === 'embedchart-info') {
			hideElement('chartwidget-info');
		} else if (info === 'chartwidget-info') {
			hideElement('embedchart-info');
		}			
        $('#' + info).toggle();
        if (html && !($('#' + info).html())) {
            $('#' + info).html(html);
        }
        return false;
    }).show();
}

// Set default text field value
function shadowType(field) {
    var value = $('#'+field).val();
    $('#'+field).focus(function() {
        if ($(this).val() == value) {
            $(this).val('');
        }
    });
    $('#'+field).blur(function() {
        if ($(this).val() == '') {
            $(this).val(value);
        }
    });  
}

// Comments
function submit_comment(form, a) {
	var message = $(form).find('textarea[name=text]').val();
	if (!message) {
		alert('Please enter a comment.');
		return false;
	}
	
    var fb_comment = $(form).find('input[name=facebook_comment]').attr('checked');
    var tw_tweet = $(form).find('input[name=twitter_tweet]').attr('checked');

	if (fb_comment) {
    	var href = '' + document.location;
    	var i = href.indexOf('#');
    	if (i > -1) {
    		href = href.substring(0, i);
    	}

    	FB.ui({
    		method: 'stream.publish',
    		message: message,
    		action_links: [ { text: 'Read the Story', href: href }],
    		attachment: {
    			name: document.title,
    			description: $('meta[name=description]').attr('content'),
    			href: post.uri,
    			media: [{
    				type: 'image',
    				src: post.thumb,
    				href: post.uri
    			}]
    		}
    	},
    	function(response) {
    		if (response && response.post_id) {
    			gaPageTrack('Share', 'Click', 'Facebook_Wall');
    		}
			if (tw_tweet) {
                $("textarea[name=tweet_in_dialog]").val($("textarea[name=text]").val());
            	$('#comment-tweet-dialog').dialog("open");
			}
			else {
			    form.submit();
			}
    	});	    

    	return false;
	}
	else if (tw_tweet) {
        $("textarea[name=tweet_in_dialog]").val($("textarea[name=text]").val());
    	$('#comment-tweet-dialog').dialog("open");

    	return false;
	}
	else {
	    return true;
	}
}

comment_reply_id = null;
function comment_reply(button) {
	var reply = get_property(button, 'cid');
	if (comment_reply_id == reply) {
		comment_reply_id = null;
		$(button).next().remove();
	} else {
		var html = $('#comments-open').html();
		html = html.replace(/Answer As/, 'Respond As');
		var html = '<div class="reply-form">' + html + '</div>';
		$('.reply-form').remove();
		$(button).after(html).next().find('input[name=reply]').val(reply);
		$(button).next().find("input, textarea").focus(function(){
            Slideshow.listenKeys = false;
	    });
		$(button).next().blur("input, textarea").blur(function(){
            Slideshow.listenKeys = true;
	    });

		comment_reply_id = reply;
	}
	return false;
}

function comment_feature(button) {
	var cid = get_property(button, 'cid');
	return comment_action(cid, 'feature');
}

function comment_action(cid, action) {
	var post_data = { comment_id: cid, action: action };
	
	if (window.post) {
		post_data['class'] = 'Post';
		post_data['id'] = post.id;
	}
	if (window.question) {
		post_data['class'] = 'Question';
		post_data['id'] = question.id;
	}
	
	ajax_json(
		'/ws/comment',
		post_data,
		function(json) {
			$('#comments').html(json.html);
		}
	);
	return false;
}

function get_post_data(post_data) {
	post_data = post_data ? post_data : {};
	if (window.post) {
		post_data['class'] = 'Post';
		post_data['id'] = post.id;
	}
	if (window.question) {
		post_data['class'] = 'Question';
		post_data['id'] = question.id;
	}
	return post_data;
}

function comment_rate(button, rate) {
	if (get_property(button, 'rateable') == '0') {
		alert('You may not rate your own comment.');
		return false;
	}
	if (rate != -1 && rate != 1) {
		return false;
	}
	var rateup = $(button).parent().parent().find('.rate-up');
	var ratedown = $(button).parent().parent().find('.rate-down');
	var rateup_count = rateup.find('.count');
	var ratedown_count = ratedown.find('.count');
	if (rateup.hasClass("selected")) {
		if (rate == 1) {
			return false;
		} else {
			rateup.removeClass("selected");
			rateup_count.html(parseInt(rateup_count.html()) - 1);
		}
	}
	if (ratedown.hasClass("selected")) {
		if (rate == -1) {
			return false;
		} else {
			ratedown.removeClass("selected");
			ratedown_count.html(parseInt(ratedown_count.html()) - 1);
		}
	}
	if (rate == -1) {
		ratedown.addClass("selected");
		ratedown_count.html(parseInt(ratedown_count.html()) + 1);
	} else {
		rateup.addClass("selected");
		rateup_count.html(parseInt(rateup_count.html()) + 1);
	}
	
	if (parseInt(rateup_count.html()) > 0) {
		rateup.addClass("voted");
	} else {
		rateup.removeClass("voted");
	}
	
	if (parseInt(ratedown_count.html()) > 0) {
		ratedown.addClass("voted");
	} else {
		ratedown.removeClass("voted");
	}
			
	var comment_id = get_property(button, 'cid');
	var post_data = get_post_data();
	post_data.comment_id = comment_id;
	post_data.rate = rate;
	$.ajax({
		type: 'POST',
		url: '/ws/ratecomment',
		data: post_data,
		dataType: 'json',
		success: function(json) {
			
		},
		error: function() {
			alert('We\'re experiencing a temporary problem with our rating system. Try again later.');
		}
	});
	return false;
}

function comment_flag_offensive(element)
{
	if ($(element).html() == 'Flagged') {
		return false;
	}
	if (!confirm("Are you sure you want to report this comment as offensive?")) {
		return false;
	}
	
	var cid = get_property(element, 'cid');
	$.ajax({
		url: '' + document.location,
		type: 'POST',
		data: {'action': 'flagOffensive', 'cid': cid},
		dataType: 'json',
		success: function(response) {
			if (response.ok) {
				$(element).html('Flagged');
				alert('Thank you. This comment will be reviewed.');
			}
			else {
				alert(response.error_msg);
			}
		},
		error: function() {
			alert('We\'re experiencing a temporary problem with our commenting system. Try again later.');
		}		
	});
	
	return false;
}

function countdown_timer() {
    var time = countdown_timer_end - Math.floor(new Date().getTime() / 1000);
    if (time <= -3600 || (countdown_timer_finish == 'hide' && time <= 0)) {
        $('#countdown').hide();
        return;
    } else if (time <= 0) {
		$('#countdown .live').show();
		$('#countdown .timer').hide();
		return;
	}

	var colon = '<span class="colon"><span>:</span></span>';
	var to_digits = function(str) {
		str = '' + str;
		var sstr = '';
		for (var i=0; i < str.length; i++) {
			var c = str.charAt(i);
			if (c >= '0' && c <= '9') {
				sstr += '<span class="digit-'+c+'"><span>'+c+'</span></span>';
			}
		}
		return '<span class="digits">' + sstr + '</span>';
	}

    var sec = time % 60;
    sec = sec < 10 ? '0'+sec : sec;
    var min = Math.floor(time / 60) % 60;
    min = min < 10 ? '0'+min : min;
    var hour = Math.floor(time / 3600);
    var str = colon + to_digits(sec);
    if (time >= 60) {
        str = to_digits(min) + str;
    }
    if (time >= 3600) {
        str = to_digits(hour) + colon + str;
    }
    $('#countdown .timer').html(str);
    setTimeout(countdown_timer, 100);
}

function require_login(redirect) {
	if (window.user_id) {
		return true;
	}
	return dialog_login(false, redirect);
}

function dialog_login(required, redirect) {
	redirect = redirect ? redirect : '' + document.location;
	ajax_json_get('/login', { redirect: redirect, required: required }, function(json) {
		$('<div>' + json.content + '</div>').dialog(json.dialog);
	});
	return false;
}


// Comment alerts
var CommentAlerts = {
    showSubscribeForm: function(div_id, obj){
        $('#' + div_id).show();
        $(obj).hide();
    },
    
    subscribeEmail: function(form, div_id) {
        var email = $(form).find('input[name=email]').val();
        var action = $(form).find('input[name=alert_action]').val();
        var validate_error = '#' + div_id + '_validate_error';

        $.ajax({ 
            type: 'POST', 
            url: '' + document.location, 
            data: { action: action, email: email }, 
            dataType: 'json', 
            success: function(json) {
                if (json.ok == true) {
                    $(validate_error).hide();
                    link_div = '#' + div_id + '_link';
                    $(link_div).html('Thank you. You will receive email alerts about new comments on this post');
                    removeClass(div_id + '_link', div_id + '_link');
                    styleElement(div_id + '_link','color', '#de1f1f');
                    $(link_div).removeAttr('onclick');
                    $(link_div).show(); 
                    $('#' + div_id).hide();
                }
                else {
                    $(validate_error).html('' + json.error_msg + '');
                    $(validate_error).show();
                }
            }
        });
    }
};

function fb_login() {
	FB.login(function(response) {
		if (response.session) {
			document.location = '/login?redirect=' + encodeURIComponent(''+document.location);
		}
	});
	return false;
}

function fb_logout() {
	if (FB.getSession()) {
		FB.logout(function(response) {
			document.location = '/logout?redirect=' + encodeURIComponent(''+document.location);
		});
		return false;
	}
	return true;
}

function gaPageTrack(a, b, c) {
	if (window.pageTracker) {
		pageTracker._trackEvent(a, b, c);
	}
}


// The Mogul Game
VoxPopPageViewCount = 0;
function VoxPopPageView() {
	VoxPopPageViewCount++;
	if (VoxPopPageViewCount % 3 == 0) {
	  // refresh ads every third update
	  $('iframe.ad').each(function() {
	    var src = $(this).attr('src');
	    src = src.replace(/cb\=.*/, 'cb=' + Math.random());
	    $(this).attr('src', src);
	  });
	}

  // google analytics
  if (window.pageTracker && pageTracker) {
    pageTracker._trackPageview();
  }

  // internal analytics
  var params = {
    location: document.location + ''
  };
  if (window.vertical && vertical) {
    params.vertical = vertical;
  }
  $.get('/track.gif', params);
}