
function TagCloud(data, callback) { 
	
	this._callback = callback;
	
	
	//////// massage the tag data
	
	var tagMap = {};
	
	var work = data.work,
		education = data.education;
	
	var thisWork, start, end, timeDelta, tags;
	for(var name in work) {
		thisWork = work[name];
		thisWork = (thisWork instanceof Array) ? thisWork : [thisWork];
		
		for(var i=0; i<thisWork.length; i++) {
			
			start = thisWork[i].date.start;
			end = thisWork[i].date.end;
			
			start = new Date(start);
			end = (end) ? (new Date(end)) : (new Date());
			
			timeDelta = Utils.getUnixTimestamp(end) - Utils.getUnixTimestamp(start);
			
			tags = thisWork[i].tags;
			for(var keyword in tags) {
				if(!(keyword in tagMap)) { tagMap[keyword] = 0; }
				tagMap[keyword] += tags[keyword] * timeDelta;
			}
		}
	}
	
	var thisEducation, courses, thisCourse, thisDate, timeDelta, start, end, tags;
	for(var name in education) {
		
		thisEducation = education[name];
		courses = thisEducation.courses;
		for(var i=0; i<courses.length; i++) {
			
			thisCourse = courses[i];
			thisDate = thisCourse.date;
			thisDate = (thisDate instanceof Array) ? thisDate : [thisDate];
			
			timeDelta = 0;
			for(var j=0; j<thisDate.length; j++) {
				
				start = thisDate[j].start;
				end = thisDate[j].end;
				
				start = new Date(start);
				end = (end) ? (new Date(end)) : (new Date());
				
				timeDelta += (Utils.getUnixTimestamp(end) - Utils.getUnixTimestamp(start));
			}
			
			tags = thisCourse.tags;
			for(var keyword in tags) {
				if(!(keyword in tagMap)) { tagMap[keyword] = 0; }
				tagMap[keyword] += tags[keyword] * timeDelta;
			}
		}
		
	}
	
	this._tags = tagMap;
}

TagCloud.prototype.steps = 5;
TagCloud.prototype.init = function() {
	
	var cloud = $("#tagCloud");
	
	var tagArray = [];
	var min = null, max = null;
	var tags = this._tags;
	for(var keyword in tags) {
		
		min = (min == null)
			? tags[keyword]
			: Math.min(tags[keyword], min);
		
		max = (max == null)
			? tags[keyword]
			: Math.max(tags[keyword], max);
		
		tagArray.push({ 
			tag : keyword, 
			size : tags[keyword]
		});
		
	}
	
	tagArray.sort(function(a,b) { 
		return (a.tag > b.tag) ? 1 : (b.tag > a.tag ) ? -1 : 0;
	}); 
	
	var stepSize = (max - min)/this.steps;
	
	for(var i=0; i<tagArray.length; i++) {
		
		cloud.append(
			$.create("a", {href:"javascript:void(0)", keyword:tagArray[i].tag }, tagArray[i].tag)
				.css({ 'font-size' : (75+(Math.floor((tagArray[i].size - min)/stepSize)*30)) + '%' })
		);
		cloud.append(" ")
	}
	
	
	var self = this;
	$("#tagCloud a[keyword]").live('click', function(e, automated) {
		
		e.preventDefault();
		e.stopPropagation();
		
		$("#tagCloud a[keyword]").removeClass("active");
		$(this).addClass('active');
		
		if(!automated) { self.cancelAutoplay(); }
		
		var keyword = this.getAttribute("keyword");
		var numInstances = this.getAttribute("instances");
		
		self._callback(keyword, e.ctrlKey || e.metaKey);
		
	});
}

TagCloud.prototype.cancelAutoplay = function() {}
TagCloud.prototype.autoplay = function() {
	
	var index = 0;
	var links = $("#tagCloud a[keyword]");
	
	var rotate = function() {
		
		if(_Bar.OnHover) { return; }
		$(links[index%links.length]).trigger("click", true /* automated */);
		index++;
	}
	
	var timer = setInterval(rotate, 5500);
	this.cancelAutoplay = function() { clearInterval(timer); }

	rotate();	
}
