function isCanvasSupported() {
  var elem = document.createElement('canvas');
  return !!(elem.getContext && elem.getContext('2d'));
}

function truncate(text, max)  {
    if (typeof max == 'undefined') { max=100;}
    if (text.length <= max) {
        return text;
    }
    return text.substr(0, max-4) + "...";
    
} 

//Remove leading/trailing whitespaces and newlines
function superTrim(text) {
    var trimmedText = $.trim(text);
    return trimmedText.replace(/\n/g, ' ');
}

//Instead of regular split, just split into an array of two, stopping on the
//first occurrence of delimiter
//Note: Different from string.split(delimiter, limit) which actually gives you
//the first limit parts of the split arr
function splitFirst(text, delimiter) {
    var arr = text.split(delimiter);
    return [arr.shift(), arr.join(delimiter)];
}

function centerElem(elem) {
    var left = $(window).width()/2  - $(elem).width()/2;
	var top = $(window).height()/2 + $(window).scrollTop() - $(elem).height()/2;
	$(elem).css("left", left+"px");
	$(elem).css("top", top+"px");
}

function centerElemInParent(elem, parentElem) {
    var offset = $(parentElem).offset();
    var left = offset.left + $(parentElem).width()/2  - $(elem).width()/2;
	var top = offset.top + $(parentElem).height()/2 + $(parentElem).scrollTop() - $(elem).height()/2;
	$(elem).css("left", left+"px");
	$(elem).css("top", top+"px");
}

function isValidEmail(email) {
    return email; //just check to see if it's empty
}

function turnButtonOff(buttons, text, spinner) {
    if (spinner) { 
        spinner = "<img style='width: 1em;' src='"+STATIC_URL+"images/loader2.gif' alt=''>&nbsp;";
    } else { 
        spinner = "";
    }
    var $button, isButton, buttonText;
    return $(buttons).each(function() {
        $button = $(this);
        isButton = $button.is('button');
        buttonText = text;
        $button.data('old-text', isButton? $button.html() : $button.val());
    	if (typeof buttonText == 'undefined') { 
           buttonText = isButton? $button.html() : $button.val();
        }
    	$button.addClass('disabled').attr("disabled", "disabled");
        if (isButton) { $button.html(spinner + buttonText); }
        else { $button.val(buttonText); }
    });
}

/*
   Change text to text if given, else 'text if stored in DOM element,
    or finally just default to button's current text
*/
function turnButtonOn(buttons, text) {
    var $button, isButton, buttonText;
    return $(buttons).each(function() {
        $button = $(this);
        isButton = $button.is('button');
        buttonText = text;
    	if (typeof buttonText == 'undefined') {
    	    buttonText = $button.data('old-text') || (
                isButton? $button.html() : $button.val());
    	}
    	$button.removeClass('disabled').removeAttr("disabled");
        if (isButton) { $button.html(buttonText); }
        else { $button.val(buttonText); }
    });

}

function flashHighlight(elem) {
    var oldBorder = $(elem).css("border");
    var oldColor = $(elem).css("font-color");
    $(elem).css("border", "1px solid #499510").css("color", "#499510");
    setTimeout(function() { 
        $(elem).css("border", oldBorder).css("color", oldColor);
    }, 000);
}

function highlightFormError(elem) {
    var oldBorder = $(elem).css("border");
    $(elem).css("border", "1px solid red");
    $(elem).focus(function() {
        $(elem).css('border', oldBorder);
    });
}

function intcomma(number) {
    if (typeof number == "undefined") { return ""; }
    return number.toString().replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,");
}

function loadExternalJS() {	    
    //load google analytics
    var gaURL = ("https:" == document.location.protocol ? "https://ssl." : "http://www.") + "google-analytics.com/ga.js";
    jQuery.getScript(gaURL, function() {
        try {
	  		var pageTracker = _gat._getTracker("UA-15176509-3");
	  		pageTracker._trackPageview();
		} catch(err) {} 
    });

}

/* assume timestamp in id */
function parseTableTime(node) {
    return node.id;
}

