/**
 * remy sharp / http://remysharp.com
 * Twitter / @rem
 * http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/
 *
 * @params
 *   cssIdOfContainer: e.g. twitters
 *   options: 
 *       {
 *           id: {String} username,
 *           count: {Int} 1-20, defaults to 1 - max limit 20
 *           prefix: {String} '%name% said', defaults to blank
 *           clearContents: {Boolean} true, removes contents of element specified in cssIdOfContainer, defaults to true
 *           ignoreReplies: {Boolean}, skips over tweets starting with '@', defaults to false
 *           template: {String} HTML template to use for LI element (see URL above for examples), defaults to predefined template
 *           enableLinks: {Boolean} linkifies text, defaults to true,
 *           newwindow {Boolean} opens links in new window, defaults to false
 *           timeout: {Int} How long before triggering onTimeout, defaults to 10 seconds if onTimeout is set
 *           onTimeoutCancel: {Boolean} Completely cancel twitter call if timedout, defaults to false
 *           onTimeout: {Function} Function to run when the timeout occurs. Function is bound to element specified with 
 *           cssIdOfContainer (i.e. 'this' keyword)
 *           callback: {Function} Callback function once the render is complete, doesn't fire on timeout
 *
 *      CURRENTLY DISABLED DUE TO CHANGE IN TWITTER API:
 *           withFriends: {Boolean} includes friend's status
 *
 *       }
 *
 * @license MIT (MIT-LICENSE.txt)
 * @version 1.13.1 - Number of fixes to ify, and fixed date parsing in Opera and 12AM issue
 * @date $Date: 2009-10-02 15:15:57 +0200 (Fri, 02 Oct 2009) $
 */

longUrl = function( url, respondTo ) {
	if( longUrl.cache[url] || longUrl.cache[url] == false ) 
	{
		respondTo( longUrl.cache[url] );
	}
	jQuery.ajax({
		type: 'GET',
		url: 'http://api.longurl.org/v1/expand',
		data: {format: 'json', url: url},
		dataType: 'jsonp',
	
		success: function(data, responseText) {
			if (typeof(data.messages) !== 'undefined') { // There was an error
				this.error();
			} else {
				respondTo( longUrl.cache[url] = data.long_url );
			}
		},
		error: function() {
			respondTo( longUrl.cache[url] = url );
		}
	});
}
longUrl.cache = [];

