// current settings
var timeSpanInfo = getStartDayInfo('12/2011', '2/2012');
var settings = {
	days: timeSpanInfo.days,
	startday: timeSpanInfo.startday,
	'words': 20,
	'postToWall': true,
	'postTopReblogs': true,
	'friendID': globals.userID
};

var statuses,
	cloud,
	reblogs,
	reblogCount,
	postData;
var firstPostDateline = globals.servertime.getTime()/1000;
var avatar = '';
var lastPost = 0;
var postCount = null;
var posts = [];

$(function(){
	// embed the generator even if we dont need it
	var flashvars = {
	};
	var params = {
		menu: 'false',
		allowscriptaccess: 'always',
		wmode: 'transparent'
	};
	var attributes = {
		id: 'cloudGenerator',
		name: 'cloudGenerator'
	};
	swfobject.embedSWF(globals.cdn + 'media/v' + globals.version + '/cloudGenerator.swf', 'cloudGenerator', 1, 1, '9.0.0','expressInstall.swf', flashvars, params, attributes);


	if (globals.userID > 0) {
	
		// check against Tumblr Uptime
		$.getJSON('http://tumblruptime.apigee.com/json?callback=?', function (response) {
			if (!response.methods['/api/read'].up || !response.methods['/oauth/write'].up) {
				$('#content-main-col').prepend('<div id="tumblr-api-warning" class="ui-state-highlight ui-corner-all" style="padding: .8em; margin-bottom: 2em; display: none; width: 65%; margin: 0 auto 20px;"><p><span style="float: left; margin-right: 0.3em;" class="ui-icon ui-icon-info"></span>Tumblr\'s API is currently broken, if you dont believe it then check out the <a href="http://tumblruptime.icodeforlove.com/" style="color: #00ACED; font-weight: bold;">Tumblr Uptime</a> page for more details. You should still try to use the service, but if it doesn\'t work you should come back later.</p></div>');
				$('#tumblr-api-warning').fadeIn().fadeOut().fadeIn();
			}
		});
		

		$("#days-header").html('look at blog posts between <span>' +  getDateString((globals.servertime.getTime()/1000) - (86400 * (settings.days))) + '<' + '/span> and <span>' + getDateString((globals.servertime.getTime()/1000) - (86400 * settings.startday)) + '<' + '/span>');
		$('#preview .example .title').text('This is a Tumblr Cloud I generated from my blog posts between ' +  getDateString((globals.servertime.getTime()/1000) - (86400 * (settings.days))) + ' and ' + getDateString((globals.servertime.getTime()/1000) - (86400 * settings.startday)) + ' containing my top ' + settings.words + ' used words.');

		// postToWall checkbox bindings
		$('#postToWall').bind('change', function(){
			settings.postToWall = $(this).is(':checked');
			
			if (settings.postToWall) {
				if (settings.postTopReblogs) $('#postTopReblogs').attr('checked','checked');
				$('#preview').css('color', '#3f3f3f');
				$('#preview .features').slideDown();
			} else {
				$('#postTopReblogs').removeAttr('checked','checked');
				$('#preview').css('color', '#cccccc');
				$('#preview .features').slideUp();
			}
		});
		
		$('#postTopReblogs').bind('change', function(){
			settings.postTopReblogs = $(this).is(':checked');
		});

		$('#start').val('12/2011');
		$('#end').val('2/2012');
		
		$('select').selectToUISlider({
			labels: 7,
			range: true,
			slide: function (e, ui) {
				var fieldset = $(e.target).parent();
				
				var startString = $('select:eq(0) option:eq(' + ui.values[0] + ')', fieldset).val();
				var endString = $('select:eq(0) option:eq(' + ui.values[1] + ')', fieldset).val();
				
				var timeSpanInfo = getStartDayInfo(startString, endString);
				settings.days = timeSpanInfo.days;
				settings.startday = timeSpanInfo.startday;
				
				$("#days-header").html('look at blog posts between <span>' +  getDateString((globals.servertime.getTime()/1000) - (86400 * (settings.days))) + '<' + '/span> and <span>' + getDateString((globals.servertime.getTime()/1000) - (86400 * settings.startday)) + '<' + '/span>');
		
				$('#preview .example .title').text('This is a Tumblr Cloud I generated from my blog posts between ' +  getDateString((globals.servertime.getTime()/1000) - (86400 * (settings.days))) + ' and ' + getDateString((globals.servertime.getTime()/1000) - (86400 * settings.startday)) + ' containing my top ' + settings.words + ' used words.');
		
				if (settings.days > 100) {
					$('#longwait-notice').fadeIn();
				} else {
					$('#longwait-notice').fadeOut();
				}
			}
		});
		
		// days-slider bindings
		$('#words-slider').slider({
			min: 2,
			max: 90,
			range: "min",
			value: settings.words,
			slide: function(event, ui) {
				settings.words = ui.value;

				if (ui.value > 1) {
					$("#words-header").html('show the top <span>' + settings.words + '<' + '/span> most used words in my cloud');
				} else {
					$("#words-header").html('show only the top used word in my cloud');
				}

				$('#preview .example .title').text('This is a Tumblr Cloud I generated from my blog posts between ' +  getDateString((globals.servertime.getTime()/1000) - (86400 * (settings.days))) + ' and ' + getDateString((globals.servertime.getTime()/1000) - (86400 * settings.startday)) + ' containing my top ' + settings.words + ' used words.');
			}
		});
		
		
		$('#create-cloud-form .submit-orange').bind('click', function(){
			$('#create-cloud-form .submit-orange').attr('disabled', 'true');
			$('#create-cloud-form .submit-orange').val('loading...');

			// tracking
			if (settings.postToWall) {
				_gaq.push(['_trackPageview', 'create_cloud_and_post']);
			} else {
				_gaq.push(['_trackPageview', 'create_cloud']);
			}


			addBlogPosts();
		});
	}
	autoPlaceFooter();
});

