/**
 * jQuery Plugin to obtain touch gestures from iPhone, iPod Touch and iPad, should also work with Android mobile phones (not tested yet!)
 * Common usage: wipe images (left and right to show the previous or next image)
 * 
 * @author Andreas Waltl, netCU Internetagentur (http://www.netcu.de)
 * @version 1.1.1 (9th December 2010) - fix bug (older IE's had problems)
 * @version 1.1 (1st September 2010) - support wipe up and wipe down
 * @version 1.0 (15th July 2010)
 */
(function($){$.fn.touchwipe=function(settings){var config={min_move_x:20,min_move_y:20,wipeLeft:function(){},wipeRight:function(){},wipeUp:function(){},wipeDown:function(){},preventDefaultEvents:true};if(settings)$.extend(config,settings);this.each(function(){var startX;var startY;var isMoving=false;function cancelTouch(){this.removeEventListener('touchmove',onTouchMove);startX=null;isMoving=false}function onTouchMove(e){if(config.preventDefaultEvents){e.preventDefault()}if(isMoving){var x=e.touches[0].pageX;var y=e.touches[0].pageY;var dx=startX-x;var dy=startY-y;if(Math.abs(dx)>=config.min_move_x){cancelTouch();if(dx>0){config.wipeLeft()}else{config.wipeRight()}}else if(Math.abs(dy)>=config.min_move_y){cancelTouch();if(dy>0){config.wipeDown()}else{config.wipeUp()}}}}function onTouchStart(e){if(e.touches.length==1){startX=e.touches[0].pageX;startY=e.touches[0].pageY;isMoving=true;this.addEventListener('touchmove',onTouchMove,false)}}if('ontouchstart'in document.documentElement){this.addEventListener('touchstart',onTouchStart,false)}});return this}})(jQuery);

/*
# Carousel 1.8 [jQuery plugin for 1.3+]
#
# Copyright (C) 2010 - Snapper Net Solutions | www.snapper.no
#
# Usage:
# $('#yourcarousel').carousel()
#
#   > where #yourcarousel points to your ul containing one li per item to be displayed
#
# 1.2 adds fade as a transition mode
# 1.3 is rewritten to be more robust when used with other plugins
# 1.4 adds optional < and > (prev, next)
# 1.5 adds new mode, circle, which just circles around (slide)
# 1.6 adds new mode, noloop, as well as possibility of using custom functions for buttons/tickbox
# 1.7 adds new transition, dissolve
# 1.8 adds play() function

# Modes:
# noloop > 1, 2, 3, 4 (doesn't loop)
# restart > 1, 2, 3, 4 < 1, 2, 3, 4 (snaps rapidly back to first when finished)
# circle > 1, 2, 3, 4, 1, 2, 3, 4
*/