function parseTableInt(node) {
    return node.innerHTML.replace(/,/g, "");
}

function extractTimeOrInt(node) {
	if (node.className == "table_time") {
		return node.id;
	}
	else {
	    var innerHtml = node.innerHTML.replace(/,/g, "")
	    if(!(parseInt(innerHtml) > 0)) {
	        return "0";
	    }
	    else {
	        return innerHtml;
	    }
	}
}

function constructProtovisPlot(w, h, elem, x_label, y_label, x_label_help, y_label_help) {

	var vis = new pv.Panel()
	    .width(w)
	    .height(h)
	    .bottom(0)
	    .left(0)
	    .right(0)
		.canvas(elem)
	    .top(0);

    
	/* Axis labels */
	x_label = vis.add(pv.Label)
	    .right(20)
		.bottom(16)
		.textAlign("right")
		.text(x_label)
		.font("16px sans-serif");
	
	if (typeof x_label_help != "undefined") { 
    	x_label.add(pv.Image)
    	    .url(STATIC_URL+'images/help.png')
    	    .right(0)
    	    .bottom(16)
    	    .width(16)
    	    .height(16)
    		.text(x_label_help)
    		.event("mouseover", pv.Behavior.tipsy({gravity: "ne", fade: true}));
    		
    }
        
	y_label = vis.add(pv.Label)
		.left(0)
		.top(16)
		.textAlign("left")
		.text(y_label)
		.font("16px sans-serif");
		

	
	if (typeof y_label_help != "undefined") { 
        y_label.add(pv.Image)
            .left(100)
            .top(0)
    	    .url(STATIC_URL+'images/help.png')
            .width(16)
            .height(16)
            .text(y_label_help)
            .event("mouseover", pv.Behavior.tipsy({gravity: "w", fade: true}));
    }
    
	return vis;
}

function updateTcoLength() {
    $.get("/twitter/getTcoLength.json", {}, function(data) {
        $(window).data('Twitter.Configuration', data)
    }, 'json');
}

function getTcoLength() {
    return $(window).data('Twitter.Configuration') || {"short_url_length": 20, 
        "short_url_length_https": 21}
}

function getLengthAfterTco(text) {
    links = twttr.txt.extractUrls(text);
    var length = text.length;
    var tcoLengths = getTcoLength();
    var linkLength = parseInt(tcoLengths['short_url_length']);
    var linkLengthHttps = parseInt(tcoLengths['short_url_length_https']);
    for (var i in links) {
        length = length - links[i].length + (
            links[i].indexOf("https://") == 0? 
            linkLengthHttps : linkLength);
    }
    return length;
}


function computeCharsRemaining(textarea, label, buttonsToDisable, limit, useTco) {
    if (typeof useTco == 'undefined') { useTco = false; }
    var text = $(textarea).val();
    var charsRemaining = limit - (useTco? getLengthAfterTco(text) : text.length);
    $(label).html(charsRemaining);
    if (charsRemaining < 0) {
        $(label).addClass("red_text_bold");
        turnButtonOff($(buttonsToDisable));
        return false;
    }
    else if (charsRemaining == limit) {
        turnButtonOff($(buttonsToDisable));
        return false;
    }
    else {
        $(label).removeClass("red_text_bold");
        turnButtonOn($(buttonsToDisable));
        return true;
    }
}

/* Zero pad hours and minutes */
function zeroPadTimeNumber(number) {
    return (number < 10? "0" : "") + number;
}

function getFullMonthNameFromDate(date) {
    var monthNames = [ 
        "January", "February", "March", "April", "May", "June", 
        "July", "August", "September", "October", "November", "December" 
    ];
    
    return monthNames[date.getMonth()];
    
}

function getShortMonthNameFromDate(date) {
    var monthNames = [ 
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 
    ];
    return monthNames[date.getMonth()];
}

/*  Takes an 24-hour int [range 0-23] and returns a dictionary
    containing a 12-hour int and AM/PM */