var setCloudImage = function (imageBase64) {

	if (settings.postToWall) {
		postData.imageBase64 = imageBase64;
		
		// create image
		$.ajax({
			type: 'POST',
			url:  'ajax.php',
			dataType: 'json',
			settings: settings.days,
			
			data: postData,
			
			success: function(json){
				switch ( json.code ) {
					case 1:
						window.location.href = globals.basedomain + json.userid + '/' + json.cloudid; 
						break;
					case 4:
						$('#preview .example .cloud-image').remove();
						$('#preview .example').css('height','auto');
						$('#cloud').html('<img src="data:image/png;base64,'+ json.image +'" />');
						break;
					case 5:
						alert(json.error);
						break;
				}
			},
			
			beforeSend: function(){
	
			},
			
			complete: function(){
				$('#create-cloud-form .submit-orange').removeAttr('disabled');
				$('#create-cloud-form .submit-orange').val('Generate my cloud');
				$('#overfifty-notice').fadeOut();
			}
		});
	} else {
		$('#cloud').html('<img src="data:image/jpeg;base64,'+ imageBase64 +'" />');
		$('#create-cloud-form .submit-orange').removeAttr('disabled');
		$('#create-cloud-form .submit-orange').val('Generate my cloud');
		$('#overfifty-notice').fadeOut();
		
		firstPostDateline = globals.servertime.getTime()/1000;
		avatar = '';
		lastPost = 0;
		postCount = null;
		console.log(posts);
		posts = [];
	}
	
	//$('#base64Image').attr('src','data:image/jpeg;base64, ' + imageBase64); 
	
	// post to wall
};

