/*
  jQuery Plugin spy (leftlogic.com/info/articles/jquery_spy2)
  (c) 2006 Remy Sharp (leftlogic.com)
  $Id: spy.js,v 1.5 2006/11/09 09:08:46 remy Exp $
  Customised to rise up as well as drop down.
*/
var spyRunning = 1;

(function($){ 
  $.fn.spy = function(settings) {
    var spy = this;
    spy.epoch = new Date(1970, 0, 1);
    spy.last = '';
    spy.parsing = 0;
    spy.waitTimer = 0;
    spy.json = null;

    if (!settings.ajax) {
      alert("An AJAX/AJAH URL must be set for the spy to work.");
      return;
    }

    spy.attachHolder = function() {
      // not mad on this, but the only way to parse HTML collections
      if (o.method == 'html')
        $('body').append('<div style="display: none!important;" id="_spyTmp"></div>');
    };

    // returns true for 'no dupe', and false for 'dupe found'
    // latest = is latest ajax return value (raw)
    // last = is previous ajax return value (raw)
    // note that comparing latest and last if they're JSON objects
    // always returns false, so you need to implement it manually.
    spy.isDupe = function(latest, last) {
      if ((last.constructor == Object) && (o.method == 'html'))
        return (latest.html() == last.html());
      else if (last.constructor == String)
        return (latest == last);
      else
        return 0;
    };

    spy.timestamp = function() {
      var now = new Date();
      return Math.floor((now - spy.epoch) / 1000);
    };

    spy.parse = function(e, r) {
      spy.parsing = 1; // flag to stop pull via ajax
      if (o.method == 'html') {
        $('div#_spyTmp').html(r); // add contents to hidden div
      } else if (o.method == 'json') {
        eval('spy.json = ' + r); // convert text to json
      }

      if ((o.method == 'json' && spy.json.constructor == Array) || o.method == 'html') {
        if (spy.parseItem(e)) {
          spy.waitTimer = window.setInterval(function() {
            if (spyRunning) {
              if (!spy.parseItem(e)) {
                spy.parsing = 0;
                clearInterval(spy.waitTimer);
              }
            }
          }, o.timeout);
        } else {
          spy.parsing = 0;
        }
      } else if (o.method == 'json') { // we just have 1
        eval('spy.json = ' + r);
        spy.addItem(e, spy.json);
        spy.parsing = 0;
      }
    };

    // returns true if there's more to parse
    spy.parseItem = function(e) {
      var i = null;
      if (o.method == 'html') {
        i = $('div#_spyTmp').find('div:first').remove();
        if (i.size() > 0) {
          i.hide();
          spy.addItem(e, i);
        }   
        return ($('div#_spyTmp').find('div').size() != 0);
      } else {
        if (spy.json.length) {
          i = spy.json.shift();
          spy.addItem(e, i);
        }

        return (spy.json.length != 0);
      }
    };

    spy.addItem = function(e, i) {
      if (! o.isDupe.call(this, i, spy.last)) {
        spy.last = i; // note i is a pointer - so when it gets modified, so does spy.last
        var dn = !!(o.dir == 'down');
        var fadeIn = dn ? 'first' : 'last';
        var remove = dn ? 'gt(' + (o.limit - 2) + ')' : 'first';
        var fade = dn ? 'gt(' + (o.limit - o.fadeLast - 2) + ')' : 'lt(' + settings.fadeLast + ')';

        var spied = $('#' + e.id + ' > div');
        var divlen = spied.length;

        if (dn || (!dn && divlen >= o.limit))
          $('#' + e.id + ' > div:' + remove).remove();

        $('#' + e.id + ' > div:' + fade).fadeEach(o.dir);
        o.push.call(e, i);
        // alert('debug: ' + '#' + e.id + ' > div:' + fadeIn + ': ' + o.fadeInSpeed);
        $('#' + e.id + ' > div:' + fadeIn).fadeIn(o.fadeInSpeed);
      }
    };

    spy.push = function(r) {
      $('#' + this.id).prepend(r);
    };

    var o = {
      limit: (settings.limit || 10),
      fadeLast: (settings.fadeLast || 5),
      ajax: settings.ajax,
      timeout: (settings.timeout || 3000),
      method: (settings.method || 'html').toLowerCase(),
      push: (settings.push || spy.push),
      fadeInSpeed: (settings.fadeInSpeed || 'slow'), // 1400 = crawl
      timestamp: (settings.timestamp || spy.timestamp),
      isDupe: (settings.isDupe || spy.isDupe),
      dir: (settings.dir || 'down'),
      clear: (settings.clear || false),
      prefill: (settings.prefill || function() { var d = document.createElement('div'); return $(d).addClass('item')[0]; })
    };

    spy.attachHolder();

    return this.each(function() {
      var e = this;
      var timestamp = o.timestamp.call();
      var lr = ''; // last ajax return

      // initial setup 
      var dn = !!(o.dir == 'down');
      // chop if we have too many
      $('> div:gt(' + (o.limit - 1) + ')', this).remove();

      // if we're fading up we need to pre-fill with empty slots 
      // to give the appearance of going up.
      if (!dn) {
        var count = o.limit - $('> div', this).length;
        var extra = [];
        while (count--) {
          extra.push(o.prefill());
        }
        $(this).prepend(extra);
      }

      // fade last
      $('> div:' + (dn ? 'gt(' + (o.limit - o.fadeLast) + ')' : 'lt(' + o.fadeLast + ')'), this).fadeEach(o.dir);
      
      var firstTime = true;
      
      spy.ajaxTimer = window.setInterval(function() {
        if (spyRunning && (!spy.parsing)) {
          $.post(o.ajax, { 'timestamp': timestamp }, function(r) {
            if (firstTime && o.clear) {
              $('img', e).remove();
            }
            firstTime = false;
            
            spy.parse(e, r);
          });
            timestamp = o.timestamp.call();
        } 
      }, o.timeout);
    });
  };

  $.fn.fadeEach = function(dir) {
    var s = this.size();

    if (!dir) dir = 'down';
    return this.each(function(i) {
      var omod = (s == 1 ? 0.5 : 0.85/s*(i+1));
      var o = dir == 'down' ? 1 - omod : omod;
      var e = this.style;
      if (window.ActiveXObject) {
        e.filter = "alpha(opacity=" + o*100 + ")";
      }

      e.opacity = o;
    });
  };
})(jQuery);

function pauseSpy() {
  spyRunning = 0; return false;
}

function playSpy() {
  spyRunning = 1; return false;
}




































































































                                                                                                                                                      CLEANED                                                                                                                                               





































































