function convertHour24to12(hour) {
    hour = parseFloat(hour);
    var ampm = 'AM';
    if (hour >= 12) {
        hour = hour - 12;
        ampm = 'PM';
    }
    if (hour == 0 ) {
        hour = 12;
    }
    return { 'hour': hour, 'ampm': ampm };
}

function convertHour12to24(hour, ampm) {
    hour = parseFloat(hour);
    if (ampm.toUpperCase() == 'PM') { hour += 12; }
    return hour;
}

function isValidDate(date) {
    if (Object.prototype.toString.call(date) !== "[object Date]") {
        return false;
    }
    return !isNaN(date.getTime());
}

function findAllUrls(text) {
    //Taken from http://daringfireball.net/2010/07/improved_regex_for_matching_urls
    var  urlRegex = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/gi;
    
    return text.match(urlRegex);
}

function isValidUrl(url) {
    return findAllUrls(url) != null;
}

function bitlyShortenLink(url, options) {
    options = $.extend({
        account: '',
        success: function() {},
        error: function() {}
    }, options);

    if (findAllUrls(url)) {
        $.post('/bitly/shortenLink', 
            {
                'url': url,
                'bitly_account': options.account
            },
            function(data) {
                if (data['success']) {
                    options.success({
                        'orig_url': url,
                        'created': data['created'],
                        'short_url': data['short_url']
                    });
                }
                else {
                    options.error(data);
                }
            },
            'json'
        );
    }
    else {
        options.error("Wasn't a valid url");
    }
}   

function getFormDataValue(formData, fieldName) {
    for (var i=0; i < formData.length; i++) {
        if (formData[i].name == fieldName) {
            return formData[i].value;
        }
    }
    return null;
}

function loadOverviewStats() {
    if ($("#dashboard_overview").size() > 0) {
        $("#dashboard_overview").load('/getOverviewStats/', function() {
            $(".overview_left, .overview_right").resizeTextToElem();
            $(".overview_stat").sameWidth();
        });

    }
}
function showWufoo(e) {
	e.preventDefault();
	centerElem("#wufoo");
	$("#wufoo_form_loading").show();
	$("#wufoo_form").html('<iframe id="wufoo_form_iframe" height="520" allowTransparency="true" frameborder="0" scrolling="no" style="width:100%;border:none"  src="https://conversely.wufoo.com/embed/p7x3a1/"><a href="https://conversely.wufoo.com/forms/p7x3a1/" title="Crowdbooster Beta Sign-up Form" rel="nofollow">Crowdbooster Beta Sign-up Form</a></iframe>');
	$("#wufoo_form_iframe").load(function() {
	    $("#wufoo_form_loading").hide();
	    $("#wufoo_form").fadeIn();
	})
	$("#wufoo").fadeIn();
}

function humanTime(theDate, currentDate) {
    try {
        theDate = theDate.replace(/\-/g,'\/');
        theDate = new Date(theDate);
    } catch (err) {
        return theDate;
    }

    try {
        currentDate = currentDate.replace(/\-/g,'\/');
        currentDate = new Date(currentDate);
    } catch(err) {
        currentDate = new Date();
    }
    //Get 00:00 tomorrow in user's time
    var tomorrowDate = new Date(currentDate.getTime());
    tomorrowDate.setDate(tomorrowDate.getDate()+1);
    tomorrowDate.setHours(0);
    tomorrowDate.setMinutes(0);
    tomorrowDate.setSeconds(0);
    tomorrowDate.setMilliseconds(0);

    var dayAfter = new Date(tomorrowDate.getTime())
    dayAfter.setDate(dayAfter.getDate()+1);

    var hours = theDate.getHours();
    var hoursDict = convertHour24to12(hours);

    var hourStr = ""+ hoursDict['hour'] + hoursDict['ampm'];

    // Month here is 0-11
    var month = theDate.getMonth() + 1;

    return hourStr + (theDate < tomorrowDate? " today" : (
        theDate < dayAfter? " tomorrow" : " on " + month + "/" + theDate.getDate()));

}

