<?xml version="1.0" encoding="UTF-8" ?> 
<Module>
  <ModulePrefs  
    title="Sellout.Woot! Watcher"
    description="Never miss a Sellout.Woot! again. This gadget will show you the Sellout.Woot! of the day, or will allow you to track Woot-Off in progress. You can specify keywords to be alerted on when they show up on sellout.woot.com. --------- This gadget was created as a service for the Woot community, by a member of the Woot community. Otherwise, this gadget is not affiliated with Woot, Inc." 
    screenshot="http://www.ljmsite.com/google/gadgets/wootwatcher/sellout.wootwatcher_screenshot.png"
    thumbnail="http://www.ljmsite.com/google/gadgets/wootwatcher/sellout.wootwatcher_thumbnail.png"
    author="Jerome Mouton"
    author_email="igoogle_gadgets@ljmsite.com"
    author_location="Huntsville, AL, USA"
    author_affiliation="LjmSite"
    author_aboutme="Google API gadget and web application developer, tech project manager in globally dispersed team environment, computer geek on call, etc. Come check me out at LjmSite.com and contact me to discuss gadget projects or opportunities."
    author_link="http://www.ljmsite.com/"
    author_photo="http://www.ljmsite.com/google/gadgets/jerome.png"
    singleton="false"
    height="300">
    <Require feature="analytics" />
    <Require feature="dynamic-height"/>
    <Require feature="setprefs"/>
    <Require feature="minimessage"/>
    <Require feature="flash"/>
  </ModulePrefs> 
  <UserPref name="mode" display_name="Display Mode" datatype="enum" default_value="compact">
    <EnumValue value="full" display_value="Full size"/>
    <EnumValue value="compact" display_value="Compact"/>
    <EnumValue value="nopict" display_value="No picture"/>
  </UserPref>
  <UserPref name="alert" display_name="Alert on keywords" datatype="enum" default_value="0">
    <EnumValue value="0" display_value="No alert"/>
    <EnumValue value="1" display_value="Only once"/>
    <EnumValue value="2" display_value="On every refresh"/>
  </UserPref>
  <UserPref name="sound" display_name="Alert sound" datatype="enum" default_value="Bells">
    <EnumValue value="bells.swf" display_value="Bells"/>
    <EnumValue value="siren.swf" display_value="Siren"/>
    <EnumValue value="alarm.swf" display_value="Alarm"/>
    <EnumValue value="airhorn.swf" display_value="Air Horn"/>
  </UserPref>
  <UserPref name="watch_items" display_name="Keyword" datatype="list" required="false" default_value="random crap|scooba"/>
  <UserPref name="refresh" display_name="Woot-Off refresh" datatype="enum" default_value="30">
    <EnumValue value="5" display_value="5 seconds"/>
    <EnumValue value="10" display_value="10 seconds"/>
    <EnumValue value="20" display_value="20 seconds"/>
    <EnumValue value="30" display_value="30 seconds"/>
    <EnumValue value="60" display_value="1 minute"/>
    <EnumValue value="120" display_value="2 minutes"/>
    <EnumValue value="300" display_value="5 minutes"/>
  </UserPref>
  <UserPref name="pca" display_name="Bells on product change" datatype="bool" required="false" default_value="false"/>
  <UserPref name="cache" display_name="Google image caching" datatype="bool" required="false" default_value="true"/>
  <UserPref name="last_alert_product" default_value="0" datatype="hidden"/>
  <UserPref name="messageid" datatype="hidden" default_value="0"/>
  <Content type="html">
