<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="DealCatcher" directory_title="dealcatcher" description="dealcatcher deals" author="Kishore Senji" author_email="ksenji+dealcatcher@gmail.com"
    thumbnail="http://ksenji.googlepages.com/dealcatcher.ig.png?v=2" 
    screenshot="http://ksenji.googlepages.com/dealcatcher.ig.png?v=2" 
    author_location="US"
    author_affiliation="none"
    title_url="http://www.dealcatcher.com/"
    render_inline="optional"
    height="166">
    <Locale lang="en" country="us" />
    <Require feature="dynamic-height"/>
  </ModulePrefs>
  <UserPref name="mode" display_name="Display mode" required="false" datatype="enum" default_value="scrolling">
    <EnumValue value="scrolling" display_value="Slideshow"/>
    <EnumValue value="classic" display_value="Classic"/>
  </UserPref>
  <UserPref name="redir" display_name="Open links directly to the deal website" datatype="bool" default_value="true"/>
  <UserPref name="count" display_name="Show" required="false" datatype="enum" default_value="3">
    <EnumValue value="3" display_value="3 deals per page in classic mode."/>
    <EnumValue value="5" display_value="5 deals per page in classic mode."/>
    <EnumValue value="10" display_value="10 deals per page in classic mode."/>
    <EnumValue value="15" display_value="15 deals per page in classic mode."/>
    <EnumValue value="20" display_value="20 deals per page in classic mode."/>
    <EnumValue value="25" display_value="25 deals per page in classic mode."/>
    <EnumValue value="30" display_value="30 deals per page in classic mode."/>
    <EnumValue value="35" display_value="35 deals per page in classic mode."/>
    <EnumValue value="40" display_value="40 deals per page in classic mode."/>
    <EnumValue value="45" display_value="45 deals per page in classic mode."/>
    <EnumValue value="50" display_value="50 deals per page in classic mode."/>
    <EnumValue value="100" display_value="100 deals per page in classic mode."/>
  </UserPref>
  <UserPref name="even" display_name="Even row bgcolor" required="false" datatype="string" default_value="eeffff"/>
  <UserPref name="odd" display_name="Odd row bgcolor" required="false" datatype="string" default_value="ffffff"/>
  <UserPref name="linksPosition" display_name="Display navigation" required="false" datatype="enum" default_value="bottom">
    <EnumValue value="top" display_value="links at top in classic mode."/>
    <EnumValue value="bottom" display_value="links at bottom in classic mode."/>
  </UserPref>
  <Content type="html">
    <![CDATA[
      <style type="text/css">
        .scrollingModeDeal {
          font-size : 75%;
          position : relative;
        }
        .classicModeDeal {
          font-size : 75%;
          padding: 2px 0px 2px 0px;
        }        
        .link {
          cursor : pointer;
        }
        .classicModeLink {
          float : left;
          cursor : pointer;
        }        
        .scrollingModeDate {
          position : absolute;
          top : 0;
          right : -1;
          font-size : 90%;
          font-weight : bold;
          color : #0000ff;
        }
        .classicModeDate {
          float : right;
          right : 1px;
          font-size : 90%;
          font-weight : bold;
          color : #0000ff;
        }        
        .previous {
          float : left;
          cursor : pointer;
          font-size : 90%;
          font-weight : bold;
        }
        .next {
          float : right;
          cursor : pointer;
          font-size : 90%;
          font-weight : bold;
        }
        .debug {
          font-size : 90%;
          color : #000000;
        }
        .info {
          font-size : 90%;
          color : #0000ff;
        }
        .warn {
          font-size : 90%;
          color : #fff000;
        }
        .error {
          font-size : 90%;
          color : #ffffff;
        }
        .more {
          font-size: 90%;
          color : #0000ff;
          font-weight : bold;
          cursor : pointer;
          float : right;
          right : -1px;
        }
      </style>
      <script src="http://www.google.com/jsapi"></script>
      <script type="text/javascript">
        google.setOnLoadCallback(function() {
          var prefs = new _IG_Prefs(__MODULE_ID__);
          var gadget = new DealCatcherGadget(__MODULE_ID__, {
            mode : prefs.getString("mode"),
            numberPerPage : prefs.getInt("count"),
            evenBgColor : prefs.getString("even"),
            oldBgColor : prefs.getString("old"),
            linksPosition : prefs.getString("linksPosition"),
            redir : prefs.getBool("redir"),
            devMode : true
          });
          gadget.load();
          $(window).unload(function() {
            gadget.unload();
          });
        });

        /* load jquery */
        google.load("jquery", "1.2.6");

        /* From prototype */
        function $A(iterable) {
	  if (!iterable) return [];
	  if (iterable.toArray) return iterable.toArray();
	  var length = iterable.length || 0, results = new Array(length);
	  while (length--) results[length] = iterable[length];
	  return results;
	};

        Function.prototype.bind = function() {
          if (arguments.length < 2 && (typeof arguments[0] == "undefined")) return this;
          var __method = this, args = $A(arguments), object = args.shift();
          return function() {
            return __method.apply(object, args.concat($A(arguments)));
          };
        };
        
        function DealCatcherGadget(id, prefs) {
          var remote = $("div[@id^=remote]");
          var supportedModes = ["classic", "scrolling"];
          
          var content = null;       
          var entries = null;
          var scrollingModeIndex = 0; /* Scrolling mode Book keeping */
          var classicModePageIndex = 1; /* Classic mode Book keeping */
          
          var interval = -1;
          
          var mode = jQuery.inArray(prefs["mode"], supportedModes) != -1 ? prefs["mode"] : supportedModes[1];
          
          var inScrollingMode = (mode == supportedModes[1]);
          var inClassicMode = (mode == supportedModes[0]);
          
          var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
          var regex = /a href/mi;
          var redirRegex = /rsslink/i;
          
          var colorRegex = /(#?)([0-9a-f]{6})/i;
          var validateBgColor = function(bgColor) {
            if(bgColor) {
              var match = bgColor.match(colorRegex)
              if(match) {
                return match[1] ? match[1] + match[2] : match[2];
              }
            }
            return "#ffffff";
          };
          
          prefs["evenBgColor"] = validateBgColor(prefs["evenBgColor"]);
          prefs["oddBgColor"] = validateBgColor(prefs["oddBgColor"]);
                    
          
          var twoDigitFormat = function(data) {
            return Number(data) > 10 ? String(data) : "0" + data;
          };
          
          var amOrPm = function(hours) {
            return hours >= 12 ? "pm" : "am";
          };
          
          var date = function(time) {
            var now = new Date();
            var d = new Date(Number(time) * 1000);
            var hours = d.getHours();
            
            if(d.getDate() == now.getDate()) {
              return  "Today " + hours + ":" + twoDigitFormat(d.getMinutes()) + amOrPm(hours);
            } else {
              return d.getDate() + " " + months[d.getMonth()] + " " + hours + ":" + twoDigitFormat(d.getMinutes()) + amOrPm(hours);
            }
          };
          
          var scrollingModeDeal = function(id, entry) {
            var deal = $("<div class=\"scrollingModeDeal\" id=\"deal_" + id + "_" + entry.ID + "\"/>");
            $("<span class=\"scrollingModeDate\">" + date(entry.Date) + "</span>").appendTo(deal);            
            $("<div class=\"link\">" + entry.Title + "</div>").click(function() {
              window.open(entry.Link);
            }).css({
              paddingTop : "10px"
            }).appendTo(deal);
            $("<p/><div>" + entry.Summary + "</div>").appendTo(deal);
            return deal;
          };
          
          var classicModeDeal = function(id, entry) {
            var deal = $("<div class=\"classicModeDeal\" id=\"deal_" + id + "_" + entry.ID + "\"/>");
            var dateDisplay = date(entry.Date);
            $("<div class=\"classicModeLink\">" + entry.Title + "</div><div class=\"classicModeDate\">" + dateDisplay + "</div><div style=\"clear:both\"></div>").click(function() {
              var win = window.open(entry.Link);
              if(!win) {
                alert("Pop up blocked. Please enable popups for " + document.domain.substring(document.domain.indexOf(".") + 1) + " domain.");
              }
            }).appendTo(deal);
            if(jQuery.browser.msie) {
              deal.css("height", "10px");
            }
            return deal;
          };
          
          this.id = id + "_" + Number(new Date());
          
          var showingMoreFromThisAuthor = false;
          var moreGadgets = [];
          
          var additionalGadgetIndex = 0;
          var rotateAdditionalGadgets = function() {
            if(additionalGadgetIndex >= moreGadgets.length) {
              additionalGadgetIndex = 0;
            }
            var gadgetsContainer = $("div#gadgets_" + id).show();
            var gadget = moreGadgets[additionalGadgetIndex];
            var wrapper = $("<div id=\"wrapper_" + id + "_" + additionalGadgetIndex + "\"/>");
            $("<div style=\"cursor:pointer;font-weight:bold;font-size:85%;\">" + gadget.title + "- Add to your iGoogle. </div>").click(function() {
              window.open(gadget.link);
            }).appendTo(wrapper);
            $("<div style=\"font-size:85%\">" + gadget.description + "</div>").appendTo(wrapper);
            wrapper.appendTo(gadgetsContainer);            
            if(gadgetsContainer.children().length > 2) {
              gadgetsContainer.find("div[@id^=wrapper]:first").animate({height : 1}, "slow", function() {
                $(this).remove();
              });
            }
            additionalGadgetIndex ++;
            if(showingMoreFromThisAuthor) {
              setTimeout(rotateAdditionalGadgets, 3000);
            } else {
              gadgetsContainer.hide();
            }
          };
          
          this.moreFromThisAuthor = function() {
            var gadgetsContainer = null;
            var more = $("div#more_" + this.id);
            if(!more.get(0)) {
             more = $("<div id=\"more_" + this.id + "\"/>").addClass("more").html("more").click(function() {
               if(content.is(":hidden")) {
                 $(this).html("more");
                 content.animate({height : this.height}, "slow"/*, function() {
                   $(this).hide();
                 }*/); 
                 $("div[@id^=gadgets]").hide();
                 showingMoreFromThisAuthor = false;
               } else {
                 $(this).html("close");
                 gadgetsContainer.find("div[@id^=wrapper]").remove();
                 showingMoreFromThisAuthor = true;
                 this.height = jQuery.css(content.get(0), "height");
                 content.animate({height : 1}, "slow", function() {
                   $(this).hide();
                   rotateAdditionalGadgets();
                 });                  
               }
             });
             more.appendTo(remote);
             $("<div style=\"clear:both\"></div>").appendTo(remote);
             gadgetsContainer = $("<div id=\"gadgets_" + id + "\"></div>").hide();
             $("<div style=\"font-size:85%;\"><i>... more gadgets from this author.</i></div>").appendTo(gadgetsContainer);
             gadgetsContainer.appendTo(remote);
             _IG_FetchXmlContent("http://ksenji.googlepages.com/gadgets.xml?v=4", function(response) {
               var gadgets = response.getElementsByTagName("gadget");
               for(var i=0; i<gadgets.length; i++) {
                 var gadget = gadgets.item(i);
                 var children = gadget.childNodes;
                 var title, description, link;
                 for(var j=0; j<children.length; j++) {
                   var child = children.item(j);
                   if(child.nodeName == "title") {
                     title = child.firstChild.nodeValue;
                   } else if(child.nodeName == "description") {
                     description = child.firstChild.nodeValue;
                   } else if(child.nodeName == "link") {
                     link = child.firstChild.nodeValue;
                   }
                 }
                 moreGadgets.push({
                   title : title,
                   description : description,
                   link : link
                 });
               }
             });
            }
          };

          this.load = function() {
            if(prefs.devMode) {
              $("<div id=\"debug_" + this.id + "\"/>").appendTo(remote);
            }
            if(!$("div#content_" + this.id).get(0)) {
              content = $("<div id=\"content_" + this.id + "\"/>");
              if(inScrollingMode) {
                content.css({
                  overflow : "hidden",
                  height : "150px"
                });
              } else {
                var links = $("<div id=\"links_" + this.id + "\"/>").css({
                  paddingTop : "5px"
                });
                $("<span class=\"previous\"/>").click(function() {
                  this.previous();
                }.bind(this)).appendTo(links);
                $("<span class=\"next\"/>").click(function() {
                  this.next();
                }.bind(this)).appendTo(links);
                $("<div style=\"clear:both\"/>").appendTo(links);
                links.hide().appendTo(content);
              }
              content.prependTo(remote);
            }
            
            setTimeout(function() {
              this.moreFromThisAuthor();
              _IG_AdjustIFrameHeight();
            }.bind(this), 10000);
            
            this.fetchData();
          };
          
          this.unload = function() {
            if(interval == -1) {
              clearInterval(interval);
            }
            if(content != null) {
              content.remove();
              content = null;
            }
            entries.length = 0;
            entries = null;
          };
          
          var preloadRegex = /img src="([^"]*)"/mi;
          var preloadImages = function() {
            jQuery.each(entries, function(i, entry) {
              var match = entry.Summary.match(preloadRegex);
              if(match) {
                var image = new Image();
                image.src = match[1];
              }
            });
          };
          
          this.fetchData = function() {
            _IG_FetchFeedAsJSON("http://rss.dealcatcher.com/rss.xml", function(data) {
              entries = data.Entry;
              
              jQuery.each(entries, function(i, entry) {
                entry.Summary = entry.Summary.replace(regex, "a target=\"_blank\" href");
                var match = entry.Summary.match(preloadRegex);
                if(match) {
                  var src = _IG_GetCachedUrl(match[0].replace(/img[\s]+src="(.*?)"/i, "$1"));
                  src = src.replace(/&log=1/gi, "");
                  entry.Summary = entry.Summary.replace(match[0], "img src=\"" + src + "\"");
                }
                
                if(prefs.redir) {
                  entry.Link = entry.Link.replace(redirRegex, "redir");
                }
              });
              
              /*entries.sort(function(e1, e2) { 
                return e1.Date <= e2.Date; 
              });*/
              
              this.render();
              
              if(interval == -1 && inScrollingMode) {
                setTimeout(function() {
                  preloadImages();
                }, 2000);
                interval = setInterval(function() {
                  if(!showingMoreFromThisAuthor) {
                    scrollingModeIndex ++;
                    if(scrollingModeIndex >= entries.length) {
                      scrollingModeIndex = 0;
                    }
                    this.render(); 
                  }
                }.bind(this), 3000);
              }
            }.bind(this), 100, true);
          };
          
          this.previous = function() {
            if(inClassicMode) {
              if(classicModePageIndex >= 1) {
                classicModePageIndex -= 1;
                this.render();
              }
            }
          };
          
          this.next = function() {
            if(inClassicMode) {
              if(classicModePageIndex * prefs.numberPerPage < entries.length) {
                classicModePageIndex += 1;
                this.render();
              }
            }
          };
          
          this.log = function(level, message) {
            if(prefs.devMode) {
              $("<div class=\"" + level + "\">" + message.toString().replace(/</mg, "&lt;").replace(/>/mg, "&gt;") + "</div>").appendTo($("div#debug_" + this.id));
            }
          };
          
          this.debug = function(message) {
            this.log("debug", message);
          };
          
          this.info = function(message) {
            this.log("info", message);
          };          
          
          this.warn = function(message) {
            this.log("warn", message);
          };          
          
          this.error = function(message) {
            this.log("error", message);
          };          
          
          this.render = function() {
            if(inScrollingMode) {
              scrollingModeDeal(this.id, entries[scrollingModeIndex]).appendTo(content);
              var secondChild = content.find("div[@id^=deal]:nth-child(2)");
              if(secondChild.get(0)) {
                content.find("div[@id^=deal]:nth-child(1)").animate({
                  height : 1
                }, "slow", function() {
                  $(this).remove();
                });
              }
            } else {
              content.find("div[@id^=deal]").remove();
              var end = classicModePageIndex * prefs.numberPerPage;
              var start = end - prefs.numberPerPage;
              var links = content.find("div[@id^=links]");
              var count = 0;
              for(var i=start; i<end; i++) {
                if(i < entries.length) {
                  classicModeDeal(this.id, entries[i]).css({
                    backgroundColor : (count++%2 != 0) ? prefs.evenBgColor : prefs.oldBgColor
                  }).appendTo(content);
                }
              }
              if(prefs.linksPosition == "bottom") {
                links.appendTo(content);
              }
              links.find("span:nth-child(1)").html("Previous " + prefs.numberPerPage + " deals")[(start > 0) ? "show" : "hide"]();
              links.find("span:nth-child(2)").html("Next " + prefs.numberPerPage + " deals")[(end < entries.length) ? "show" : "hide"]();
              links.show();
            }
            _IG_AdjustIFrameHeight();
          };
        };
      </script>
    ]]>
  </Content>
</Module>
