// 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 OPENIDSNIFF=function(){
  /*
    Created by Niall Kennedy: http://www.niallkennedy.com/

    Compare a set of known links against a visitor's browser history to determine a preferred list of OpenID providers
    Add the appropriate branding for each provider, prompting visitor action.
  */

  this.runstate={
    link:null,
    test_elem:null,
    visitedlinks:[] // store positive matches here
  };

  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

      Listed in roughly the same order as on the OpenID list:
      http://openid.net/get/

      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
    */
    providers:[
    {
      provider:'aol',
      urlset:[
        'https:\/\/my.screenname.aol.com\/_cqr\/login\/login.psp'
      ]
    },
    {
      provider:'livedoor',
      urlset:[
        'http:\/\/member.livedoor.com\/login\/',
        'https:\/\/member.livedoor.com\/login\/'
      ]
    },
    {
      provider:'livejournal',
      urlset:[
        'http:\/\/www.livejournal.com\/login.bml'
      ]
    },
    {
      provider:'orange',
      urlset:[
        'http:\/\/id.orange.fr\/auth_user\/bin\/auth_user.cgi'
      ]
    },
    {
      provider:'smugmug',
      urlset:[
        'https:\/\/www.smugmug.com\/login.mg'
      ]
    },
    {
      provider:'technorati',
      urlset:[
        'http:\/\/technorati.com\/signup\/',
        'http:\/\/www.technorati.com\/signup\/',
        'http:\/\/technorati.com\/login.php',
        'http:\/\/www.technorati.com\/login.php'
      ]
    },
    {
      provider:'vox',
      urlset:[
        'http:\/\/www.vox.com\/',
        'http:\/\/www.vox.com\/signin\/save'
      ]
    },
    {
      provider:'wordpresscom',
      urlset:[
        'http:\/\/wordpress.com\/wp-login.php',
        'https:\/\/wordpress.com\/wp-login.php'
      ]
    },
    {
      provider:'yahoo',
      urlset:[
        'https:\/\/login.yahoo.com\/config\/login',
        'https:\/\/login.yahoo.com\/'
      ]
    },
    {
      provider:'claimid',
      urlset:[
        'http:\/\/claimid.com\/',
        'https:\/\/claimid.com\/',
        'http:\/\/claimid.com\/account\/login',
        'https:\/\/claimid.com\/account\/login'
      ]
    },
    {
      provider:'myopenid',
      urlset:[
        'https:\/\/www.myopenid.com\/signin_password'
      ]
    },
	{
      provider:'verisign',
      urlset:[
        'https:\/\/pip.verisignlabs.com\/login.do'
      ]
    },
    {
      provider:'myid',
      urlset:[
        'http:\/\/myid.net\/',
        'https:\/\/myid.net\/'
      ]
    },
    {
      provider:'myvidoop',
      urlset:[
        'https:\/\/myvidoop.com\/vidsec_handler.php'
      ]
    }
  ]
};

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 openids=getCookie('openids');
    if ( openids!==null && openids!=="" ) {
      runstate.visitedlinks=openids.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;
    }
  },

  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
    */

    // 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;
        }
      };
    }
  },

  scan:function() {
    /*
      Scan all defined links for possible :visited matches
    */
    var links = testlinks.providers;
    for (var i=0;i<links.length;i++){
      var linktype = links[i];
      if ( linktype.provider && linktype.urlset ) {
        var provider = 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(provider)<0 ){
              runstate.visitedlinks.push(provider);
              break;
            }
          }
          url=found=null;
        }
        provider=null;
      }
      linktype=null;
    }
    links=null;
    runstate.test_elem.innerHTML = '';
  },

  addbuttons:function() {
    var loginlist = document.getElementById('login-list');
    // only take action if an ordered or an unordered login list exists
    if ( loginlist && (loginlist.tagName.toLowerCase() == 'ul' || loginlist.tagName.toLowerCase() == 'ol' ) ) {
      for (var i=0;i<runstate.visitedlinks.length;i++) {
        var li = document.createElement('li');
        li.id = runstate.visitedlinks[i];
        li.appendChild(document.createTextNode(runstate.visitedlinks[i]));
        loginlist.appendChild(li);
        li = null;
      }
    }
    loginlist = null;
  },

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