function processPosts (json) {
	lastPost += json.response.posts.length;
	
	var oldest = (globals.servertime.getTime()/1000) - (Math.floor(settings.days)*86400);
	var youngest = (globals.servertime.getTime()/1000) - (86400 * (Math.floor(settings.startday)));
	
	for (var i = 0; i < json.response.posts.length; i++) {
		var post = json.response.posts[i],
			text = '';


		if (post.timestamp < oldest) {
			crawlingComplete();
			return false;
		} else if (post.timestamp < youngest) {
			
			switch(post.type) {
				case 'text':
					text = post.title + ' ' + post.body;
					break;
				case 'quote':
					text = post.source + ' ' + post.text;
					break;
				case 'photo':
					if (!(post.caption.match("Ordered by most used:") || (typeof post.tags != 'undefined' && post.tags[0] == 'tumblrcloud'))) 
						text = post.caption;
					break;
				case 'link':
					text = post.description + ' ' + post.title;
					break;
				case 'chat':
					text = post.body + ' ' + post.title;
					break;
				case 'video':
					text = post.caption;
					break;
				case 'audio':
					text = post.caption;
					break;
				case 'answer':
					text = post.question + post.answer;
					break;
			}
			
			if (text.length > 0) posts.push(text);
		}
	}
	
	if (lastPost > 2000) {
		$('#overfifty-notice .count').text(lastPost);
		$('#overfifty-notice').fadeIn();
	}
	
	if (postCount == null) postCount = json.response.total_posts;
	
	if (lastPost < postCount) {
		addBlogPosts();
	} else {
		crawlingComplete();
		return;
	}
}

function addBlogPosts() {
	$.getJSON('http://api.tumblr.com/v2/blog/' + globals.tumblelog + '.tumblr.com/posts/text?api_key=PyezS3Q4Smivb24d9SzZGYSuhMNPQUhMsVetMC9ksuGPkK1BTt&jsonp=?&limit=2000&format=text&offset=' + lastPost, processPosts);
}







