(function($){
	$.simpleTweet = function(el, options){
		var base = this;
        
        base.$el = $(el);
		base.el = el;
        
		base.$el.data("simpleTweet", base);
        
        base.types = {
			hash:1,
        	username:2,
        	search:3,
        	list:4,
        	rss:5
        };
        
        base.searchType = 1;
        base.tweets = -1;
        base.searchURL = "http://search.twitter.com/search.json?callback=?";
        
        base.init = function(){
            base.options = $.extend(true,{},$.simpleTweet.defaultOptions, options);
            base.vars = $.extend(true,{},$.simpleTweet.vars,{});
            
            if(base.options.maxTweets > 200){
            	base.options.maxTweets = 200;
            }
            //set search type
            base.searchType = base.getSearchType();
            //get tweets
            base.getData();
        };
        //*****************************DOM FUNCTIONS***********************************
        base.buildTweets = function(){
        	var tString = "<ul class='"+base.options.css.tweetContainer+"'>"; 
        	for(i = 0; i < base.tweets.length; i++){
        		var tweetClass = "odd";
				if(i%2 == 0){
					tweetClass = "even";
				}
				
				tString += "<li class='"+tweetClass+" "+base.options.css.tweetClass+"' tweetid='"+base.tweets[i].id+"'>";
				if(base.searchType === base.types.hash || base.searchType === base.types.search){
					tString += "<img class='"+base.options.css.avatarClass+"' width='48' height='48' src='"+base.tweets[i].profile_image_url+"' border='0'/>";
					tString += "<a href='http://www.twitter.com/"+base.tweets[i].from_user+"'>"+base.tweets[i].from_user+"</a>&nbsp;";
				}
				
				tString += base.replaceURLs(base.tweets[i].text) + "<br>";
				
				if(base.options.displayDate){
					tString += "<span class='"+base.options.css.tweetDate+"'>" + base.writeDate(base.tweets[i].created_at) + "</span>";
				}
				if(base.options.displaySource){
					tString += "&nbsp;from&nbsp;<span class='"+base.options.css.tweetSource+"'>" + base.fixEncHTML(base.tweets[i].source) + "</span>";
				}
				
				tString += "<br style='clear:both;'></li>";
        	}
        	tString += base.writeTweetFooter() + "</ul>";
        	base.$el.fadeOut("slow",function(){
        		base.$el.html(tString).fadeIn();
        	});
        };
        
        base.buildTweetList = function(){
        	var tString = "<ul class='"+base.options.css.tweetContainer+"'>"; 
        	for(i = 0; i < base.tweets.length; i++){
        		var tweetClass = "odd";
				if(i%2 == 0){
					tweetClass = "even";
				}
				tString += "<li class='"+tweetClass+" "+base.options.css.tweet+"' tweetid='"+base.tweets[i].id+"'>";
				tString += "<img class='"+base.options.css.avatar+"' wdth='48' height='48' src='"+base.tweets[i].user.profile_image_url+"' border='0'/>";
				tString += "<a href='http://www.twitter.com/"+base.tweets[i].user.name+"'>"+base.tweets[i].user.name+"</a>&nbsp;" + base.replaceURLs(base.tweets[i].text) + "<br>";
				
				if(base.options.displayDate){
					tString += "<span class='"+base.options.css.tweetDate+"'>" + base.writeDate(base.tweets[i].created_at) + "</span>";
				}
				if(base.options.displaySource){
					tString += "&nbsp;from&nbsp;<span class='"+base.options.css.tweetSource+"'>" + base.fixEncHTML(base.tweets[i].source) + "</span>";
				}
				
				tString += "<br style='clear:both;'></li>";
        	}
        	tString += base.writeTweetFooter() + "</ul>";
        	base.$el.fadeOut("slow",function(){
        		base.$el.html(tString).fadeIn();
        	});
        };
        
        base.writeTweetFooter = function(){
        	var ret = "<li class='"+base.options.css.footer+"'>";
        	if(base.searchType == base.types.username){
        		ret += "<img class='"+base.options.css.avatar+"' width='48' height='48' src='"+base.tweets[0].profile_image_url+"' border='0'/>";
				ret += "<div class='"+base.options.css.search+"'><a href='http://www.twitter.com/"+base.tweets[0].from_user+"'>"+base.tweets[0].from_user+"</a></div>";      	
        	}else{
        		ret += "<div class='"+base.options.css.search+"'>";
        		if(base.searchType == base.types.search || base.searchType == base.types.hash){
        			ret += "search results for: " + base.options.search;
        		}else if(base.searchType == base.types.list){
        			ret += "<a href='http://www.twitter.com/"+base.options.search.user+"/"+base.options.search.list+"' target='_blank'>@"+base.options.search.user+"/"+base.options.search.list+"</a>";
        		}
        		ret += "</div>";
        	}
        	ret += "<br style='clear:both;'></li>";
        	return ret;
        };
        
        base.writeDate = function(date){
        	if(!base.options.useRelativeTime){
        		return date;
        	}
        	var tweetDate = new Date(date),today = new Date(),timeDiff = "",
        	minDiff = Math.ceil((today.getTime()-tweetDate.getTime())/(60*1000)),
			hourDiff = Math.ceil((today.getTime()-tweetDate.getTime())/(60*60*1000)),
			dayDiff = Math.ceil((today.getTime()-tweetDate.getTime())/(24*60*60*1000));
			                       					
			if(minDiff < 59){
			    timeDiff = minDiff+" minutes ago";
			}else if(hourDiff < 24){
			    timeDiff = hourDiff+" hours ago";
			}else if(dayDiff < 5){
			    timeDiff = dayDiff+" days ago";
			}else{
			    var AMPM = "PM";
			    var myHours;
			    if(tweetDate.getHours() < 12){
			    	AMPM = "AM";
			    	if(tweetDate.getHours() == 0){
			    		myHours = "12";
			    	}else{
			    		myHours = tweetDate.getHours();
			    	}
			    }else{
			    	myHours = tweetDate.getHours()-12;
			    }
			    
			    var myDate = tweetDate.getDate() +"th";
			    if(tweetDate.getDate() == 1 || tweetDate.getDate() == 21 || tweetDate.getDate() == 31){
			    	myDate = tweetDate.getDate() +"st";
			    }else if(tweetDate.getDate() == 2 || tweetDate.getDate() == 22){
			    	myDate = tweetDate.getDate() +"nd";
			    }else if(tweetDate.getDate() == 3 || tweetDate.getDate() == 23){
			    	myDate = tweetDate.getDate() +"rd";
			    }
			    
			    var myMinutes = tweetDate.getMinutes();
			    if(myMinutes === 0){
			    	myMinutes = "00";
			    }
			    
			    timeDiff = myHours+":"+myMinutes+"&nbsp;"+AMPM+"&nbsp;"+base.vars.months[tweetDate.getMonth()]+"&nbsp;"+myDate;
			}
			return timeDiff;
        };
        
        base.getData = function(){
        	if(base.searchType === base.types.rss){
        		
        		$.ajax({
        			type: "GET",
        			url: base.searchURL,
        			dataType: "xml",
        			success: function(data) {
        			    var tcount = 0;
        			    $(data).find('item').each(function(){
        			    	var $obj = $(this),tweetText = $obj.find("description").text(),firstClass = " first";
        			    	var tweet = "";
        			    	
        			    	if(tcount === 0){
        			    		tweet += "<div class='tweet first'>";
        			    	}else{
        			    		tweet += "<div class='tweet'>";
        			    	}
        			    	//build tweet and append it
        			    	tweet += "<div class='tweet-desc'>"+base.replaceURLs(tweetText.substring(tweetText.indexOf(':')+2))+"</div>";
        			    	
        			    	tweet += "<div class='tweetInfo'>"+base.writeDate($obj.find("pubDate").text())+"&nbsp;&middot;&nbsp;<a href='http://www.twitter.com/home?status="+base.options.search+"'>reply</a>&nbsp;&middot;&nbsp;<a href='"+$obj.find("link").text()+"'>view tweet</a></div>";
        			    	
        			    	tweet += "</div>";
        			    	
        			    	if(base.options.maxTweets > tcount){
        			    		base.$el.append(tweet);
        			    	}
        			    	tcount++;
        			    	
        			    	
        			    });
        			},
        			error: function(request,tStatus,eThrown){
        				console.debug("Error loading XML: "+eThrown + " : " + base.searchURL);
        			}
        		});
        		
        		return;
        	}
        	
        	$.getJSON(base.searchURL,function(data){
        		if(typeof data.error !== "undefined"){
        			base.$el.html("Sorry, there was an error while looking for your tweets: " + data.error);
        			return;
        		}
        		if(base.searchType === base.types.list){
        			base.tweets = data;
        			base.buildTweetList();
        		}
        		$.each(data, function(i, tweets){
                    if (typeof tweets.length != "undefined"){                   			
                   		if (typeof tweets[0] != "undefined"){
                   			if (typeof tweets[0].created_at != "undefined"){
                   				base.tweets = tweets;
                   				base.buildTweets();
                   			}
                   		}
                   	}
                });
        	});
        };
        
        base.getSearchType = function(){
        	var search = base.options.search;
        	if(base.options.fromRSS){
        		base.searchURL = "/script/getRSS.asp?url=http://twitter.com/statuses/user_timeline/"+search.split('@')[1]+".rss";
        		return base.types.rss;
        	}
        	
        	if(typeof search.user !== "undefined" && typeof search.list !== "undefined"){
        			base.searchURL = "http://api.twitter.com/1/"+search.user+"/lists/"+search.list+"/statuses.json?callback=?&per_page=" + base.options.maxTweets;
        			return base.types.list;
        	}
        	
        	var fChar = search.charAt(0);
        	base.searchURL += "&rpp="+base.options.maxTweets + "&q=";
        	switch(fChar){
        		case "#":
        			base.searchURL += "%23" + search.split('#')[1];
        			return base.types.hash;
        			break;
        		case "@":
        			base.searchURL += "from:" + search.split('@')[1];
        			return base.types.username;
        			break;
        		default:
        			var secCheck = search.slice(0,4);
        			switch(secCheck){
        				case "from":
        						base.searchURL += search;
        						return base.types.username;
        					break;
        				default:
        						base.searchURL += search;
        						return base.types.search;
        					break;
        			}
        			break;
        	}
        };
        
        base.isEncHTML = function(str){
			if(str.search(/&amp;/g) != -1 || str.search(/&lt;/g) != -1 || str.search(/&gt;/g) != -1 || str.search(/&quot;/g) != -1) 
		    	return true; 
		  	else 
		    	return false;
        };
        
        base.fixEncHTML = function(str){
        	if(base.isEncHTML(str)) 
		      return str.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g,"'"); 
		    return str; 
        };
        
        base.replaceURLs = function(text){
			text = text.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,"<a href='$1' target='_blank'>$1</a>");
			text = text.replace(/(^|\s)@(\w+)/g,"$1<a class='user' href='http://www.twitter.com/$2' target='_blank'>@$2</a>");
			text = text.replace(/(^|\s)#(\w+)/g,"$1<a class='hashtag' href='http://search.twitter.com/search?q=%23$2' target='_blank'>#$2</a>");
			return text;
        };
        
        base.init();
    };
    
    $.simpleTweet.defaultOptions = {
    	search:"#jquery",
    	maxTweets:5,
    	fromRSS:false,
		useRelativeTime:true,
		displaySource:true,
		displayDate:true,
		aTagRegexp:/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
		hashtagRegexp:/(^|\s)#(\w+)/g,
		userRegexp:/(^|\s)@(\w+)/g,
		css:{
			tweetContainer:"tweet-container",
			tweet:"tweet",
			avatar:"avatar",
			tweetDate:"date",
			tweetSource:"source",
			footer:"footer",
			search:"tweet-identifier"
		}
    };
    
    $.simpleTweet.vars = {
   		aTagRegexp:/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig,
		hashtagRegexp:/(^|\s)#(\w+)/g,
		userRegexp:/(^|\s)@(\w+)/g,
		months:["January","February","March","April","May","June","July","August","September","October","November","December"]
    };
    
    $.fn.simpleTweet = function(options){
        return this.each(function(){
            (new $.simpleTweet(this, options));
        });
    };
})(jQuery);