(function($){//BEGIN $ = jQuery
	
	
	$.makeLink = $.makeLink || function(str, options){
		options = $.extend({
			  target: '_blank'
		}, options);
		return str.replace(/[A-Za-z]+?:\/\/[A-Za-z0-9_-]+\.[A-Za-z0-9:%&\?\/.=~_-]+/g, function(m){
			return [
				  '<a href="'
				, m
				, options.target ? '" target="' + options.target + '">' : ''
				, m
				, '</a>'
			].join('');
		});
	};
	
	$.twitter = {
		  make_user_link: function(str){
			return str.replace(/@(\w+)/g, function(m, user){
				return [
					  '@<a href="'
					, 'http://twitter.com/'
					, user
					, '" target="_blank">'
					, user
					, '</a>'
				].join('');
			});
		}
		, make_hash_link: function(str){
			return str.replace(/#(\w+)/g, function(m, hashtag){
				return [
					  '#<a href="'
					, 'http://search.twitter.com/search?q='
					, encodeURIComponent(m)
					, '" target="_blank">'
					, hashtag
					, '</a>'
				].join('');
			});
		}
		, related_time: function(created_at, options){
			options = $.extend({
				  sec: function(c, d, diff){
					return [(Math.floor(diff / 5) + 1) * 5, '秒以内前'].join('');
				}
				, min: function(c, d, diff){
					var m = Math.floor(diff / 60);
					return m < 45 ? [m, '分前'].join('') : '約1時間前';
				}
				, hour: function(c, d, diff){
					var h = Math.floor(diff / 60 / 60) + 1;
					return h < 24 ? ['約', h, '時間前'].join('') : options.other(c, d, diff);
				}
				, other: function(c, d, diff){
					var dd = new Date(c);
					var m = dd.getMonth() + 1;
					var d = dd.getDate();
					var h = dd.getHours();
					var i = dd.getMinutes();
					
					return [
						  [
							  dd.getFullYear() || dd.getYear()
							, m < 10 ? ['0', m].join('') : m
							, d < 10 ? ['0', d].join('') : d
						].join('/')
						, [
							  h < 10 ? ['0', h].join('') : h
							, i < 10 ? ['0', i].join('') : i
						].join(':')
					].join(' ');
				}
			}, options);
			var d = new Date().getTime();
			var c = Date.parse(created_at) || (function(at){
				var c = new Date([at[1], at[2], at[5], at[3]].join(' '));
				c.setTime(c.getTime() - (!(at[4] - 0) ? c.getTimezoneOffset() * 60 * 1000 : 0));
				return c.getTime();
			})(created_at.split(' '));
			var diff = (d - c) / 1000;
			
			if(diff < 60){
				return options.sec(c, d, diff);
			}else if(diff < 60 * 60){
				return options.min(c, d, diff);
			}else if(diff < 60 * 60 * 24){
				return options.hour(c, d, diff);
			}
			
			return options.other(c, d, diff);
		}
	};
	$.twitter.convert_link = function(str){
		var $tw = $.twitter;
		return $tw.make_user_link($tw.make_hash_link($.makeLink(str)));
	};
	
	$.fn.twitter = function(username, options){
		if(!username || typeof arguments[0] != 'string') throw 'requires a username';
		
		var $this = this;
		
		var default_count = 5;
		options = $.extend({
			  method: 'status/user_timeline'
			, count: default_count
			, loading: 'now loading...'
			, prefix: '<ul>'
			, postfix: '</ul>'
			, each_line: '<li><a class="user" href="%user.link%" target="_blank"><img src="%user.profile_image_url%" width="16" height="16" alt="%user.name%" /></a> %text% <a class="date" href="%link%" target="_blank">%date%</a></li>'
			, success: function(json){
				var ret = [options.prefix];
				$.each(json, function(i, item){
					var screen_name = item.user.screen_name;
					item.link = ['http://twitter.com', screen_name, 'status', item.id].join('/');
					item.text = $.twitter.convert_link(item.text);
					item.date = $.twitter.related_time(item.created_at);
					item.user.link = ['http://twitter.com/', screen_name].join('');
					var each_line = options.each_line
						.replace(/%(.*?)%/g, function(m, obj){
							var mm = obj.match(/(.+?)\.(.+)/);
							return mm ? item[mm[1]][mm[2]] : item[obj];
						})
					ret.push(each_line);
				});
				ret.push(options.postfix);
				$this.html(ret.join(''));
			}
			, error: function(XMLHttpRequest, textStatus, errorThrown){
				console && console.log && console.log(XMLHttpRequest, textStatus, errorThrown);
				$this.html('error...');
			}
			, params : {}
		}, options);
		
		$this.html(options.loading);
		
		
		var Tw_API_URI = ['http://twitter.com/', options.method, '/', username, '.json'].join('');
		
		var params = $.extend({
			count: options.count
		}, options.params);
		if(!params.count || params.count > 200) params.count = default_count;
		params = $.param(params);
		
		var uri = [Tw_API_URI, params].join('?');
		
		$.ajax({
			  url: uri
			, dataType: 'jsonp'
			, success: options.success
			, error: options.error
		});
		
		return this;
	};
	
	
})(jQuery);//END $ = jQuery