/*
var addBlogPosts = function (json) {
	if (!json) {
	
		// TODO:
		// use v2...
		// url: 'http://api.tumblr.com/v2/blog/' + globals.tumblelog + '.tumblr.com/posts/text?api_key=PyezS3Q4Smivb24d9SzZGYSuhMNPQUhMsVetMC9ksuGPkK1BTt&jsonp=?&limit=50&offset=0',
	
		// first time its been called
		//$.getJSON('http://' + globals.tumblelog + '.tumblr.com/api/read/json?callback=?&start=0&num=50', addBlogPosts);
		
		// fallback jsonp with three retries (this is horrible... but its tumblrs fault)
		$.jsonp({
			url: 'http://' + globals.tumblelog + '.tumblr.com/api/read/json?callback=?&start=0&num=50',
			success: addBlogPosts,
			error: function(xOptions, textStatus) {
				// retry 1
				$.jsonp({
					url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
					success: addBlogPosts,
					error: function (xOptions, textStatus) {
						// retry 2
						$.jsonp({
							url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
							success: addBlogPosts,
							error: function (xOptions, textStatus) {
								// retry 3
								$.jsonp({
									url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
									success: addBlogPosts
								});
							}
						});
					}
				});
			}
		});
		
		return false;
	}
	
	if (postCount === null) {
		// first time its returned with data
	    postCount = json['posts-total'] > 2000 ? 2000 : json['posts-total'];

		$.jsonp({
			url: 'http://' + globals.tumblelog + '.tumblr.com/api/read/json?callback=?&start=' + (json['posts-total']-1) + '&num=1',
			success: function (json) { firstPostDateline = json.posts[0]['unix-timestamp']; },
			error: function(xOptions, textStatus) {
				// retry 1
				$.jsonp({
					url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
					success: function (json) { firstPostDateline = json.posts[0]['unix-timestamp']; },
					error: function (xOptions, textStatus) {
						// retry 2
						$.jsonp({
							url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
							success: function (json) { firstPostDateline = json.posts[0]['unix-timestamp']; },
							error: function (xOptions, textStatus) {
								// retry 3
								$.jsonp({
									url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
									success: function (json) { firstPostDateline = json.posts[0]['unix-timestamp']; },
								});
							}
						});
					}
				});
			}
		});
	}
	
	var oldest = (globals.servertime.getTime()/1000) - (Math.floor(settings.days)*86400);
	var youngest = (globals.servertime.getTime()/1000) - (86400 * (Math.floor(settings.startday)));
	
	for (post in json['posts']) {
		if (json['posts'][post]['unix-timestamp'] < oldest) {
			crawlingComplete();
			return false;
		} else if (json['posts'][post]['unix-timestamp'] < youngest) {
			// process post, its young enough
			var text = '';
			switch(json['posts'][post].type) {
				case 'regular':
					text = json['posts'][post]['regular-title'] + ' ' + json['posts'][post]['regular-body'];
					break;
				case 'quote':
					text = json['posts'][post]['quote-source'] + ' ' + json['posts'][post]['quote-text'];
					break;
				case 'photo':
					if (json['posts'][post]['photo-caption'].match("Ordered by most used:") || (typeof json['posts'][post].tags != 'undefined' && json['posts'][post].tags[0] == 'tumblrcloud')) {
						// do not parse this
					} else {
						text = json['posts'][post]['photo-caption'];
					}
					break;
				case 'link':
					text = json['posts'][post]['link-description'] + ' ' + json['posts'][post]['link-text'];
					break;
				case 'conversation':
					text = json['posts'][post]['conversation-text'] + ' ' + json['posts'][post]['conversation-title'];
					break;
				case 'video':
					text = json['posts'][post]['video-caption'];
					break;
				case 'audio':
					
					break;
			}
			
			if (text.length > 0) posts.push(text);
		}
	}

	if (lastPost > 50) {
		$('#overfifty-notice .count').text(lastPost);
		$('#overfifty-notice').fadeIn();
	}

	if (postCount > lastPost) {
		// continue crawling posts
		lastPost += 50;
		//$.getJSON('http://' + globals.tumblelog + '.tumblr.com/api/read/json?callback=?&start=' + lastPost + '&num=50', addBlogPosts);
		
		// fallback jsonp with three retries (this is horrible... but its tumblrs fault)
		$.jsonp({
			url: 'http://' + globals.tumblelog + '.tumblr.com/api/read/json?callback=?&start=' + lastPost + '&num=50',
			success: addBlogPosts,
			error: function(xOptions, textStatus) {
				// retry 1
				$.jsonp({
					url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
					success: addBlogPosts,
					error: function (xOptions, textStatus) {
						// retry 2
						$.jsonp({
							url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
							success: addBlogPosts,
							error: function (xOptions, textStatus) {
								// retry 3
								$.jsonp({
									url: xOptions.url.replace(/callback=\?/, 'callback=' + xOptions.callback),
									success: addBlogPosts
								});
							}
						});
					}
				});
			}
		});
	} else {
		// we have crawled all of the users posts
		crawlingComplete();
	}
};
*/