(function($)
{
  $.fn.carousel = function(options)
  {
    var self = this;

    self.current = 0;
    self.previous = 0;
    self.items = [];
    self.itemw = 0;
    self.fullw = 0;
    self.timer = null;
    self.locked = false;
    self.animating = false;

    var obj = $(this);
    var defaults =
    {
      auto: 0,
      pos: 0,
      mode: 'restart',
      transmode: 'slide',
      transition: 1.0,
      tickbox: false,
      buttons: ''
    };

    // Get parameters
    self.options = $.extend({}, defaults, options);
    self.options.auto = self.options.auto * 1000;
    self.options.transition = self.options.transition * 1000;

    //
    // Public methods
    //

    this.prev = function()
    {
      if (self.locked == true || self.animating == true)
        return false;

      // Remember previous object id
      self.previous = self.current;
      self.current--;
      self._animate(self.current);
    };

    this.next = function()
    {
      if (self.locked == true || self.animating == true)
        return false;

      // Remember previous object id
      self.previous = self.current;
      self.current++;
      self._animate(self.current);
    };

    this.goto = function(n, noanim)
    {
      if (self.locked == true || self.animating == true)
        return false;

      // Remember previous object id
      self.previous = self.current;
      self.current = n;
      self._animate(self.current, noanim);
    };

    this.stop = function()
    {
      clearInterval(self.timer);
      self.timer = null;
    };

    this.play = function()
    {
      clearInterval(self.timer);
      self.timer = setInterval(function(){self.next()}, self.options.auto);
    }

    this.clicked = function(el)
    {
      self.stop();
      if ($(el).hasClass('prev'))
        self.prev();
      else
        self.next();
    };

    this.update_tickbox = function()
    {
      var ticknum = self.current;
      if (self.options.mode == 'circle' && self.current >= self.shownum)
        ticknum = 0;

      if (self.tickbox_method)
      {
        self.tickbox_method()
      }
      else
      {
        var tb = $('.tickbox', self.master);
        var ti = $('li', tb);
        ti.removeClass('active');
        $(ti[ticknum]).addClass('active');
      }
    };

    //
    // Private methods
    //

    var _finished = function()
    {
      self.animating = false;
      if (self.options.tickbox)
        self.update_tickbox();

      if (self.options.mode == 'circle')
      {
      	if (self.current >= self.shownum)
        {
          self.current = 0;
          self.goto(0, true);
        }
        else if (self.current < 0)
        {
          self.current = self.shownum-1;
          self.goto(self.shownum-1, true);
        }
      }
    };

    // Transition mode slide (default)
    var _slide = function(i, noanim)
    {
      _track_control(i);

      var cp = (self.options.mode == 'circle') ? self.current+1 : self.current;
      var pos = cp * self.itemw * -1;

      if (noanim == true)
      {
        var x = 0;
        self.css({left: pos});
        _finished();
      }
      else
      {
        self.animating = true;
        self.animate({left: pos, easing: 'swing'}, self.options.transition, function(){_finished()});
      }
    };

    var _fade = function(i, noanim)
    {
      _track_control(i);
      //if (self.current == self.previous)
      //  return;

      if (noanim == true)
        var x = 0;
      else
      {
        self.animating = true;
        var pel = self.items[self.previous];
        var nel = self.items[self.current];
        $(pel).fadeOut(self.options.transition, function(){ $(nel).fadeIn(self.options.transition, function(){_finished()}) });
      }
    };

    var _dissolve = function(i, noanim)
    {
      _track_control(i);
      if (noanim == true)
        var x = 0;
      else
      {
        self.animating = true;
        var pel = self.items[self.previous];
        var nel = self.items[self.current];
        $(pel).css('z-index', 2);
        $(nel).css('z-index', 1).show();
        $(pel).fadeOut(self.options.transition, function(){_finished()});
      }
    }

    var _track_control = function(i)
    {
      if (self.options.mode == 'restart')
      {
        if (self.current >= self.items.length) self.current = 0;
        else if (self.current < 0) self.current = self.items.length - 1;
      }
      else if (self.options.mode == 'circle')
      {
        if (self.current >= self.items.length) self.current = self.items.length - 1;
        else if (self.current < -1) self.current = -1;
      }
      else if (self.options.mode == 'noloop')
      {
        if (self.current <= 0) self.current = 0;
        else if (self.current >= self.items.length) self.current = self.current-1;
      }
      else
      {
        if (self.current >= self.items.length) self.current = self.items.length - 1;
        else if (self.current < 0) self.current = 0;
      }
    };

    // Set up
    return this.each( function()
    {
      self.master = $(this).parent();
      self.items = $('ul:first-child > li', self.master);
      self.itemw = $(self.items[0]).width();
      self.fullw = self.items.length * self.itemw;
      self.shownum = self.items.length;
      var li_css = {width: self.itemw};

      // Adjust to circle mode
      if (self.options.mode == 'circle')
      {
        var pref = $(self.items[0]).clone();
        var suff = $(self.items[self.items.length-1]).clone();
        pref.appendTo(this);
        suff.prependTo(this);
        self.items.push(pref[0]);
        self.items.push(suff[0]);
        self.fullw += (self.itemw*2);
      }

      // Set transition mode
      switch (self.options.transmode)
      {
        case "fade":
          self.fullw = self.itemw;
          li_css.position = 'absolute';
          li_css.display = 'none';
          self._animate = _fade;
          break;

        case "dissolve":
          self.fullw = self.itemw;
          li_css.position = 'absolute';
          li_css.display = 'none';
          self._animate = _dissolve;
          $.each(self.items, function(n){$(this).css('z-index', 1+n)});
          break;

        default:
          self._animate = _slide;
          if (self.options.mode == 'circle')
            self.css({left: self.itemw*-1});

          break;
      }

      $.each(self.items, function(){$(this).css(li_css)});
      $('li:first-child', this).css('display', 'block')
      $(this).addClass('lime_carousel').css('width', self.fullw);

      if (self.options.auto && self.items.length > 1)
        self.timer = setInterval(function(){self.next()}, self.options.auto);

      // Do we need to add any buttons?
      if (self.options.buttons)
      {
        if (typeof(self.options.buttons) == 'function')
        {
          self.options.buttons(self);
        }
        else
        {
          self.master.append('<div class="' + self.options.buttons + ' prev"></div><div class="' + self.options.buttons + ' next"></div>');
          $('.button', self.master).click(function(){self.clicked(this)});
        }
      }

      if (typeof(self.options.tickbox) == 'function')
      {
         self.options.tickbox(self);
         self.options.tickbox = true;
      }

      // Do we need to add status pointers
      if (self.options.tickbox && !self.tickbox_method)
      {
      	if (!self.shownum) return;

        var html = '<li class="active" value="0">&nbsp;</li>';
        var il = self.shownum;
        for (var i=1; i < il; i++)
        {
          html += '<li value="' + i + '">&nbsp;</li>';
        }
        self.master.append('<ul class="tickbox">' + html + '</ul>');
        var tb = $('.tickbox', self.master);
        $('li', tb).click(function(){self.stop(); self.goto($(this).attr('value'))});
      }
    });
  };
})(jQuery);