<![CDATA[

<style type="text/css">
* {
	font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;
}	
.product {
	text-align:right;	
	font-size:18px;
	color:#000000;
	background-color:#ffffff;
}	
.product a {
	color:#000000;
	text-align:right;
	text-decoration:none;
	background-color:#ffffff;
}
.product a:link {
        color:#000000;
        text-align:right;
        text-decoration:none;
        background-color:#ffffff;
}
.product a:visited {
        color:#000000;
        text-align:right;
        text-decoration:none;
        background-color:#ffffff;
}
.product a:hover {
	text-align:right;
	text-decoration:none;
	background-color:#f29f01;
	color:#ffffff;
}
.price {
	text-align:right;	
	font-size:20px;
	font-weight:bold;
	color:#000000;
}
.price a {
	text-align:right;
	font-size:14px;
        font-weight:bold;
        color:#000000;
	text-decoration:none;	
}
.price a:hover {
	background-color:#f29f01;
}
.price a:visited {
	color:#000000;
}
.description {
	font-size:12px;
	font-family:sans-serif,Helvetica,Arial;
	color:#000000;
	background-color:#ffffff;
}
.description th {
	font-size:11px;
	vertical-align:top;
	font-family:sans-serif,Helvetica,Arial;
	color:#b4b2bc;
	background-color:#ffffff;
}
.description td {
	font-size:12px;
	font-family:sans-serif,Helvetica,Arial;
	color:#000000;
	background-color:#ffffff;
}
.sepline {
	padding:0px;
	margin:0px;
	height:1px;
	font-size:0px;
	background-color:#b4b2bc;
	width:100%;
}
.sepbar {
	padding:0px;
	margin:0px;
	height:3px;
	font-size:0px;
	background-color:#f29f01;
	width:100%;
}
.sidedeal {
	border:1px solid #335533;
	background-color:#443a64;
	color:#aaccaa;
	font-size:11px;
	white-space:nowrap;
}
.sidedeal b {
	color:#f29f01;
	background-color:#443a64;
	font-weight:bold;
	font-size:11px;
}
.sidedeal a {
	text-decoration:none;
	background-color:#443a64;
	color:#d4d2dc;
	font-size:11px;
	overflow:hidden;
}
.sidedeal a:visited {
        text-decoration:none;
        color:#d4d2dc;
}
.sidedeal a:hover {
	background-color:#f29f01;
	color:#ffffff;
}
.wootoffbar {
        background-color:#f29f01;
	color:#f29f01;
	font-size:16px;
}
.flasharea {
	padding:0px;
	margin:0px;
	height:0px;
	font-size:0px;
	background-color:#ffffff;
}
.mmlib_table__MODULE_ID__ {
	background-color: #f29f01;
	color: #000000;
}
</style>

<div class="sidedeal"><b>wwd:</b> <span id="wwd"></span></div>
<div class="sepbar"></div>
<div id="woot"></div>  
<div class="sepbar"></div>
<div id="flasharea1" class="flasharea"></div>
<div id="flasharea2" class="flasharea"></div>

<script type="text/javascript">

var wootOff = false;
var prefs;
var refreshCount = 0;
var html; // Global variable to reduce the memory leak

function getWidth() {
  var w;
  if(self.innerHeight) {
    w = self.innerWidth;
  }
  else if(document.documentElement && document.documentElement.clientHeight) {
    w = document.documentElement.clientWidth;
  }
  else if(document.body) {
    w = document.body.clientWidth;
  }
  return w;
}

function getImageUrl(url) {
  // Turned off the image caching totally as the AWS URLs are breaking the gmodules proxy
  return url;

  if(__UP_cache__) {
    return _IG_GetImageUrl(url);
  }
  return url;
}
  
function writeContent(product, buyurl, price, condition, description, picture, wootoff, percent) {
  html = '';

  if(wootoff) {
    var wootoff_light = getImageUrl('http://gzip.static.woot.com/Images/woot-off-light.gif');
    var barhtml = '&nbsp;';
    if(percent > 0) {
      barhtml = '<div class="wootoffbar" style="width: ' + percent + '%;">.</div>';
    }
    html += '<div><table width="100%"><tr><td><img src="' + wootoff_light + '" width="22" height="25" alt="Woot-Off"/></td>';
    html += '<td width="100%" align="left">' + barhtml + '</td>';
    html += '<td><img src="' + wootoff_light + '" width="22" height="25" alt="woot! off"/></td></table></div>';
  }

  if('__UP_mode__' == 'compact') {
    html += '<table border="0" cellspacing="0" cellpadding="0"><tr><td width="50%">';
  }

  if('__UP_mode__' != 'nopict') {
    var imgWidth = getWidth();
    if('__UP_mode__' == 'compact') {
      imgWidth = Math.floor(imgWidth / 2);
    }
    html += '<a href="http://sellout.woot.com" target="_blank">';    
    html += '<img src="' + picture + '" alt="woot!" width="' + imgWidth  + '" border="0"/></a>';
  }

  if('__UP_mode__' == 'compact') {
    html += '</td><td width="50%">';
  }

  html += '<div class="product"><a href="http://sellout.woot.com" target="_blank">' + product + '</a></div>';
  html += '</a>';
        if(percent == 0) {
                html += '<div class="price">sold out! (' + price + ')</div>';
        }
  else {
    html += '<div class="price"><a href="' + buyurl
          + '" target="_blank">I want one!</a>  ' + price + '</div>';
  }

  if('__UP_mode__' == 'compact') {
    html += '</td></table>';
  }

  html += '<div class="sepline"></div>';
  html += '<table class="description"><tr><th>conditition:</th><td>' + condition + '</td></tr>';
  html += '<tr><th>product(s):</th><td>' + description + '</td></tr></table>';
  html += '<div class="sepline"></div>';
  
  var wootDiv = document.getElementById('woot');
  wootDiv.innerHTML = html; 

  wootOff = wootoff;

  setTimeout('_IG_AdjustIFrameHeight()',1000);
  _IG_AdjustIFrameHeight();

  var refresh = 300000; // 5 minutes
  if(wootoff) {
    refresh = __UP_refresh__ * 1000;
  }
  setTimeout('getWoot()', refresh);
}

function getValue(data, pre, post) {
  var val = '';
  var start = data.indexOf(pre);
  if(start != -1) {
    start += pre.length;
    var data2 = data.substring(start);
    var end = data2.indexOf(post);
    if(end != -1) {
      val = data2.substring(0, end);
    }
  }
  return val;
}

function getXmlValue(data, tag) {
  var val = '';
  var start = data.indexOf('<' + tag);
  if(start != -1) {
    start += tag.length + 1;
    var data2 = data.substring(start);
    var end = data2.indexOf('</' + tag);
    if(end != -1) {
      data2 = data2.substring(0, end);
      start = data2.indexOf('>');
      if(start != -1) {
        start += 1;
        val = data2.substring(start);
      }
    }
  }
  return val;
}

function parseWoot(output) {
  if(output.indexOf('<item>') != -1) {
    output = output.substring(output.indexOf('<item>'));
  }

  var productdesc = getXmlValue(output, 'woot:products');
  var title = getXmlValue(output, 'title');
  var price = getXmlValue(output, 'woot:price');
  var condition = getXmlValue(output, 'woot:condition');
  var buyurl = getXmlValue(output, 'woot:purchaseurl');
// TODO - fix this
  var description = productdesc;
  //description = getValue(description, '/dt>', '</dl>');
  //description = description.replace(/<dd>/g, '').replace(/<\/dd>/g, '<br />');

  // Code below compensate &amp; &lt; and &gt; in the URL as the iGoogle ccache does not like those
  //var picture = getImageUrl(getValue(pictarea, 'src="', '"').replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/, '>'));
  var picture = getXmlValue(output, 'woot:standardimage');

  var fulldescription = getXmlValue(output, 'description');


  var wootoff = false;
  var percent = 0;
  if(getXmlValue(output, 'woot:wootoff') == 'true') {
    wootoff = true;
    percent = Math.round((1 - parseFloat(getXmlValue(output, 'woot:soldoutpercentage'))) * 100);
  }
  else if(getXmlValue(output, 'woot:soldout') == 'false') {
    percent = 100;
  }
  
  if((__UP_alert__ >= 1) && (percent > 0)) { // No need to alert if sold out
    var last = prefs.getString("last_alert_product");
    if((title != last) || (__UP_alert__ == 2)) { // Alert only once per item or on each refresh based on setup
      var keywords = prefs.getArray("watch_items");
      var searchtext = fulldescription.toLowerCase();
      for(var i = 0; i < keywords.length; i++) {
        if(searchtext.indexOf(keywords[i].toLowerCase()) != -1) {
          prefs.set("last_alert_product", title);
          _IG_EmbedFlash(
            _IG_GetCachedUrl('http://www.ljmsite.com/google/gadgets/wootwatcher/__UP_sound__'), 
                            "flasharea1", {wmode: "window", width: 1, height: 1});
          break;
        }
      }
    }
  }
  if(__UP_pca__) { // Product change alert
    var last = prefs.getString("last_alert_product");
    prefs.set("last_alert_product", title);
    if((refreshCount > 0) && (title != last)) { // We don't want to warn on the first refresh, as the condition would be true
      _IG_EmbedFlash(
        _IG_GetCachedUrl('http://www.ljmsite.com/google/gadgets/wootwatcher/bells.swf'),
        "flasharea2", {wmode: "window", width: 1, height: 1});
    }
  }
  refreshCount++;
  writeContent(title, buyurl, price, condition, description, picture, wootoff, percent);
}
  
function getWoot() {
  _IG_FetchContent('http://sellout.woot.com/SaleRss.aspx?r='+Math.random(),
    function(output) {
      if(output && (output.indexOf('Woot') != -1)) {
        parseWoot(output);
      }
      else {
        var wootDiv = document.getElementById('woot');
        wootDiv.innerHTML = "<p>Sorry, I couldn't connect to <a href=\"http://sellout.woot.com\">woot.com</a>...</p><p>I will try again in 10 seconds... Stay tuned!</p>";
        setTimeout('getWoot()', 10000);
      }
    }, {refreshInterval: 0}); // We only cache Woot! for 5 seconds (important in case of Woot-Off)
}

function init() {
  prefs = new _IG_Prefs(__MODULE_ID__);
  getWoot();

  //Need to switch to a mode where we don't depend on a successful fetch to continue... dead lock if fetch fails
  // For Woot! Off, we rather go with setInterval()
  // We also need to comment out the setTimeout()
  //setInterval('getWoot()', __UP_refresh__ * 1000);

  updateWatcherDeal();
  setInterval('updateWatcherDeal()', 2 * 60 * 1000); // Update the Watcher Deal every 2 minutes

  //createInfoMessage();
}

// ---------- Dismissable information utilities
// ------------------------------------------------------------------

var infoID = 1;
function createInfoMessage()
{
	// When changing the info message, increment infoID
	var messageHTML = '<b>Warning - Woot-Off expected Thursday July 19th, 2007</b>';
	var msg = new _IG_MiniMessage();

	var current = prefs.getInt("messageid");
	if((current == 0 /* new gadget */) || (current < infoID)) {
		msg.createDismissibleMessage(messageHTML, onDismissInfo);
	}
}

function onDismissInfo() {
        prefs.set("messageid", infoID);
	_IG_AdjustIFrameHeight();
}

// ------------------------------------------------------------------

function updateWatcherDeal()
{
        _IG_FetchContent('http://gadgets.ljmsite.com/watcherdeals/wwd.php?f=2', function(output) {
                if((output.charAt(0) == '#') && (output.indexOf('#E#') > 3)) {
                        document.getElementById('wwd').innerHTML = getValue(output, '#B#', '#E#');
                        return;
                }
        }, { refreshInterval: 150 });
}

// ------------------------------------------------------------------

_IG_RegisterOnloadHandler(init);
_IG_Analytics("UA-1189083-1", "/Sellout.WootWatcher/1");
	
</script>

]]> 
  </Content>
</Module>