var blacklistedWords = {'tumblr': 1, 'about': 1, 'above': 1, 'across': 1, 'after': 1, 'again': 1, 'against': 1, 'almost': 1, 'alone': 1, 'along': 1, 'already': 1, 'also': 1, 'although': 1, 'always': 1, 'among': 1, 'another': 1, 'anybody': 1, 'anyone': 1, 'anything': 1, 'anywhere': 1, 'area': 1, 'areas': 1, 'around': 1, 'asked': 1, 'asking': 1, 'asks': 1, 'away': 1, 'back': 1, 'backed': 1, 'backing': 1, 'backs': 1, 'became': 1, 'because': 1, 'become': 1, 'becomes': 1, 'been': 1, 'before': 1, 'began': 1, 'behind': 1, 'being': 1, 'beings': 1, 'best': 1, 'better': 1, 'between': 1, 'both': 1, 'came': 1, 'cannot': 1, 'case': 1, 'cases': 1, 'certain': 1, 'certainly': 1, 'clear': 1, 'clearly': 1, 'come': 1, 'could': 1, 'differ': 1, 'different': 1, 'differently': 1, 'does': 1, 'done': 1, 'down': 1, 'down': 1, 'downed': 1, 'downing': 1, 'downs': 1, 'during': 1, 'each': 1, 'early': 1, 'either': 1, 'ended': 1, 'ending': 1, 'ends': 1, 'enough': 1, 'even': 1, 'evenly': 1, 'ever': 1, 'every': 1, 'everybody': 1, 'everyone': 1, 'everything': 1, 'everywhere': 1, 'face': 1, 'faces': 1, 'fact': 1, 'facts': 1, 'felt': 1, 'find': 1, 'finds': 1, 'first': 1, 'four': 1, 'from': 1, 'full': 1, 'fully': 1, 'further': 1, 'furthered': 1, 'furthering': 1, 'furthers': 1, 'gave': 1, 'general': 1, 'generally': 1, 'gets': 1, 'give': 1, 'given': 1, 'gives': 1, 'going': 1, 'good': 1, 'goods': 1, 'great': 1, 'greater': 1, 'greatest': 1, 'group': 1, 'grouped': 1, 'grouping': 1, 'groups': 1, 'have': 1, 'having': 1, 'here': 1, 'herself': 1, 'high': 1, 'high': 1, 'high': 1, 'higher': 1, 'highest': 1, 'himself': 1, 'however': 1, 'important': 1, 'interest': 1, 'interested': 1, 'interesting': 1, 'interests': 1, 'into': 1, 'itself': 1, 'just': 1, 'keep': 1, 'keeps': 1, 'kind': 1, 'knew': 1, 'know': 1, 'known': 1, 'knows': 1, 'large': 1, 'largely': 1, 'last': 1, 'later': 1, 'latest': 1, 'least': 1, 'less': 1, 'lets': 1, 'like': 1, 'likely': 1, 'long': 1, 'longer': 1, 'longest': 1, 'made': 1, 'make': 1, 'making': 1, 'many': 1, 'member': 1, 'members': 1, 'might': 1, 'more': 1, 'most': 1, 'mostly': 1, 'much': 1, 'must': 1, 'myself': 1, 'necessary': 1, 'need': 1, 'needed': 1, 'needing': 1, 'needs': 1, 'never': 1, 'newer': 1, 'newest': 1, 'next': 1, 'nobody': 1, 'noone': 1, 'nothing': 1, 'nowhere': 1, 'number': 1, 'numbers': 1, 'often': 1, 'older': 1, 'oldest': 1, 'once': 1, 'only': 1, 'open': 1, 'opened': 1, 'opening': 1, 'opens': 1, 'order': 1, 'ordered': 1, 'ordering': 1, 'orders': 1, 'other': 1, 'others': 1, 'over': 1, 'part': 1, 'parted': 1, 'parting': 1, 'parts': 1, 'perhaps': 1, 'place': 1, 'places': 1, 'point': 1, 'pointed': 1, 'pointing': 1, 'points': 1, 'possible': 1, 'present': 1, 'presented': 1, 'presenting': 1, 'presents': 1, 'problem': 1, 'problems': 1, 'puts': 1, 'quite': 1, 'rather': 1, 'really': 1, 'right': 1, 'right': 1, 'room': 1, 'rooms': 1, 'said': 1, 'same': 1, 'says': 1, 'second': 1, 'seconds': 1, 'seem': 1, 'seemed': 1, 'seeming': 1, 'seems': 1, 'sees': 1, 'several': 1, 'shall': 1, 'should': 1, 'show': 1, 'showed': 1, 'showing': 1, 'shows': 1, 'side': 1, 'sides': 1, 'since': 1, 'small': 1, 'smaller': 1, 'smallest': 1, 'some': 1, 'somebody': 1, 'someone': 1, 'something': 1, 'somewhere': 1, 'state': 1, 'states': 1, 'still': 1, 'still': 1, 'such': 1, 'sure': 1, 'take': 1, 'taken': 1, 'than': 1, 'that': 1, 'their': 1, 'them': 1, 'then': 1, 'there': 1, 'therefore': 1, 'these': 1, 'they': 1, 'thing': 1, 'things': 1, 'think': 1, 'thinks': 1, 'this': 1, 'those': 1, 'though': 1, 'thought': 1, 'thoughts': 1, 'three': 1, 'through': 1, 'thus': 1, 'today': 1, 'together': 1, 'took': 1, 'toward': 1, 'turn': 1, 'turned': 1, 'turning': 1, 'turns': 1, 'under': 1, 'until': 1, 'upon': 1, 'used': 1, 'uses': 1, 'very': 1, 'want': 1, 'wanted': 1, 'wanting': 1, 'wants': 1, 'ways': 1, 'well': 1, 'wells': 1, 'went': 1, 'were': 1, 'what': 1, 'when': 1, 'where': 1, 'whether': 1, 'which': 1, 'while': 1, 'whole': 1, 'whose': 1, 'will': 1, 'with': 1, 'within': 1, 'without': 1, 'work': 1, 'worked': 1, 'working': 1, 'works': 1, 'would': 1, 'year': 1, 'years': 1, 'young': 1, 'younger': 1, 'youngest': 1, 'your': 1, 'yours': 1, 'dont': 1, 'thats': 1, 'youre': 1, 
/* stupid replacemnts */
'(via': 1, 'didn': 1, 'http': 1, 'wasn': 1, 'doesn': 1,
/* auxiliary verbs */
'am': 1, 'arent': 1, 'aint': 1, 'im': 1, 'are': 1, 'arent': 1, 'aint': 1, 'be': 1, 'been': 1, 'can': 1, 'cant': 1, 'could': 1, 'couldnt': 1, 'did': 1, 'didnt': 1, 'do ': 1, 'dont': 1, 'does': 1, 'doesnt': 1, 'had': 1, 'hadnt': 1, 'has': 1, 'hasnt': 1, 'have': 1, 'havent': 1, 'ive': 1, 'is': 1, 'isnt': 1, 'may': 1, 'maynt': 1, 'might': 1, 'mightnt': 1, 'must': 1, 'mustnt': 1, 'ought': 1, 'oughtnt': 1, 'shall': 1, 'shant': 1, 'should': 1, 'shouldnt': 1, 'was': 1, 'wasnt': 1, 'were': 1, 'werent': 1, 'will': 1, 'wont': 1, 'would': 1, 'wouldnt': 1, 'shes': 1, 'hes': 1, 'she': 1, 'he': 1, 'shell': 1, 'id': 1,
/* error words */
'null': 1
};

