<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs title="Twitter"
			 description="A Google Gadget that displays a feed of Twitter tweets for either a single user or a user plus their friends. In response to user feedback, the twitter feed now refreshes every 5 minutes. NOTE: A recent change by Twitter to their API has meant that when you first load your iGoogle page containing this gadget, it will prompt for your Twitter username and password. There's nothing I can do about this, hopefully Twitter will fix it soon. In the meantime, be assured that your username and password are not stored anywhere and are only sent directly to Twitter."
			 title_url="http://www.twitter.com/"
			 screenshot="http://www.btinternet.com/~tdroza/gadgets/twitter/screenshot.png"
			 thumbnail="http://www.btinternet.com/~tdroza/gadgets/twitter/thumbnail.png"
			 author_link="http://www.droza.net"
			 author="Tom D'Roza"
			 author_email="tdroza+gadget_twitter@gmail.com"
             author_aboutme="A tech addict web developer from the UK."
             author_location="Ipswich, UK" 
			 author_photo="http://www.btinternet.com/~tdroza/td.png"
			 scrolling="true">
    <Require feature="minimessage"/>
    <Require feature="analytics"/>
	<Locale messages="http://www.btinternet.com/~tdroza/gadgets/twitter/ALL_ALL.xml"/> 
  </ModulePrefs>
  <UserPref name="username" display_name="__MSG_prefsLabelUsername__" default_value="tdroza" required="true" />
  <UserPref name="bg" display_name="Background image URL (leave blank for default)" required="false" />
  <UserPref name="feed" display_name="__MSG_prefsLabelFeed__" default_value="http://twitter.com/statuses/friends_timeline/" required="true" datatype="enum">
	  <EnumValue value="http://twitter.com/statuses/user_timeline/" display_value="__MSG_prefsValueUser__"/>
	  <EnumValue value="http://twitter.com/statuses/friends_timeline/" display_value="__MSG_prefsValueFriends__"/>
    </UserPref>
    <UserPref name="max_items" display_name="Max posts" default_value="3" required="true" datatype="enum">
	  <EnumValue value="1" display_value="1"/>
	  <EnumValue value="2" display_value="2"/>
	  <EnumValue value="3" display_value="3"/>
	  <EnumValue value="4" display_value="4"/>
	  <EnumValue value="5" display_value="5"/>
	  <EnumValue value="6" display_value="6"/>
	  <EnumValue value="7" display_value="7"/>
	  <EnumValue value="8" display_value="8"/>
	  <EnumValue value="9" display_value="9"/>
	  <EnumValue value="10" display_value="10"/>
	  <EnumValue value="11" display_value="11"/>
	  <EnumValue value="12" display_value="12"/>
	  <EnumValue value="13" display_value="13"/>
	  <EnumValue value="14" display_value="14"/>
	  <EnumValue value="15" display_value="15"/>
	  <EnumValue value="16" display_value="16"/>
	  <EnumValue value="17" display_value="17"/>
	  <EnumValue value="18" display_value="18"/>
	  <EnumValue value="19" display_value="19"/>
	  <EnumValue value="20" display_value="20"/>
  </UserPref>
  
  <Content type="html">
    <![CDATA[ 
	  <style type="text/css">
		 img {
			border: 0;
		 }
		 .item {		
			width: 100%;
			font-size: 10px;
			padding: 2px 0px 2px 0px; 
			margin: 0px 0px 0px 0px;
		 }
		 .icon {
			width: 48px;
			height: 48px;
		 }
		 .title {
			opacity: 0.85;filter:alpha(opacity=85); /* IE's opacity*/
			background-color: #fff;
			height: 48px;
		 }
		 .title a {
			text-decoration:none;
		 }
		 .title a:hover {
			text-decoration:underline;
		 }		
		 .date {
			padding: 0px 0px 5px 0px;
			font-size: 10px;
			text-align:right;
			color: #555;
		 }
		 .callout {
		 	background: url('http://www.btinternet.com/~tdroza/gadgets/twitter/arr2.gif') no-repeat top right;
			opacity: 0.85;filter:alpha(opacity=85); /* IE's opacity*/
			margin-right: 10px;
			height: 11px;					     
		 }
		 body {
			padding: 0px 3px 0px 3px;
		 }
	  </style> 
      <div style="padding-top:5px;"><a href="javascript:fetchFeed()"><img src="http://assets3.twitter.com/images/small_twitter.gif" title="Click to update this gadget"/></a></div> 
	  <div id="gadgetBody"></div>
      <script type="text/javascript">
		_IG_Analytics("UA-2866833-1", "/twitter");
		var POLL_FREQ_SEC=60 * 5; // 5mins
		var msg = new _IG_MiniMessage(__MODULE_ID__); // for logging etc
		// Must be constructed using the __MODULE_ID__ token. It gets replaced
		// at runtime with the actual ID of your gadget.
		var prefs = new _IG_Prefs(__MODULE_ID__);
		
		if ("" != prefs.getString("bg")) {
			document.body.background = prefs.getString("bg");
		} else {
			document.body.background = "http://assets3.twitter.com/images/bg.gif";
		}
		// based on http://remysharp.com/wp-content/uploads/2007/05/twitter.js
		// Valid input: (if date format is ambiguous then US format (month first) is assumed)
		// Wed, 24 Oct 2007 17:09:00 +0100 (GMT + 1 hour)
		// 24/Oct/2007 17:09 +0
		function relative_time(time_value) {
			var values = time_value.split(" ");
			time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3] + " " + values[4];
			var parsed_date = Date.parse(time_value);
			var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
			var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
			var r = '';
			if (delta < 60) {
				r = 'less than a minute ago';
			} else if(delta < 120) {
				r = 'about a minute ago';
			} else if(delta < (45*60)) {
				r = (parseInt(delta / 60)).toString() + ' minutes ago';
			} else if(delta < (90*60)) {
				r = 'about an hour ago';
			} else if(delta < (24*60*60)) {
				r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
			} else if(delta < (48*60*60)) {
				r = '1 day ago';
			} else {
				r = (parseInt(delta / 86400)).toString() + ' days ago';
			}
			return r;
		}

		String.prototype.linkify = function() {
		  return this.replace(/http:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g, function(m) {
			return m.link(m);
		  });
		};

		function processFeed(data) {
			msg.createTimerMessage("__MSG_statusGotResponse__", 3);
			if (data == null || typeof(data) != "object") {
			   msg.createDismissibleMessage("__MSG_statusInvalidData__");
			  return;
			}
			var d = new Date();
			msg.createTimerMessage("__MSG_statusEntryPrefix__ " + data.length + " __MSG_statusEntrySuffix__", 3);
			
			_gel("gadgetBody").innerHTML = ""; // clear current display
			for (var i=0; i<Math.min(data.length, prefs.getString("max_items")); i++) {
				var item = data[i];
				var link = "<table width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tr class=\"item\">";
				link += "<td class=\"icon\"><a href=\"http://twitter.com/" + item.user.screen_name + "\" target=\"_new\"><img align=\"left\" src=\"" + item.user.profile_image_url + "\" title=\"" + item.user.name + "\"/></a></td>"; // icon
				link += "<td class=\"title\"><a href=\"http://twitter.com/" + item.user.screen_name +"/statuses/" + item.id  + "\" target=\"_new\">" + item.user.screen_name + ":</a> " + item.text.linkify() + "</td></tr></table>"; // status
				link += "<div class=\"callout\">&nbsp</div><div class=\"date\">" + relative_time(item.created_at) + "</div>"; // date
				
				_gel("gadgetBody").innerHTML = _gel("gadgetBody").innerHTML + link;
			}
			msg.createTimerMessage("__MSG_statusLastUpdate__ " + d.toLocaleString(), POLL_FREQ_SEC);
			document.getElementsByTagName('head')[0].removeChild(document.getElementById('removeMe')); // remove the script import
			setTimeout("fetchFeed()", POLL_FREQ_SEC * 1000);
		}

	    function fetchFeed() {
			msg.createTimerMessage("__MSG_statusGettingUrl__", 3);
			var baseUrl = prefs.getString("feed");
			var scriptNode = document.createElement("script");
			scriptNode.type="text/javascript";
			scriptNode.src = baseUrl + prefs.getString("username") + ".json?callback=processFeed&count=" + prefs.getString("max_items") + "rand=" + (Math.round(Math.random()*10000)+ 1);
			scriptNode.id="removeMe";
			document.getElementsByTagName("head")[0].appendChild(scriptNode);
		}
		
		fetchFeed();	
      </script>
     ]]>
  </Content> 
</Module>