// to protect variables from resetting if included more than once
if (typeof renderTwitters != 'function') (function () {
    /** Private variables */
    var monthDict = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
    
	var domain = /(https?):\/\/(www\.)?inudge.net/;
	var currentLocation = document.location.href.replace(domain, "");
	if( currentLocation.charAt(0) != "/" )
	{
		currentLocation = "/"+currentLocation;
	}
	
	function isRoot( location ) {
		return location == "/index.en.html" || location == "/inudge" || location == "/";
	}
	
	function createUserLink( user ) {
		return '<a href="http://twitter.com/' + user + '" class="twitterUser indirect" title="Show the user ' + user + ' at twitter">@' + user + '</a>';
	}
	
	function createHashLink( hash ) {
		return '<a href="http://search.twitter.com/search?q=%23' + hash + '" class="twitterTag indirect" title="Search for other tweets with #'+hash+' at twitter">#' + hash + '</a>'
	}
	
    /** Global functions */	
	function directLink( elem ){
		var href = elem.href;
		var j = $(elem);
		elem.className = "";
		if( href.search( domain ) != -1 )
		{
			var location = href.replace(domain,"");
			if( location.charAt(0) != "/" )
			{
				location = "/"+location;
			}
			j.addClass( "direct" );
			j.attr("target", null);
			if( location.indexOf("#") != -1 )
			{
				var hash = location.substring( location.indexOf( "#" ) + 1 );
				j.attr("href", "#"+hash);
			}
			else
			if( location == currentLocation || ( isRoot( location ) && isRoot( currentLocation ) ) ) {
				j.attr("href", location);
				j.click( function(){
					return confirm('Do you want to reload this page?');
				} );
			}
			else
			{
				elem.href = location;
				j.attr("target", "_blank");
			}
			return;
		}
		j.addClass( "indirect" );
		j.attr("target", "_blank" );
		longUrl( href, function( url ) {
			if( url != j.attr("href") )
			{
				j.attr("href", url);
				j.attr("title", "Redirects to: "+url);
				directLink( elem );
			}
		});
	}
    
    // based on Dustin Diaz's ify, but with my fixes :-)
    window.ify = function() {
      var entities = {
          '"' : '&quot;',
          '&' : '&amp;',
          '<' : '&lt;',
          '>' : '&gt;'
      };

      return {
        "link": function(t) {
		  // /(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|]/ig
		  // /b(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$])/g
		  // /[a-z]+:\/\/[a-z0-9-_]+\.[a-z0-9-_:~%&\?\/.=]+[^:\.,\)\s*$]/ig
          return t.replace(/(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[A-Z0-9+&@#\/%=~_|]/ig, function(m) {
            return '<a href="' + m + '" class="unidentified">' + ((m.length > 25) ? m.substr(0, 24) + '...' : m) + '</a>';
          });
        },
        "at": function(t) {
          return t.replace(/(^|[^\w]+)\@([a-zA-Z0-9_]{1,15})/g, function(m, m1, m2) {
            return m1 + createUserLink( m2 );
          });
        },
        "hash": function(t) {
          return t.replace(/(^|[^\w'"]+)\#([a-zA-Z0-9_]+)/g, function(m, m1, m2) {
            return m1 + createHashLink( m2 );
          });
        },
        "clean": function(tweet) {
          return this.hash(this.at(this.link(tweet)));
        }
      };
    }();
	
	
    
    // to create a public function within our private scope, we attach the 
    // the function to the window object
    window.renderTwitters = function (obj, options) {
        // private shortcuts
        function node(e) {
            return document.createElement(e);
        }
        
        function text(t) {
            return document.createTextNode(t);
        }

        var target = document.getElementById(options.twitterTarget);
        var data = null;
        var ul = node('ul'), li, statusSpan, timeSpan, i, max = obj.length > options.count ? options.count : obj.length;
        var current = null;
        for (i = 0; i < max && (current = obj[i]); i++) {
            data = getTwitterData(current, i);
                      
            if (options.ignoreReplies && current.text.substr(0, 1) == '@') {
                max++;
                continue; // skip
            }
            
            li = node('li');
			li.className = "twitterZebra-"+current.zebra;
			if( i == 0 )
			{
				li.className += " twitterFirstLine";
			}
            
            li.innerHTML = options.template.replace(/%([a-z_\-\.]*)%/ig, function (m, l) {
                var r = data[l] + "" || "";
                if (l == 'text' && options.enableLinks) r = ify.clean(r);
				if (l == 'from_user_link') r = createUserLink( data.from_user );
                return r;
            });
			
			$("a.unidentified", li).each( function( no, elem ){
				directLink( elem );
			});
            
            ul.appendChild(li);
        }

        if (options.clearContents) {
            while (target.firstChild) {
                target.removeChild(target.firstChild);
            }
        }

        target.appendChild(ul);
        
        if (typeof options.callback == 'function') {
            options.callback();
        }
    };
    

    /** Private functions */
    
    function getTwitterData(orig, count) {
        var data = orig, i;
		data.zebra = count % 2 ? 1 : 0;
        for (i in orig.user) {
            data['user_' + i] = orig.user[i];
        }
        
        data.time = relative_time(orig.created_at);
        
        return data;
    }
        
	function formatTime(date) {
		var hour = date.getHours(),
			min = date.getMinutes() + "",
			ampm = 'AM';
		
		if (hour == 0) {
			hour = 12;
		} else if (hour == 12) {
			ampm = 'PM';
		} else if (hour > 12) {
			hour -= 12;
			ampm = 'PM';
		}
		
		if (min.length == 1) {
			min = '0' + min;
		}
		
		return hour + ':' + min + ' ' + ampm;
	}
	
	function formatDate(date) {
		var ds = date.toDateString().split(/ /),
			mon = monthDict[date.getMonth()],
			day = date.getDate()+'',
			dayi = parseInt(day),
			year = date.getFullYear(),
			thisyear = (new Date()).getFullYear(),
			th = 'th';
		
		// anti-'th' - but don't do the 11th, 12th or 13th
		if ((dayi % 10) == 1 && day.substr(0, 1) != '1') {
			th = 'st';
		} else if ((dayi % 10) == 2 && day.substr(0, 1) != '1') {
			th = 'nd';
		} else if ((dayi % 10) == 3 && day.substr(0, 1) != '1') {
			th = 'rd';
		}
		
		if (day.substr(0, 1) == '0') {
			day = day.substr(1);
		}
		
		return mon + ' ' + day + th + (thisyear != year ? ', ' + year : '');
	}
    
    function relative_time(time_value, relative_to) {
		if( !relative_to )
		{
			relative_to = new Date();
		}
        var date = new Date( Date.parse(time_value) ),
            delta = parseInt( (relative_to.getTime() - date.getTime()) / 1000 ),
            r = '';

        if (delta < 5) {
            r = 'less than 5 seconds ago';
        } else if (delta < 30) {
            r = 'half a minute ago';
        } else if (delta < 60) {
            r = 'less than a minute ago';
        } else if (delta < 120) {
            r = '1 minute ago';
        } else if (delta < (45*60)) {
            r = (parseInt(delta / 60)).toString() + ' minutes ago';
        } else if (delta < (2*90*60)) { // 2* because sometimes read 1 hours ago
            r = 'about 1 hour ago';
        } else if (delta < (24*60*60)) {
            r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
        } else {
            if (delta < (48*60*60)) {
                r = formatTime(date) + ' yesterday';
            } else {
                r = formatTime(date) + ' ' + formatDate(date);
                // r = (parseInt(delta / 86400)).toString() + ' days ago';
            }
        }

        return r;
    }
})();