// add support for Array scan (ECMA 262 extension) if not already supported
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/) {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++) {
      if (from in this && this[from] === elt)
        return from;
    }
    return -1;
  };
}

var READERSNIFF=function(){
  /*
    Created by Niall Kennedy: http://www.niallkennedy.com/

    Compare a set of known links against a visitor's browser history to determine preferred online feed aggregator(s).
    Add the appropriate feed subscription button for each positive match.
  */

  this.runstate={
    feed:{  // hard-code the feed URL and type to save a DOM trip
      url:'http:\/\/www.niallkennedy.com\/blog\/index.atom',
      type:'application/atom+xml'
    },
    link:null,
    test_elem:null,
    visitedlinks:[] // store positive matches here
  };

  this.feedbuttons={
    /*
      Define the appropriate remotely-hosted branded feed subscription button URI for each service
      Define the base URI string to add a new feed subscription on each service
      
      Note:
      You should really just use one big image and CSS sprites instead, but I realize remotely hosted buttons are a more reasonable solution for most users
    */
    generic:{
      image:{
        url:'http:\/\/graphics8.nytimes.com\/images\/global\/icons\/rss.gif',
        height:16,
        width:44
      }
    },
    aol:{
      link:'http:\/\/feeds.my.aol.com\/?url=',
      image:{
        url:'http:\/\/o.aolcdn.com\/myfeeds\/vis\/myaol_cta1.gif',
        height:14,
        width:63
      }
    },
    bloglines:{
      link:'http:\/\/www.bloglines.com\/sub\/',
      image:{
        url:'http:\/\/static.bloglines.com\/images\/sub_modern11.gif',
        height:17,
        width:76
      }
    },
    earthlink:{
      link:'http:\/\/reader.earthlink.net\/feed\/add_from_website?url=',
      image:{
        url:'http:\/\/reader.earthlink.net\/img\/add_to_myearthlink.gif',
        height:17,
        width:91
      }
    },
    google:{
      link:'http:\/\/fusion.google.com\/add?feedurl=',
      image:{
        url:'http:\/\/buttons.googlesyndication.com\/fusion\/add.gif',
        height:17,
        width:104
      }
    },
    gritwire:{
      link:'http:\/\/www.gritwire.com\/default.htm?feedurl=',
      image:{
        url:'http:\/\/www.gritwire.com\/img\/icons\/addtomygritwire.gif',
        height:17,
        width:91
      }
    },
    netvibes:{
      link:'http:\/\/www.netvibes.com/subscribe.php?type=rss&url=',
      image:{
        url:'http:\/\/eco.netvibes.com\/img\/add2netvibes.png',
        height:17,
        width:91
      }
    },
    newsburst:{
      link:'http:\/\/www.newsburst.com\/Source\/?add=',
      image:{
        url:'http:\/\/i.i.com.com\/cnwk.1d\/i\/newsbursts\/btn\/newsburst3.gif',
        height:20,
        width:96
      }
    },
    newsgator:{
      link:'http:\/\/www.newsgator.com\/ngs\/subscriber\/subext.aspx?url=',
      image:{
        url:'http:\/\/www.newsgator.com\/images\/ngsub1.gif',
        height:17,
        width:91
      }
    },
    pageflakes:{
      link:'http:\/\/www.pageflakes.com\/subscribe.aspx?url=',
      image:{
        url:'http:\/\/www.pageflakes.com\/images\/AddToPageflakes.gif',
        height:17,
        width:116
      }
    },
    protopage:{
      link:'http:\/\/www.protopage.com\/add-button-site?type=feed&url=',
      image:{
        url:'http:\/\/www.protopage.com\/web\/images\/buttons\/add-site-to-protopage.gif',
        height:17,
        width:91
      }
    },
    rojo:{
      link:'http://www.rojo.com\/add-subscription?resource=',
      image:{
        url:'http:\/\/www.rojo.com\/skins\/corporate\/images\/add-to-rojo.gif',
        height:17,
        width:91
      }
    },
    winlive:{
      link:'http:\/\/www.live.com\/?add=',
      image:{
        url:'http:\/\/shared.live.com\/A!G-2!XK1cEdKyyMw9kaWUrm0ESmdFrrspm4eXq813MFmfncap9qXYZDfu!eypuK\/base\/3432\/Gallery\/img\/addlive.gif',
        height:17,
        width:106
      }
    },
    yahoo:{
      link:'http:\/\/add.my.yahoo.com\/content?url=',
      image:{
        url:'http:\/\/us.i1.yimg.com\/us.yimg.com\/i\/us\/my\/addtomyyahoo4.gif',
        height:17,
        width:91
      }
    }
  };

  this.testlinks={
    /*
      Supply a set of test links placed into provider buckets.
      urlset defines a list of links that may indicate a site visitor's usage of a particular service.
      Links should be supplied in the order of most likely usage to most quickly achieve a positive match
      
      Note:
      Order does not matter in this case, since we scan for all matches, but you might rearrange based on service popularity if you want to have a first service wins scenario
    */
    readers:[
    {
      provider:'aol',
      urlset:[
        'http:\/\/feeds.my.aol.com\/'
      ]
    },
    {
      provider:'bloglines',
      urlset:[
        'http:\/\/www.bloglines.com\/myblogs_subs',
        'http:\/\/www.bloglines.com\/'
      ]
    },
    {
      provider:'earthlink',
      urlset:[
        'http:\/\/reader.earthlink.net\/'
      ]
    },
    {
      provider:'google',
      urlset:[
        'http:\/\/www.google.com\/reader\/view\/',
        'http:\/\/www.google.com\/ig',
        'http:\/\/www.google.com\/ig\/dell',
        'http:\/\/www.google.com\/ig\/emachines',
        'http:\/\/www.google.com\/ig\/gateway',
        'http:\/\/www.google.com\/ig\/usgov'
      ]
    },
    {
      provider:'gritwire',
      urlset:[
        'http:\/\/www.gritwire.com\/',
        'http:\/\/my.gritwire.com\/'
      ]
    },
    {
      provider:'netvibes',
      urlset:[
        'http:\/\/www.netvibes.com\/'
      ]
    },
    {
      provider:'newsburst',
      urlset:[
        'http:\/\/www.newsburst.com\/'
      ]
    },
    {
      provider:'newsgator',
      urlset:[
        'http:\/\/www.newsgator.com\/ngs\/subscriber\/reader\/index.aspx',
        'http:\/\/www.newsgator.com\/ngs\/subscriber\/WebEd2.aspx'
      ]
    },
    {
      provider:'pageflakes',
      urlset:[
        'http:\/\/www.pageflakes.com\/'
      ]
    },
    {
      provider:'protopage',
      urlset:[
        'http:\/\/www.protopage.com\/'
      ]
    },
    {
      provider:'winlive',
      urlset:[
        'http:\/\/www.live.com\/',
        'http:\/\/my.live.com\/'
      ]
    },
	{
      provider:'yahoo',
      urlset:[
        'http:\/\/my.yahoo.com\/',
        'http:\/\/att.my.yahoo.com\/'
      ]
    }
  ]
};

function buildButton(obj){
  /*
    Build a new "Add to ____" button
  */
  var link = document.createElement('a');
  link.href = obj.link + encodeURIComponent(runstate.feed.url);
  link.appendChild(document.createElement('div'));
  return link;
}

return{
  alreadyScanned:function(){
    return false;
    // usually we would scan the site cookie for our previously stored values, but we're not storing anything so you can more easily see how things work
    /*
    var readers=getCookie('feedreaders');
    if ( readers!==null && readers!=="" ) {
      runstate.visitedlinks=readers.split(',');
      return true;
    }
    else {
      return false;
    }
    */
  },

  hasVisitedLinks:function(){
    /*
      Check to see if our scan yielded any results
    */
    if ( runstate.visitedlinks && runstate.visitedlinks.length>0 ) {
      return true;
    }
    else {
      return false;
    }
  },

  feeddiscovery:function() {
    var feedlink = document.getElementById('webfeed');
    if (feedlink && feedlink.tagName.toLowerCase()=='a') {
      if (feedlink.href && feedlink.type){
        runstate.feed.url = feedlink.href;
        runstate.feed.type = feedlink.type;
        return true;
      }
    }
    else {
      var head = document.getElementsByTagName('head')[0];
      if (head) {
        var links = head.getElementsByTagName('link');
        if (links) {
          for (var i=0; i<links.length;i++) {
            var link = links[i];
            if (link.rel && link.type && (link.rel=='alternate' && accepted_types.indexOf(link.type)>=0)) {
              runstate.feed.url = link.href;
              runstate.feed.type = link.type;
              return true;
            }
            link=null;
          }
        }
        links=null;
      }
    }
    feedlink=null;
    return false;
  },

  init:function(){
    /*
      Setup our link scanner runtime.
      
      Setup the test area where links will be inserted.
      Determine the proper way to communicate with the visitor's browser regarding element style and color
    */

    if (!runstate.feed.url) {
      if (!feeddiscovery()) {
        return false; // no feed found. stop everything.
      }
    }

    // check for a defined element for link testing
    runstate.test_elem = document.getElementById('linktest');
    // create a test container at the bottom of the page no test element exists
    if( !runstate.test_elem ){
      runstate.test_elem = document.createElement('div');
      runstate.test_elem.id = 'linktest';
      runstate.test_elem.style.height = '1px';
      runstate.test_elem.style.width = '1px';
      document.body.appendChild(runstate.test_elem);
    }
    runstate.link = document.createElement('a');
    runstate.link.id = 'test_link';
    runstate.test_elem.appendChild(runstate.link);
    
    // Determine the proper method needed to communicate with the visitor's browser regarding element style and color
    if( runstate.link.currentStyle ) {
      this.islinkvisited=function(url) {
        var link = document.createElement('a');
        link.href = url;
        runstate.test_elem.appendChild(link);
        // does the color of the link match your defined :visited value?
        var color = link.currentStyle.color;
        if( color == '#000000' ) {
          runstate.test_elem.removeChild(link);
          return true;
        }
        else {
          runstate.test_elem.removeChild(link);
          return false;
        }
      };
    }
    else {
      this.islinkvisited=function(url) {
        var link = document.createElement('a');
        link.href = url;runstate.test_elem.appendChild(link);
        // does the color of the link match your defined :visited value expressed in RGB?
        var computed_style = document.defaultView.getComputedStyle(link,null);
        if (computed_style) {
          if( computed_style.color == 'rgb(0, 0, 0)' ) {
            runstate.test_elem.removeChild(link);
            return true;
          }
        }
        else{
          runstate.test_elem.removeChild(link);
          return false;
        }
      };
    }
    return true;
  },

  scan:function() {
    /*
      Scan all defined links for possible :visited matches
    */
    var links = testlinks.readers;
    for (var i=0;i<links.length;i++){
      var linktype = links[i];
      if ( linktype.provider && linktype.urlset ) {
        var reader = linktype.provider;
        for (var j=0;j<linktype.urlset.length;j++) {
          var url = linktype.urlset[j];
          var found = this.islinkvisited(url);
          if (found) {
            if ( runstate.visitedlinks && runstate.visitedlinks.indexOf(reader)<0 ){
              runstate.visitedlinks.push(reader);
              break;
            }
          }
          url=found=null;
        }
        reader=null;
      }
      linktype=null;
    }
    links=null;
    runstate.test_elem.innerHTML = '';
  },

  addbuttons:function() {
    var sublist = document.getElementById('subscribe-list');
    if ( sublist && (sublist.tagName.toLowerCase() == 'ul' || sublist.tagName.toLowerCase() == 'ol' ) ) {
      for (var i=0;i<runstate.visitedlinks.length;i++){
        var li = document.createElement('li');
        var link = null;
        switch (runstate.visitedlinks[i]) {
          case 'aol':
            link = buildButton(feedbuttons.aol);
            link.id='feedreader-aol';
            break;
          case 'bloglines':
            link = buildButton(feedbuttons.bloglines);
            link.id='feedreader-bloglines';
            break;
          case 'earthlink':
            link = buildButton(feedbuttons.earthlink);
            link.id = 'feedreader-earthlink';
            break;
          case 'google':
            link = buildButton(feedbuttons.google);
            link.id = 'feedreader-google';
            break;
          case 'gritwire':
            link = buildButton(feedbuttons.gritwire);
            link.id = 'feedreader-gritwire';
            break;
          case 'netvibes':
            link = buildButton(feedbuttons.netvibes);
            link.id = 'feedreader-netvibes';
            break;
          case 'newsburst':
            link = buildButton(feedbuttons.newsburst);
            link.id = 'feedreader-newsburst';
            break;
          case 'newsgator':
            link = buildButton(feedbuttons.newsgator);
            link.id = 'feedreader-newsgator';
            break;
          case 'pageflakes':
            link = buildButton(feedbuttons.pageflakes);
            link.id = 'feedreader-pageflakes';
            break;
          case 'protopage':
            link = buildButton(feedbuttons.protopage);
            link.id = 'feedreader-protopage';
            break;
          case 'rojo':
            link = buildButton(feedbuttons.rojo);
            link.id='feedreader-rojo';
            break;
          case 'winlive':
            link = buildButton(feedbuttons.winlive);
            link.id = 'feedreader-winlive';
            break;
          case 'yahoo':
            link = buildButton(feedbuttons.yahoo);
            link.id = 'feedreader-yahoo';
            break;
          default:
            break;
        }
        if (link) {
          link.className = 'feedreader';
          li.appendChild(link);
          sublist.appendChild(li);
        }
        li=link=null;
      }
    }
  },

  run:function() {
    // check if we need to run a test
    if ( !this.alreadyScanned() ) {
      if(this.init()) {
        this.scan();
      }
    }
    // only take action if something matches
    if ( this.hasVisitedLinks() ) {
      this.addbuttons();
    }
  }
};
}();
