if (typeof shnap === 'undefined') {
	shnap = {};
}
shnap.constants = shnap.constants || {};
shnap.constants.SLOW_FADE = 1000;
shnap.constants.FAST_FADE = 250;

shnap.sanitize = function(aString) {
	return aString.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
};

shnap.timeDescription = function(timestamp) {
	var now = (new Date()).getTime()/1000;
	var diff = now - timestamp;
	var daysDiff = Math.floor((now-timestamp)/86400);
	if (daysDiff > 0) {
		return (daysDiff==1)? '1 day ago' : daysDiff + ' days ago';
	}
	return 'Hours ago';
};

shnap.Size = function(width, height) {
	this.width = width;
	this.height = height;
};

shnap.Stat = function(title, count, percent, fractionOfMax) {
	this.title = title;
	this.count = count;
	this.percent = percent;
	this.fractionOfMax = fractionOfMax;
};

shnap.StatBubble = function() {
	this.divElement = $('<div>');
	this.divElement.attr('class', 'stat-bubble');
	
	this.bubbleTitle = $('<div>');
	this.bubbleTitle.addClass('stat-bubble-label');
	this.divElement.append(this.bubbleTitle);
	
	this.bubbleCount = $('<div>');
	this.bubbleCount.addClass('stat-bubble-count');
	this.divElement.append(this.bubbleCount);
	
	this.bubblePercent = $('<div>');
	this.bubblePercent.addClass('stat-bubble-percent');
	this.divElement.append(this.bubblePercent);
    
    this.divElement.mouseenter(function() {
    	$(this).css('-webkit-transform', 'scale(1.0)');
        $(this).css('-moz-transform', 'scale(1.0)');
        $(this).stop().animate({'pulse': 1.0}, 250);
    });
};

shnap.StatBubble.prototype.div = function() {
	return this.divElement;
};

shnap.StatBubble.prototype.renderStat = function(stat, animated, containerHeight) {
	containerHeight = containerHeight || 215;
	animated = (animated===undefined)? true : animated;
	
	this.bubbleTitle.html(stat.title);
	this.bubbleCount.html(stat.count);
	this.bubblePercent.html(Math.round(100*stat.percent)+'%');
    
	var offset = containerHeight - 70;
    	
	if (animated) {
		if (!$.browser.msie) {
			this.divElement.animate(
				{ bottom: offset*stat.fractionOfMax+'px',
					opacity: 0.5+stat.fractionOfMax/2
				}, 500,
				function (x, t, b, c, d) {
					return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
				}
			);
	    } else {
	    	// Don't modulate opacity for IE
			this.divElement.animate(
				{ bottom: offset*stat.fractionOfMax+'px' }, 500,
				function (x, t, b, c, d) {
					return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
				}
			);
	    }
	} else {
		this.divElement.css('bottom', offset*stat.fractionOfMax+'px');
		this.divElement.css('opacity', 0.5+stat.fractionOfMax/2);
	}

};

shnap.adjustForBounds = function(originalSize, outputSize) {
	var ar = originalSize.width/originalSize.height;
	var target_ar = outputSize.width/outputSize.height;
	if (ar > target_ar) {
    outputSize.width = outputSize.width;
    outputSize.height = Math.floor(outputSize.width/ar);
  } else {
    outputSize.height = outputSize.height;
    outputSize.width = Math.floor(outputSize.height*ar);
  }
};

shnap.calculateStats = function(labels, responses) {
	var totalResponses = 0;
	var maxCount = 0;
	var percent = 0.0;
	var maxFraction = 0.0;
	var stats = [];
	var i, stat;
	
	for (i=1; i<responses.length; i++) {
		totalResponses += responses[i];
		if (responses[i] > maxCount) {
			maxCount = responses[i];
		}
	}
	
	for (i=0; i<responses.length; i++) {
		response = responses[i];
		if (totalResponses > 0) {
			percent = response/totalResponses;
			maxFraction = response/maxCount;
		} else {
			percent = 0.0;
			maxFraction = 0.0;
		}
		stat = new shnap.Stat(labels[i], response, percent, maxFraction);
		stats.push(stat);
	}
	return {stats:stats, totalResponses:totalResponses};
};


shnap.setUpBasePage = function() {

	var linkStepFn = function(now, fx) {
		// Change color along with opacity (1.0 - white, 0.5 - pink)
		var value = Math.floor(207+(255-207)*(now-0.5)*2);
		$(fx.elem).css('color', 'rgb(255,'+value+','+value+')');
	};	
	$('a.fadeable').hover(
		function() {
            $(this).stop().animate({opacity: 0.5}, {step:linkStepFn, duration:250});
		},
        function() {
            $(this).stop().animate({opacity: 1.0}, {step:linkStepFn, duration:250});
        }
    );
    
    var dlLinkFn = function(now, fx) {
        // Opacity goes from 1.0 to 0.9 as color goes from (255,32,32) to (255,208,208)
        var value = Math.floor(32+(208-32)*(1-now)*10);
        $(fx.elem).css('color', 'rgb(255,'+value+','+value+')');
    };
    if (!$.browser.msie) {
	    $('a.download-link').hover(
			function() {
	            $(this).stop().animate({opacity: 0.9}, {step:dlLinkFn, duration:250});
			},
	        function() {
	            $(this).stop().animate({opacity: 1.0}, {step:dlLinkFn, duration:250});
	        }
	    );
    }
};