var crawlingComplete = function () {
	cloud = {};
	reblogs = {};
	reblogCount = 0;
	
	var tumblelogRegex = /<a href="[^"]*tumblr[^"]*"[^>]*>([a-z0-9-_]+)<\/a>\:?/gi;
	var tumblelogViaRegex = /\(via <a href="[^"]+"[^>]*>([a-z0-9-_]+)<\/a>\:?\)/gi;
	
	for (var i = 0, len = posts.length; i < len; i++) {
			var html = posts[i];
			var original = true;
			
			while (match = tumblelogRegex.exec(html))
			{
				if (match[1] == globals.tumblelog) continue;
				if (match[1].match(/(post|photo)/i)) continue;
				
				if (typeof reblogs[match[1]] != 'undefined') {
					reblogs[match[1]]++;
				} else {
					reblogs[match[1]] = 1;
				}
				if (original) {
					reblogCount++;
					original = false;
				}
			}
			
			while (match = tumblelogViaRegex.exec(html))
			{
				if (match[1] == globals.tumblelog) continue;
				if (match[1].match(/(post|photo)/i)) continue;
				
				if (typeof reblogs[match[1]] != 'undefined') {
					reblogs[match[1]]++;
				} else {
					reblogs[match[1]] = 1;
				}
				if (original) {
					reblogCount++;
					original = false;
				}
			}
			
			html = html.replace(tumblelogRegex, '');
			html = html.replace(tumblelogViaRegex, '');
			var textBlob = html.replace(/<\/?[^>]+(>|$)/g, '')
			.toLowerCase()
			.replace(/((ht|f)tp(s?):\/\/)(([a-z0-9]([a-z0-9]|-)*[a-z0-9]|[a-z0-9])\.)+([a-z]([a-z0-9]|-)*[a-z0-9]|[a-z])(\/([a-z0-9\.!$&'\(\)*+,;=_~:@-]|%[a-f0-9]{2})*)*(\?[a-z0-9\.!$&'\(\)*+,;=_~:@\/?-]*)?(\#[a-z0-9\.!$&'\(\)*+,;=_~:@\/?-]*)?/g, '')
			.replace(/[\ï\Í\'\(\)\:]/ig, '')
			.replace(/[^a-z0-9\-\_]+/ig, ' ')
			.replace(/  /ig, ' ')
			.replace(/ [0-9]+ /ig, '');
			
			
			var initial_words_array = textBlob.split(' ');
			var new_textBlob = textBlob;
			var popularity = {};
		
			var _i;
			for (_i in initial_words_array) {
				if (typeof popularity[initial_words_array[_i]] != 'undefined') {
					popularity[initial_words_array[_i]].count++;
					popularity[initial_words_array[_i]].points += Math.floor(10 / (popularity[initial_words_array[_i]].count+2));
				} else {
					if (initial_words_array[_i].length > 3 && typeof blacklistedWords[initial_words_array[_i]] == 'undefined') {
						popularity[initial_words_array[_i]] = {
							count: 1,
							word: initial_words_array[_i],
							points: 10
						};
					}
				}
			}
		
			var _i;
			for (_i in popularity) {
				if (typeof cloud[popularity[_i].word] != 'undefined') {
					cloud[popularity[_i].word].count += popularity[_i].count;
					cloud[popularity[_i].word].points += popularity[_i].points;
				} else {
					cloud[popularity[_i].word] = {
						count: popularity[_i].count,
						word: popularity[_i].word,
						points: popularity[_i].points
					};
				}
			}
	}
	
	var sortedArray = [];
	var i;
	for (i in cloud) {
		sortedArray.push(cloud[i]);
	}
	
	// sort array
	usort(sortedArray, function (a, b) {return (a.points > b.points) ? +1 : -1;});

	// chop the set up
	var wordsToReturn = settings.words;
	var total_words = 0;
	var total_points = 0;
	var words = [];
	for (var i = 0, len = sortedArray.length; i < len && i < wordsToReturn; i++) {
		var word = sortedArray.pop();
		words.push(word);
		total_words += word.count;
		total_points += word.points;
	}
	
	for (var i = 0, len = words.length; i < len; i++) {
		words[i].percent = words[i].points / total_points;
	};
	
	// sort reblogs
	var reblogsSortable = [];
	for (reblog in reblogs) {
		reblogsSortable.push({
			username: reblog,
			count: reblogs[reblog]
		});
	}
	usort(reblogsSortable, function (a, b) {return (a.count < b.count) ? +1 : -1;});
	reblogsSortable = reblogsSortable.slice(0,10);
	
	// create stringify object
	var stringified = {};
	stringified.words = [];
	stringified.count = [];
	stringified.percent = [];
	stringified.reblogs = [];
	
	for (var i = 0, len = words.length; i < len; i++) {
		stringified.words.push(words[i].word);
		stringified.count.push(words[i].count);
		stringified.percent.push(words[i].percent);
	}
	
	for (var i = 0, len = reblogsSortable.length; i < len; i++) {
		stringified.reblogs.push(reblogsSortable[i].username);
	}
	
	postData = {};
//	var i;
//	for (i in userInfo) postData[i] = userInfo[i];
	
	postData.method = 'create.cloud';
	postData.postToWall = settings.postToWall;
	postData.postTopReblogs = settings.postTopReblogs;
	postData.friendID = settings.friendID;
	postData.max = settings.words;
	postData.startday = settings.startday;
	postData.days = settings.days;
	postData.words = stringified.words.join(',');
	postData.count = stringified.count.join(',');
	postData.percent = stringified.percent.join(',');
	postData.reblogs = stringified.reblogs.join(',');
	postData.totalPosts = posts.length;
	postData.totalReblogs = reblogCount;
	
	var daysRegistered = ((globals.servertime.getTime()/1000) - firstPostDateline) / 86400;
	var postsPerDay = parseInt(postCount)/daysRegistered;
	var selectionPostPerDay = posts.length/(settings.days-settings.startday);
	var postFrequencyChange = Math.ceil((selectionPostPerDay/postsPerDay)*100) - 100;

	$('#cloudGenerator')[0].createCloudPost([
		globals.tumblelog, 
		globals.profile_picture.match(/avatar_([a-z0-9]+)_/i) ? globals.profile_picture.match(/avatar_([a-z0-9]+)_/i)[1] : 'default_avatar', 			
		postData.words,
		postData.count, 
		posts.length, 
		postFrequencyChange, 
		reblogCount, 
		posts.length-reblogCount, 
		((globals.servertime.getTime()/1000) - (settings.days*86400)) * 1000, 
		((globals.servertime.getTime()/1000) - (settings.startday*86400)) * 1000
	].join('|'));
	
};

			
/*
* usort
*/
var usort = function (inputArr, sorter) { 
	var valArr = [];
	var k = '', i = 0;
 
	if (typeof sorter === 'string') {
		sorter = this[sorter];
	} else if (sorter instanceof Array) {
		sorter = this[sorter[0]][sorter[1]];
	}
	for (k in inputArr) {
		valArr.push(inputArr[k]);
		delete inputArr[k];
	}
	try {
		valArr.sort(sorter);
	} catch (e) {
		return false;
	}
	for (i = 0; i < valArr.length; i++) {
		inputArr[i] = valArr[i];
	}
 
	return true;
};


var getDateString = function (timestamp) {
    var date = new Date(timestamp * 1000);
    var monthNames = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
    
    //return monthNames[date.getMonth()] + ' ' + getSuffixWithNumber(date.getDate()) + ' ' + date.getFullYear();
    return monthNames[date.getMonth()] + ' ' + date.getFullYear();
}

var getSuffixWithNumber = function ($n){
	var n=$n+'';
	var l=n.length, r=parseInt(n.substring(l-2,l)), i = n % 10;
	return $n + (((r < 11 || r > 19) && (i < 4)) ? ['th','st','nd','rd'][i] : 'th');
}

function getStartDayInfo (startString, endString) {
	var start = new Date();
	start.setMonth(parseInt(startString.split('/')[0])-1);
	start.setFullYear(parseInt(startString.split('/')[1]));
	start.setDate(1);
	start.setHours(0);
	start.setMinutes(0);
	start.setSeconds(0);
	start.setMilliseconds(0);

	var end = new Date();
	end.setMonth(parseInt(endString.split('/')[0])-1);
	end.setFullYear(parseInt(endString.split('/')[1]));
	end.setHours(0);
	end.setMinutes(0);
	end.setSeconds(0);
	end.setMilliseconds(0);
	
	var startday = (new Date().getTime() - end.getTime())/86400000;
	var days = (new Date().getTime() - start.getTime())/86400000;
	
	return {
		startday: startday,
		days: days
	};
}

