/*
	TweetShow 18 okt 2011, 09:41 - WJ

	TweetShow is an instanceable javascript class that gets a set of tweets, displays them	according to a simple
	custom HTML template, and appends the resultant HTML to a supplied element.

	TweetShow is based on the Twitter Search API, though it's not much more than just querying an url with a few search parameter.

	On construction, it takes the argument mapOptions, which has the following fields. *marked fields are required.
	{
		*url				string	url where to get the tweets from, in JSON format. By default, a file called ajax_twitter_json.asp should be present in /snippets/
		*user				string	the username from which to query the tweets, formatted as a from: search parameter.
		query				string	extra search parameters according to the Twitter API. These will be appended to the username parameter with AND.
		top				int		limit results to a most recent number of tweets. When left empty, TweetShow will try to get them all.
		*metaTemplate	string	the htmltemplate to be used for the items. May contain replace-tags for the actual content.
		*itemTemplate	string	the htmltemplate for extra information such as the twitter icon and username. May contain replace-tags for the actual content.
		*rootElement	jQuery	the element that will contain the output HTML. HTML will be appended to already existing children, if any.
		onload			func		optional callback function to execute after the entire html has been placed. Currently provdes no handy access to the original tweetshow instance.
	}

	todo:
		inside load callback: provide access to relevant portions of the instance, such as the root element and/or the items etc.
*/
function TweetShow(mapOptions) {
   var _self = this;
   var posturl;
   var results = [];
   var formattedResults = [];

   if (mapOptions.url) {
		posturl = mapOptions.url;
   }
	else {
		posturl = '/templates/snippets/ajax_twitter_json.asp';
	}

   posturl += '?q=from:'+ mapOptions.user;

   if (mapOptions.query) {
      posturl += escape(' AND '+ mapOptions.query);
   }

   if (!mapOptions.top) {
      mapOptions.top = 20;
   }

   ////////////

   _self.start = function () {
      jQuery.getJSON(
         posturl,
         function (jsonData, status, xhr) {
            results = jsonData.results;

            _self.formatResults();
            _self.displayContent();
         }
      );
   }

   _self.formatResults = function () {
      var baseurl = 'http://twitter.com/';
      var dtNow = new Date();
      var limitCount = Math.min(results.length, parseInt(mapOptions.top));

      for (var i=0; i < limitCount; i++) {
         //replace mentions and tags with links
         results[i].text = results[i].text.replace(/(^| )(http:\/\/[^ ]+)($| )/ig, ' <a href="$2" class="tweet_link">$2</a> ');
         results[i].text = results[i].text.replace(/(@([a-z_\d]+))/ig, ' <a href="'+ baseurl +'$2" class="tweet_userlink">$1</a> ');
         results[i].text = results[i].text.replace(/(#([a-z\d]+))/ig, ' <a href="'+ baseurl +'#!/search?q=%23$2" class="tweet_tag">$1</a> ');

         var dtCreated = new Date(results[i].created_at);
         var diffTime = dtNow.getTime() - dtCreated.getTime();
         var humanTime = getHumanTimeInterval(diffTime, dtCreated);

         formattedResults.push({
            user: results[i].from_user + ':',
            user_url: baseurl + results[i].from_user,
            user_icon: results[i].profile_image_url,
            text: results[i].text,
            date: humanTime +' '+ Globals.langfields.ago
         });
      }
   }
   _self.displayContent = function () {
      _html = '';

      if (formattedResults.length == 0) {
         return;
      }

      _html += mapOptions.metaTemplate
         .replace(/@username/g, mapOptions.user)
         .replace(/@user_icon/g, formattedResults[0].user_icon)
         .replace(/@followcount/g, '9999');

      for (var i=0; i < formattedResults.length; i++) {
         _html += mapOptions.itemTemplate
            .replace(/@text/g, formattedResults[i].text)
            .replace(/@date/g, formattedResults[i].date);
      }

      mapOptions.rootElement.html( mapOptions.rootElement.html() + _html );

		//fire onload event
		if (typeof mapOptions.onload == 'function') {
			mapOptions.onload();
		}
   }
}

/* string getHumanTimeInterval
   in: difftime in milliseconds; fallback date if the time interval is too large.

   returns a labeled time since now, e.g. "5 seconds ago", "3 days ago".
*/
function getHumanTimeInterval(milliseconds, fallbackDate) {
   var humanTime;
   //console.log('ms', milliseconds);

   humanTime = milliseconds / (1000);
   //console.log('ht', humanTime);

   if (humanTime < 60) {
      return Math.floor(humanTime) + ' seconden';
   }

   humanTime = milliseconds / (1000 * 60);
   //console.log('ht', humanTime);

   if (humanTime < 60) {
      return Math.floor(humanTime) + ' minuten';
   }

   humanTime = milliseconds / (1000 * 60 * 60);
   //console.log('ht', humanTime);

   if (humanTime < 60) {
      return Math.floor(humanTime) + ' uur';
   }

   humanTime = milliseconds / (1000 * 60 * 60 * 24);
   //console.log('ht', humanTime);

   if (humanTime < 24) {
      return Math.floor(humanTime) + ' dagen';
   }

   humanTime = milliseconds / (1000 * 60 * 60 * 24 * 7);
   //console.log('ht', humanTime);

   if (humanTime < 7) {
      return Math.floor(humanTime) + ' weken';
   }

   return  fallBackDate.getDate() +' '+ (fallBackDate.getMonth() + 1) +' '+ fallBackDate.getFullYear() +', '
      + fallBackDate.getHours() +':'+ fallBackDate.getMinutes();
}