function fbs_click(u, t) 
{
  if (!u) u=location.href;
  if (!t) t=document.title;
  window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}

function digg_click()
{
  u=location.href;
  t=document.title;
  window.open('http://digg.com/submit?phase=2&url='+encodeURIComponent(u)+'&title='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}

function twitter_click(u, t)
{
  if (!u) u=location.href;
  if (!t) t=document.title;
  window.open('http://twitter.com/home/?status='+encodeURIComponent(t)+'%20'+encodeURIComponent(u),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}

function reddit_click()
{
  u=location.href;
  t=document.title;
  window.open('http://reddit.com/submit?url='+encodeURIComponent(u)+'&title='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}

function mixx_click()
{
  u=location.href;
  t=document.title;
  window.open('http://www.mixx.com/submit?page_url='+encodeURIComponent(u)+'&title='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}

function email_click(u, t)
{
  if (!u) u=location.href;
  if (!t) t=document.title;
  window.open('/email_share?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}



var faq = {
  toggle : function(el)
  {
    var item = $(el).closest('li');
    item.toggleClass('active');
    if (item.hasClass('active'))
    {
      $('.text', item).slideDown('fast');
    }
    else
    {
      $('.text', item).slideUp('fast');
    }
  }
}

$(document).ready(function()
{
  $('h2', '.faq').click(function(){faq.toggle(this)})
});


function initMembershipForm() {
    if ($.browser.mozilla) $("body").addClass('mozilla');
    scrollControls();
    initShare();
    if (!$("#membershipform, #contributionform").length) return;
    $(".content").addClass('membership');
    $("#membershipform form, #contributionform form").bind('submit', function() { return validateMembershipForm(($(this))); });
    $(".field.radio .option label").bind('click', function() { changeFakeRadio($(this)); });
    $(".field.radio .option input").bind('click', function() { updateRadios($(this)); });
    updateRadios();
    focusOverLabel($(".field.text input").bind('focus', function() { focusOverLabel($(this)); }));
    blurOverLabel($(".field.text input").bind('blur', function() { blurOverLabel($(this)); }));
    $("a.count_label").bind('click', function() {
        if ($(".topframe .banner .page_slider .avatars").length) return false;
        $.post('./renderAvatarSlide',{'popup':1}, function(data) {
            $(".banner .page_slider").append(data);
            scrollControls();
            $("#close").bind('click', function() { $(".banner .page_slider .avatars").remove(); })
        });
        return false;
    });
}

function initShare() {
    var u = $("#share_url").val()
    var t = $("#share_title").val()
    $(".share_facebook").bind('click', function(){ fbs_click(u, t); })
    $(".share_twitter").bind('click', function(){ twitter_click(u, t); })
    $(".share_email").bind('click', function(){ email_click(u, t); })
}

function validateMembershipForm(form) {
    form.find(".field.missing").removeClass('missing');
    var inputs = form.find(":input").not("button, [type='radio'], [type='checkbox']").not("[name^='birthnumber']");
    for (var i = 0, ii=inputs.length; i<ii; i++) {
        var input = inputs.eq(i);
        if (!input.val()) input.parents(".field").addClass('missing');
    }
    var radio = form.find(".field.radio input");
    if (!radio.is(":checked")) radio.parents(".field").addClass('missing');

    var taxCheck = form.find("input[name='taxrefund']");
    var birthNumber = form.find("input[name^='birthnumber']");
    if (taxCheck.length && taxCheck.is(":checked") && birthNumber.length && birthNumber.val().length!=11) birthNumber.parents(".field").addClass('missing');

    if (form.find(".field.missing").length) return false;
    return true;
}

function focusOverLabel(ob) {
    for (var i=0,ii=ob.length; i<ii; i++) ob.eq(i).siblings("label[for='" + ob.eq(i).attr('id') + "']").hide();
}

function blurOverLabel(ob) {
    for (var i=0,ii=ob.length; i<ii; i++) if (!ob.eq(i).val()) ob.siblings("label[for='" + ob.eq(i).attr('id') + "']").show();
}

function changeFakeRadio(label) {
    // This is rather stupid and roundabout, but IE8 wouldn't cooperate on the change event.
    if (label && label.length) {
        var labelFor = label.attr('for');
        var thisRadio = $("#"+labelFor);
        // Double click needed, for some stupid reason (argh, IE)
        thisRadio.click().click();
    }
}
function updateRadios(thisRadio) {
    var radios = $(".field.radio input");
    for (var i = 0, ii=radios.length; i<ii; i++) {
        var radio = radios.eq(i);
        var parent = radio.parents(".option");
        if (radio.is(":checked") || radio==thisRadio) parent.addClass('active');
        else parent.removeClass('active');
    }
}

function scrollControls() {
    var scrollControl = $("#scroll_controls");
    if (!scrollControl.length) return;
    var scrollee = $("#avatars");
    var scrolleeContainer = scrollee.find(".avatar_container");
    var up = scrollControl.find(".scroll_up");
    var down = scrollControl.find(".scroll_down");
    var step = 119;
    down.bind('click', function() {
        scrollAnimate('down',scrollee, step, scrolleeContainer.height());
    });
    up.bind('click', function() {
        scrollAnimate('up', scrollee, step);
    });
    var timeval;
    down.bind('mousedown', function() {
        timeval = setTimeout(function() {
            scrollAnimate('down',scrollee, scrolleeContainer.height(), scrolleeContainer.height(), true);
        }, 200);
    }).bind('mouseup mouseleave', function() {
        clearTimeout(timeval);
        scrollee.stop();
    });
    up.bind('mousedown', function() {
        timeval = setTimeout(function() {
            scrollAnimate('up',scrollee, scrolleeContainer.height(), scrolleeContainer.height(), true);
        }, 200);
    }).bind('mouseup mouseleave', function() {
        clearTimeout(timeval);
        scrollee.stop();
    });
    var keepFetching = true;
    scrollee.infiniteScroll({
            'containerSelector':'.avatar_container',
            'getNext': function(ob, callback) {
                if (keepFetching) {
                    $.get('./renderAvatars', {'start_at':scrolleeContainer.find(".avatar").length}, function(data) {
                        if (data.length) scrolleeContainer.append(data);
                        else keepFetching = false;
                        callback();
                    });
                }
            }

    });
}

function scrollAnimate(dir, scrollee, step, height, calculateTime) {
    if (dir=='up') step = step*-1;
    var newScrollTop = scrollee.scrollTop()+step;
    if (dir=='up' && newScrollTop<0) newScrollTop = 0;
    else if (dir=='down' && height < newScrollTop) newScrollTop = height;
    duration = 'fast';
    if (calculateTime) {
        var absStep = Math.abs(newScrollTop - scrollee.scrollTop());
        duration = parseInt(absStep/0.3);
    }
    scrollee.animate({scrollTop:newScrollTop}, duration);
}

/*
function fbs_click(u, t) {
  if (!u) u=location.href;
  if (!t) t=document.title;
  window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');
  return false;
}
*/


function renderFlashObject(url, width, height, id)
{
  return '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="' + width + '" height="' + height + '" id="' + id + '" align="left">' +
         '  <param name="allowScriptAccess" value="sameDomain" />' +
         '  <param name="movie" value="' + url + '" />' +
         '  <param name="quality" value="high" />' +
         '  <param name="bgcolor" value="#ffffff" />' +
         '  <param name="wmode" value="transparent" />' +
         '  <embed wmode="transparent" src="' + url + '" quality="high" bgcolor="#ffffff" width="' + width + '" height="' + height + '" name="' + id + '" align="left" allowscriptaccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />' +
         '</object>';
}

/* *** */

var imageCache = [];

function PreloadImages()
{
  for (var i=0; i < imgs.length; i++)
  {
    var image = new Image();
    image.src = imgs[i];
    imageCache[imageCache.length] = image;
  }
}

function highlight(el)
{
  if (IE6)
  {
    var cn = el.getAttribute('cn');
    el.className = el.className + ' ' + cn;
  }
}

function nolight(el)
{
  if (IE6)
  {
    var cn = el.getAttribute('cn');
    el.className = el.className.replace(' ' + cn, '');
  }
}

function validateEmail(email) {
  var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
  if(reg.test(email) == false)
    return false;
  return true;
}

function validateForm(el)
{
  var email = $('input[name=user]', el).val();
  if (email == '' || email == 'E-post')
  {
    alert("Du m\xe5 fylle inn en gyldig e-postadresse");
    return false;
  }
  else if (!validateEmail(email))
  {
    alert("Du m\xe5 fylle inn en gyldig e-postadresse");
    return false;
  }

  var chex = $('input:checked', el);
  if (chex.length < 1)
  {
    alert("Du m\xe5 angi kategori");
    return false;
  }  

  return true;
}


// Adds startsWith and endsWith as "builtin" methods on String
String.prototype.startsWith = function(str) {return (this.match("^"+str)==str)}
String.prototype.endsWith = function(str) {return (this.match(str+"$")==str)}

// Functions for rot13 "encoding"
function rot13init() {
	var map = new Array();
	var s = "abcdefghijklmnopqrstuvwxyz";
        slen=s.length;
	for (var i = 0 ; i < slen ; i++)
		map[s.charAt(i)] = s.charAt((i+13)%slen);
	for (var i = 0 ; i < s.length ; i++)
		map[s.charAt(i).toUpperCase()] = s.charAt((i+13)%slen).toUpperCase();
	return map;
}

function str_rot13(a,map) {
	var s = "";
	for (var i = 0 ; i < a.length ; i++) {
		var b = a.charAt(i);
		s += (b>='A' && b<='Z' || b>='a' && b<='z' ? map[b] : b);
	}
	return s;
}

function decodeEmailLinks() {
    var links=$("a");
    var ll=links.length;
    var rotMap = rot13init();
    for (var i=0; i<ll; i++) {
      var link = links.eq(i);
      var href = link.attr('href');
      if (href && href.startsWith('/contact')) {
        var rec_ind = href.indexOf('recipient');
        if (rec_ind>0) {
          var start = href.indexOf('=',rec_ind);
          var titleStart = href.indexOf('&title',start)
          var len  = titleStart - (start+1);
          var encodedAddress = href.substr(start+1, len);
          var title = href.substr(titleStart+20);
          var address=str_rot13(encodedAddress,rotMap)
          link.attr('href', 'mailto:' + address);
          //link.html(decodeURI(title).replace(/\x2b/g," "));
        }
      }
    }
}

function initMyTickbox(ob)
{
  var il = ob.items.length;
  if (il == 1)
  {
    $('.navigation').hide();
    return false;
  }

  // add custom method for handling the tickers
  ob.tickbox_method = function()
  {
    var items = $('div', '.navigation');
    items.removeClass('active');
    $(items[this.current]).addClass('active').fadeIn('fast');

    if (this.current == 0)
      $('.greenlist')[0].scrollTop = 0;
    else
      $('.redlist')[0].scrollTop = 0;
  }
}

function initMyButtons(ob)
{
  $('div', '.navigation').click(function(){$(this).fadeOut('fast'); hideProd(); ob.clicked(this)});
}

function scrollList(dir, list)
{
  var el = $(['.redlist', '.greenlist'][list])
  var y = el[0].scrollTop;
  if (dir == 0)
  {
    el.animate({'scrollTop':y+600, duration:700});
  }
  else
  {
    y = y - 600;
    if (y < 0) y = 0;
    el.animate({'scrollTop':y, duration:700});
  }
}

function showProd(el, event)
{
  $('.product.active', '.icarousel').removeClass('active');
  $(el).addClass('active');
  var html = $('.descr', el).html();
  if (!html) return;

  var pa = $('.prod_arrow');
  var pv = $('.prod_view');
  var h3 = $('h3', el);
  var p_offset = $('.prod_list').offset();
  var h_offset = h3.offset();
  pv.html(html).show();

  var hw = h3.width();
  if (hw > 230) hw = 230;

  var mh = (pv.height()) / 2;
  var mx = p_offset.left + hw + 22;
  var my = h_offset.top - mh;

  pv.css({left:mx, top:my-5, opacity:.95});
  pa.css({left:mx-25, top:my+mh-376}).show(); //416
}

function hideProd(el)
{
  if (el)
    $(el).removeClass('active');
  $('.prod_view').html('').hide();
  $('.prod_arrow').hide();
}

$(document).ready(function()
{
  initMembershipForm();
  $('body').append('<div class="prod_view"></div><div class="prod_arrow arrow-w"></div>');
  //$('.logo').html(renderFlashObject('/images/layout/toppbanner.swf', 990, 120, 'toppbanner'));
  $(".page .text table[align=right]").addClass('marginleft');
  if ($('ul.carousel > li').length>1) $('.carousel').carousel({mode:'circle', auto: 7, transition: .7, buttons:'button sprites', tickbox:true});
  var crsl = $('.icarousel').carousel({mode:'noloop', auto: 0, transition: .7, tickbox: function(self){initMyTickbox(self)}, buttons: function(self){initMyButtons(self)}});
  $('.product', '.icarousel').hover(function(event){showProd(this, event)}, function(){});
  $(".icarousel").touchwipe({
     wipeLeft: function() { hideProd(); crsl.stop(); crsl.goto(1) },
     wipeRight: function() { hideProd(); crsl.stop(); crsl.goto(0) },
     wipeDown: function() { hideProd(); scrollList(0, crsl.current) },
     wipeUp: function() { hideProd(); scrollList(1, crsl.current) },
     min_move_x: 20,
     min_move_y: 30,
     preventDefaultEvents: true
  });
  $('li', '.icarousel').scroll(function(){hideProd()});

  var boxes = $(".boxes .box .body");
  var maxHeight = 0;
  for (var i=0; i<boxes.length; i++) {
    var thisHeight=boxes.eq(i).height();
    if (maxHeight<thisHeight) maxHeight=thisHeight;
  }
  boxes.height(maxHeight);
  //decodeEmailLinks should be called last among the init functions, as it is possibly slow (traverses through all A elements in page)
  decodeEmailLinks();
});

/* Infinite scroll plugin
 * Inspired by http://www.infinite-scroll.com
 */
$.fn.infiniteScroll = function(props, callback) {
    if (!this.length) return this;

    var fns = {
        isNearBottom: function(me) {
            return (me.height()+me.scrollTop()+props.delta)>=me.find(props.containerSelector).height();
        }
    };

    if (!props){props=[];}
    props = $.extend({
                getNext: function() {},
                afterGet: function() {},
                delta: 50,
                containerSelector: '.container'
            },props);

    this.each(function() {
        var me = $(this);
        me.bind('scroll',function() {
            if (!me.ajaxPending && fns.isNearBottom(me)) {
                me.ajaxPending=true;
                props.getNext(me, function(){me.ajaxPending=false;});
            }
        })
    });
}


