
// welcome !
// i'm a javascript developer as well as an mp3 blogger

// everything else in here is pretty clever and groovy
// if you have any questions, hit me on the contact form
// cheers- paul.
 
window.AURGASM = {
  
  context : document.body,


  cats :  [ 'dance', 'electronic', 'experimental', 'folk', 'french', 'funk', 'global', 'hip-hop', 'israeli', 'jazz', 'other', 'pop', 'rock', 'scandinavian', 'singer-songwriter', 'soul', 'reggae', 'classical', 'reflex reaction', 'hey dj friday', 'aurgasm interview', 'aurgasm news', 'aurgasm special'],

  genrecolors : ['magenta', 'pink', 'kellygreen', 'cactus', 'deepblue', 'teal', 'lime', 'basket', 'purple', 'turquoise', 'grey', 'puse', 'burntsienna', 'midnight', 'rouge', 'acloudman', 'purplered', 'brown'],

  
  treatPosts : function(elem){
    AURGASM.context = elem  || document.body; 
    AURGASM.genrePrep();
    AURGASM.imageryPrep();
    AURGASM.buyLinkPrep();
    
    
    AURGASM.actuallyItsQuiteGrand(AURGASM.context);
    $(AURGASM.context).find('form.commentform')
      .submit(AURGASM.clearURLField)
      .find('input:text[value!=""]').inputHint().end();
      // .prev().find('a').click().parent().hide(); // cli
    
  },
  
  
  // fix any post images.
  imageryPrep : function(){

    $('div.reviewtext img',AURGASM.context).each(function(){
      var wid = $(this).width();
      if (wid == 600){    return true;   } 
      else if (wid < 165 ){     $(this).css('background','url('+$(this).attr('src')+') repeat-x 0 0'  ).css('paddingRight',(600-wid)+'px');  }
      else {  $(this).css('padding','0 '+(600-wid)/2+'px');   }
    });    
            
    
  },
  
  // coloring the genres
  genrePrep : function(){
    var context = $('div.post',AURGASM.context);
        context = context.length != 0 ? context : $(AURGASM.context).filter('div.post');
    
    context.each(function(){
    
      if (!$(this).attr('category')) return false;  // if we dont have a genre
      var primarycat = $(this).attr('category').split(',')[0];
      
      
      var $genre = $(this).find('span.genre');
      
      if ($genre.length <= 1){
        $genre.addClass( AURGASM.genrecolors[ $.inArray(primarycat,AURGASM.cats)  ] );
      } else {
        $genre.addClass('oldgenre').removeClass('genre');
      }
      
    
    
      
      // getting that super pretty 1px gap between the things.
      $('strong.boldline',this).each(function(){
        var $this = $(this);
            
        $this.width(  559 - $genre.width() );
        
      });
      
      
    });
    
    
    
  },
  
  // move the buylink outside of the post.
  // hook up click
  buyLinkPrep : function(){
    
    
    
    $('a.buy',AURGASM.context)
      .html('<span>+</span> Purchase / Visit')
      .each(function(){
        $(this).appendTo( $(this).parents('div.post') )
      }).hoverIntent( {    
         sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)    
         interval: 50, // number = milliseconds for onMouseOver polling interval    
         timeout: 200, // number = milliseconds delay before onMouseOut    
         out: function(){ }, 
         over: AURGASM.showBuy 
      })
      .click(AURGASM.showBuy);  
    
    
      
      $('#buyVisit').bind('mouseleave',function(){ $(this).hide() });
      
  },
  
  
  showBuy : function(){
        var off = $(this).offset();
        $('#buyVisit').css({ top:  off.top -4 + 'px' , left: off.left-14 + 'px' }).show();
        AURGASM.setUpBuyLinks( this, $('#buyVisit') );
  },
  
  
  // set the amazon, itunes, google links
  setUpBuyLinks : function(origLink,buyVisit){
    var src = origLink.href, zon = null, itunes = null, web = null;
    var artist = $(origLink).parents('.post').find("h2").text();
    artist = encodeURIComponent(artist);
    var affiliateID = 'aurgasm-20';
    var country = navigator.language || navigator.systemLanguage;
    country = country.split('-')[1];
    
    // detect link we got
    if ( src.match(/amazon/) ) zon = src;
    else if ( src.match(/itunes|apple|phobos/) ) itunes = src;
    else web = src;
    
    // set amazon
    zon = zon || "http://www.amazon.com/gp/search?ie=UTF8&tag=" + affiliateID + "&index=blended&keywords=" + artist;
    
    
    // itunes override
    var ituneslink = $(origLink).attr('itunes') ||   $(origLink).data('itunes');
    if (ituneslink){
      AURGASM.itunesData( undefined,ituneslink , origLink)
    } else {
      var url = 'http://pipes.yahoo.com/pipes/pipe.run?Artist='+artist+'&Country='+country+'&_id=Rsuwwcbk3RGpKIt0rbQIDg&_render=json&_callback=AURGASM.itunesData&callback=?';
      AURGASM.origLink = origLink; // store on the func
      $.getJSON(url);
    }

    //set artist
    web = web || 'http://google.com/search?btnI=1&q='+artist+'+ music';
      
     // amazon override
    if ($(origLink).attr('amazon')){
      zon = $(origLink).attr('amazon');
    }
    
    // website override
    if ($(origLink).attr('web')){
       zon = $(origLink).attr('web');
    }
    
    buyVisit.find('dd.web a').attr('href',web);
    buyVisit.find('a.amazon').attr('href',zon);
    
  }, // end of setupbuylinks

  
  itunesData : function(data,itunes,origLink){
    try{
      if (data && data.value.items[0].results){
        data = data.value.items[0].results;
      } 
      var itunes = itunes ||  (data && data[0].artistLinkUrl);


      if (!itunes){  // die if we still got nothing.
        $('#buyVisit').find('a.itunes').hide();
      }

      // affiliateize it.
      if (itunes.indexOf('linksynergy')==-1 && itunes.indexOf('siteID')==-1  ){
        itunes = itunes.replace('#','').replace('?uo=4','') + (itunes.indexOf('?') > -1 ? '&partnerId=30&siteID=1498801' : '?partnerId=30&siteID=1498801');
        
      }
      
      // cache it 
      origLink = origLink || AURGASM.origLink;   
      $(origLink).data('itunes',itunes);
      
      // set it
      $('#buyVisit a.itunes').attr('href',itunes);
      
    } catch(e){}
      
  }, // end of itunesData
  
  
  infScrollSetup : function(){
    
      // quit if we're on a single post 
      // right now Pages pass this test but should fail
      if (! $('#content').hasClass('narrowcolumn')) return;
   

       $('#content').infinitescroll({
        debug           : false,
        nextSelector    : "div.navigation:last a:first",
        loadingImg      : "/images/ajax-loader.gif",
        text            : "Loading the next posts...",
        donetext        : "<em>Nice! You've hit the end.</em>",
        navSelector     : "div.navigation:last",
        itemSelector    : "#content > div.post"
        },function(elems){ 
          AURGASM.treatPosts(elems);
          if (YAHOO && YAHOO.MediaPlayer){
            $(elems).each(function(){
              YAHOO.MediaPlayer.addTracks && YAHOO.MediaPlayer.addTracks(this);
            })
          }
          AURGASM.dots();
          AURGASM.setUpCommentTogglesInside( $(elems) );
          pageTracker && pageTracker._trackPageview && pageTracker._trackPageview( "/page/"+ this.id.match(/\d/) +"/" );
        });
   
   
        $("div.navigation:last").click(function(){
          
           $(document).trigger('retrieve.infscr');
           $(this).hide();
           return false;
        })
    
    
  },
  
  fixHeights : function(){
    if ($('#content').height() < $('#sidebar').height())  $('#content,#sidebar').setAllToMaxHeight();
  },
  
  colorSideGenres : function(){
  
    $('li.categories li').each(function(){
      var cat = $(this).text().match(/(.*?) \(/)[1];
      $(this).addClass( AURGASM.genrecolors[ $.inArray(cat,AURGASM.cats) ] );
    });

  }, 
  
  dots : function(){
      $('#dots').height( $(document).height() );
  },
  
  contactPage : function(){
    if (!$('#contact').length) return;
 



  },
  
  resourcesPage : function(){
    
    if (!$('#resources').length) return;
  
    var favurl =  ['http://', '/favicon.ico'];
    $('#resources a').each(function(){
      var domain = $(this).attr('href').match(/\/\/(.*?)(\/|$)/)[1];
      $(this).css('background', 'url('+ favurl.join(domain)+ ') no-repeat');
    });
    
  } // eo resources()  


}; // end of AURGASM{}


   
$(function(){
    
  AURGASM.treatPosts();
  AURGASM.colorSideGenres();
  AURGASM.dots();

  AURGASM.setUpCommentTogglesInside( $('#content') );
  
  AURGASM.contactPage();
  //AURGASM.resourcesPage();

  $.browser.msie && $('#sidebar > div').css('zoom',1);   // triger haslayout
  
  
  AURGASM.infScrollSetup();
  
  AURGASM.concerts();
  
  
  $(window).load(function(){ 
      AURGASM.fixHeights(); 
      AURGASM.infiniteListen();
  });  

  

   if ($('#flickr').length){
	$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?id=42168647%40N04&format=json&jsoncallback=?",
	        function(data){
	          var html = '';
	          $.each(data.items, function(i,item){
	            html += $("<img/>").attr("src", item.media.m.replace('m.jpg','b.jpg')).appendTo('<div/>').parent().html();
	            if ( i == 30 ) return false;
	          });
	           $(html).appendTo('#flickr');
	        });
}
});


AURGASM.infiniteListen = function(){
  
  // if we dont have our ducks in a row, wait.
  if (!(YAHOO && YAHOO.MediaPlayer && YAHOO.MediaPlayer.onTrackComplete)) { 
    setTimeout(arguments.callee,500);
    return;
  }
  
  
  YAHOO.MediaPlayer.onTrackComplete.subscribe(function(){
  
    // after complete, is the player at the end?
    if (YAHOO.MediaPlayer.getPlayerState() != 7) return;
    
    //where do we start the music back up?
    var lastSongId =  YAHOO.MediaPlayer.getPlaylistCount();
    
    $(document).bind('ajaxSuccess',function(e,r,s){
      
      // if its an infinite scroll (not a comment submit, etc)
      if (s.url.match(/page\/\d+/)){
        
  
        YAHOO.MediaPlayer.onPlaylistUpdate.subscribe(function(e){
            YAHOO.MediaPlayer.play(e && e[lastSongId]); // this basically queues it
            setTimeout(function(){ 
              if ( YAHOO.MediaPlayer.getPlayerState()==5) YAHOO.MediaPlayer.play(e && e[lastSongId]); // force play!
            },500)
            YAHOO.MediaPlayer.onPlaylistUpdate.unsubscribe(arguments.callee);
        });
  
      }
      
      $(document).unbind('ajaxSuccess',arguments.callee);
    
    });
    
    //trigger infinite-scroll
    window.scrollTo(0,$(document).height());
    
  });
  
}



AURGASM.setUpCommentTogglesInside = function($elem){
  
  if ($.browser.msie && $.browser.version < 7) return; // dont apply for IE users.
  
  $elem.find('a.comment-link').click( function(){
    if ($(this).hasClass('open')){
      $(this).removeClass('open');
      $(this).parent().parent().removeClass('open').find('div.comment-wrap').hide();
    }
    else{
      var ref = $(this).addClass('open').attr('href').replace(/((%23)|#)comments/,'');
      $(this)
      .parent()
        .parent().addClass('open')
          .find('div.comment-wrap')
          .show()
          .html('<div class="comment-loading">Loading the comments...</div>').parent().css('zoom',1).end();
          
      $(this)
      .parent()
        .parent()
        .find('div.comment-wrap')
          .load(ref +' #content div.comment-block',null, function(){
            AURGASM.setUpAjaxCommentSubmitsInside($(this));
          });

          // fix purchase/visit link.
          var post = $(this).parents('div.post');
          post.find('a.buy').css({top: $(this).offsetFrom('.post').top-4 +'px',bottom:'auto'})
         
    }
  return false;
  });
}

AURGASM.clearURLField = function(form){
    var web = $(this).find('input[name=url]');
    if (web.val()=="Website" || web.val()=='website') web.val('');
}

// :-p
AURGASM.actuallyItsQuiteGrand = function(elem){
  
  $(elem).find('cite a').each(function(){
    if ($(this).text().match(/music\s?sucks/gi))
      $(this).text('I Fancy This Music');      
  });
  
}


AURGASM.setUpAjaxCommentSubmitsInside = function($elem){
  
  AURGASM.actuallyItsQuiteGrand($elem);
  
    
  $('input:text[value!=""]',$elem).inputHint();
  
  
  $elem.find('form.commentform').each(function(i,elem){
    $(elem).ajaxForm({
      beforeSubmit: function(){
        AURGASM.clearURLField.apply(elem);
        $(elem).hide().prev().replaceWith('<div class="comment-loading"/>');
      },
      success: function(){
        var author = $(elem).find('input[name="author"]').val();
        var url = $(elem).find('input[name="url"]').val();
        var comment = $(elem).find('textarea[name="comment"]').val();
        var str = '<cite>';
        if (url) { str += '<a rel="external nofollow" href="'+url+'">' };
        str += author;
        if (url) { str += '</a>' };
        str += '</cite> Says: <br/><p>' + comment + '</p>';
        var theol = $elem.find('ol:first');
        $('<li/>').html(str).appendTo(theol);
        $elem.parent().find('div.comment-loading,form').remove();
      }});
  });
}

// legacy
function popup(mylink, animation){
  if (! window.focus) {return true;}
  var href;
  if (typeof(mylink) == 'string'){
	href=mylink;}
  else{
	href=mylink.href;}
  window.open(href, animation, 'width=290,height=237,resizable=no,scrollbars=no');
  return false;
}

AURGASM.theLinkList = function(){


  var feed = new google.feeds.Feed("http://feeds2.feedburner.com/aurgasmlinklist");
  feed.setNumEntries(10);
  feed.load(function(result) {
    if (!result.error) {
      var container = document.getElementById("linklistcontainer");
      var ul = document.createElement("ul");
      for (var i = 0; i < result.feed.entries.length; i++) {
        var entry = result.feed.entries[i];
        var li = document.createElement("li");
        var a = document.createElement("a");
        var span = document.createElement("span")
        li.appendChild(a);
        a.href = entry.link;
        a.innerHTML = entry.title+' ';
        span.innerHTML = ' '+entry.content;
        li.appendChild(span);
        ul.appendChild(li);
      }
      container && container.appendChild(ul);
    }
  });



};


AURGASM.concerts = function(){
  
    if (!$('#concerts').length) return;
  
    var url =   'http://api.songkick.com/api/3.0/blogs/19/events.json?apikey=WvaKBTMQlzQF8f9G&'+
                'jsoncallback=songkickcallback&callback=?&location=clientip&per_page=14',
        resultsstr = '';



    $.getJSON(url);

    window.songkickcallback = function(data){
        var results = window.da = data.resultsPage.results.event;
        $.each(results,function(k,v){
            resultsstr += tmpl('item_tmpl',v);


        });

        $('#concerts').html(resultsstr);

    };

    
};

// http://www.malsup.com/jquery/form/
(function($){$.fn.ajaxSubmit=function(options){if(typeof options=='function')options={success:options};options=$.extend({url:this.attr('action')||window.location.toString(),type:this.attr('method')||'GET'},options||{});var veto={};$.event.trigger('form.pre.serialize',[this,options,veto]);if(veto.veto)return this;var a=this.formToArray(options.semantic);if(options.data){for(var n in options.data)a.push({name:n,value:options.data[n]})}if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false)return this;$.event.trigger('form.submit.validate',[a,this,options,veto]);if(veto.veto)return this;var q=$.param(a);if(options.type.toUpperCase()=='GET'){options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;options.data=null}else options.data=q;var $form=this,callbacks=[];if(options.resetForm)callbacks.push(function(){$form.resetForm()});if(options.clearForm)callbacks.push(function(){$form.clearForm()});if(!options.dataType&&options.target){var oldSuccess=options.success||function(){};callbacks.push(function(data){if(this.evalScripts)$(options.target).attr("innerHTML",data).evalScripts().each(oldSuccess,arguments);else $(options.target).html(data).each(oldSuccess,arguments)})}else if(options.success)callbacks.push(options.success);options.success=function(data,status){for(var i=0,max=callbacks.length;i<max;i++)callbacks[i](data,status,$form)};var files=$('input:file',this).fieldValue();var found=false;for(var j=0;j<files.length;j++)if(files[j])found=true;if(options.iframe||found){if($.browser.safari&&options.closeKeepAlive)$.get(options.closeKeepAlive,fileUpload);else fileUpload()}else $.ajax(options);$.event.trigger('form.submit.notify',[this,options]);return this;function fileUpload(){var form=$form[0];var opts=$.extend({},$.ajaxSettings,options);var id='jqFormIO'+$.fn.ajaxSubmit.counter++;var $io=$('<iframe id="'+id+'" name="'+id+'" />');var io=$io[0];var op8=$.browser.opera&&window.opera.version()<9;if($.browser.msie||op8)io.src='javascript:false;document.write("");';$io.css({position:'absolute',top:'-1000px',left:'-1000px'});var xhr={responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){}};var g=opts.global;if(g&&!$.active++)$.event.trigger("ajaxStart");if(g)$.event.trigger("ajaxSend",[xhr,opts]);var cbInvoked=0;var timedOut=0;setTimeout(function(){var encAttr=form.encoding?'encoding':'enctype';var t=$form.attr('target'),a=$form.attr('action');$form.attr({target:id,method:'POST',action:opts.url});form[encAttr]='multipart/form-data';if(opts.timeout)setTimeout(function(){timedOut=true;cb()},opts.timeout);$io.appendTo('body');io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false);form.submit();$form.attr({action:a,target:t})},10);function cb(){if(cbInvoked++)return;io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);var ok=true;try{if(timedOut)throw'timeout';var data,doc;doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;xhr.responseText=doc.body?doc.body.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(opts.dataType=='json'||opts.dataType=='script'){var ta=doc.getElementsByTagName('textarea')[0];data=ta?ta.value:xhr.responseText;if(opts.dataType=='json')eval("data = "+data);else $.globalEval(data)}else if(opts.dataType=='xml'){data=xhr.responseXML;if(!data&&xhr.responseText!=null)data=toXml(xhr.responseText)}else{data=xhr.responseText}}catch(e){ok=false;$.handleError(opts,xhr,'error',e)}if(ok){opts.success(data,'success');if(g)$.event.trigger("ajaxSuccess",[xhr,opts])}if(g)$.event.trigger("ajaxComplete",[xhr,opts]);if(g&&!--$.active)$.event.trigger("ajaxStop");if(opts.complete)opts.complete(xhr,ok?'success':'error');setTimeout(function(){$io.remove();xhr.responseXML=null},100)};function toXml(s,doc){if(window.ActiveXObject){doc=new ActiveXObject('Microsoft.XMLDOM');doc.async='false';doc.loadXML(s)}else doc=(new DOMParser()).parseFromString(s,'text/xml');return(doc&&doc.documentElement&&doc.documentElement.tagName!='parsererror')?doc:null}}};$.fn.ajaxSubmit.counter=0;$.fn.ajaxForm=function(options){return this.ajaxFormUnbind().submit(submitHandler).each(function(){this.formPluginId=$.fn.ajaxForm.counter++;$.fn.ajaxForm.optionHash[this.formPluginId]=options;$(":submit,input:image",this).click(clickHandler)})};$.fn.ajaxForm.counter=1;$.fn.ajaxForm.optionHash={};function clickHandler(e){var $form=this.form;$form.clk=this;if(this.type=='image'){if(e.offsetX!=undefined){$form.clk_x=e.offsetX;$form.clk_y=e.offsetY}else if(typeof $.fn.offset=='function'){var offset=$(this).offset();$form.clk_x=e.pageX-offset.left;$form.clk_y=e.pageY-offset.top}else{$form.clk_x=e.pageX-this.offsetLeft;$form.clk_y=e.pageY-this.offsetTop}}setTimeout(function(){$form.clk=$form.clk_x=$form.clk_y=null},10)};function submitHandler(){var id=this.formPluginId;var options=$.fn.ajaxForm.optionHash[id];$(this).ajaxSubmit(options);return false};$.fn.ajaxFormUnbind=function(){this.unbind('submit',submitHandler);return this.each(function(){$(":submit,input:image",this).unbind('click',clickHandler)})};$.fn.formToArray=function(semantic){var a=[];if(this.length==0)return a;var form=this[0];var els=semantic?form.getElementsByTagName('*'):form.elements;if(!els)return a;for(var i=0,max=els.length;i<max;i++){var el=els[i];var n=el.name;if(!n)continue;if(semantic&&form.clk&&el.type=="image"){if(!el.disabled&&form.clk==el)a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});continue}var v=$.fieldValue(el,true);if(v&&v.constructor==Array){for(var j=0,jmax=v.length;j<jmax;j++)a.push({name:n,value:v[j]})}else if(v!==null&&typeof v!='undefined')a.push({name:n,value:v})}if(!semantic&&form.clk){var inputs=form.getElementsByTagName("input");for(var i=0,max=inputs.length;i<max;i++){var input=inputs[i];var n=input.name;if(n&&!input.disabled&&input.type=="image"&&form.clk==input)a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y})}}return a};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic))};$.fn.fieldSerialize=function(successful){var a=[];this.each(function(){var n=this.name;if(!n)return;var v=$.fieldValue(this,successful);if(v&&v.constructor==Array){for(var i=0,max=v.length;i<max;i++)a.push({name:n,value:v[i]})}else if(v!==null&&typeof v!='undefined')a.push({name:this.name,value:v})});return $.param(a)};$.fn.fieldValue=function(successful){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,successful);if(v===null||typeof v=='undefined'||(v.constructor==Array&&!v.length))continue;v.constructor==Array?$.merge(val,v):val.push(v)}return val};$.fieldValue=function(el,successful){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(typeof successful=='undefined')successful=true;if(successful&&(!n||el.disabled||t=='reset'||t=='button'||(t=='checkbox'||t=='radio')&&!el.checked||(t=='submit'||t=='image')&&el.form&&el.form.clk!=el||tag=='select'&&el.selectedIndex==-1))return null;if(tag=='select'){var index=el.selectedIndex;if(index<0)return null;var a=[],ops=el.options;var one=(t=='select-one');var max=(one?index+1:ops.length);for(var i=(one?index:0);i<max;i++){var op=ops[i];if(op.selected){var v=$.browser.msie&&!(op.attributes['value'].specified)?op.text:op.value;if(one)return v;a.push(v)}}return a}return el.value};$.fn.clearForm=function(){return this.each(function(){$('input,select,textarea',this).clearFields()})};$.fn.clearFields=$.fn.clearInputs=function(){return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(t=='text'||t=='password'||tag=='textarea')this.value='';else if(t=='checkbox'||t=='radio')this.checked=false;else if(tag=='select')this.selectedIndex=-1})};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType))this.reset()})};$.fn.enable=function(b){if(b==undefined)b=true;return this.each(function(){this.disabled=!b})};$.fn.select=function(select){if(select==undefined)select=true;return this.each(function(){var t=this.type;if(t=='checkbox'||t=='radio')this.checked=select;else if(this.tagName.toLowerCase()=='option'){var $sel=$(this).parent('select');if(select&&$sel[0]&&$sel[0].type=='select-one'){$sel.find('option').select(false)}this.selected=select}})}})(jQuery);


/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
* 
* @param  f  onMouseOver function || An object with configuration options
* @param  g  onMouseOut function  || Nothing (use configuration options object)
* @author    Brian Cherne <brian@cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);


(function($){

    // hinting with default values for text input items. 
    // usage: $(':text[value!=""]').inputHint();
    // author: paul irish
    $.fn.inputHint = function(){
      return $(this)
        .each(function(){ 
          $(this).data('default', $(this).val());
        })
        .focus(function(){
          ($(this).val()===$(this).data('default')) && $(this).val('');
        })
        .blur(function(){
          ($(this).val()==='') && $(this).val($(this).data('default'));
        });
    }



     $.fn.setAllToMaxHeight = function(){
      this.css('min-height','').css('min-height'+ Math.max.apply(this, $.map( this , function(e){ return $(e).height() }) ) +'px')
      return this;
    }



    $.fn.offsetFrom = function(parentElem){
      var po = $(parentElem).offset();
      var to = $(this).offset();
      return { left: to.left - po.left, top: to.top - po.top};
    }

})(jQuery);

// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
  var cache = {};
 
  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :
     
      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function("obj",
        "var p=[],print=function(){p.push.apply(p,arguments);};" +
       
        // Introduce the data as local variables using with(){}
        "with(obj){p.push('" +
       
        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, " ")
          .split("<%").join("\t")
          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
          .replace(/\t=(.*?)%>/g, "',$1,'")
          .split("\t").join("');")
          .split("%>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");
   
    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();





/*!
// Infinite Scroll jQuery plugin
// copyright Paul Irish, licensed GPL & MIT
// version 1.5.100504

// home and docs: http://www.infinite-scroll.com
*/
 
;(function($){
    
  $.fn.infinitescroll = function(options,callback){
    
    // console log wrapper.
    function debug(){
      if (opts.debug) { window.console && console.log.call(console,arguments)}
    }
    
    // grab each selector option and see if any fail.
    function areSelectorsValid(opts){
      for (var key in opts){
        if (key.indexOf && key.indexOf('Selector') > -1 && $(opts[key]).length === 0){
            debug('Your ' + key + ' found no elements.');    
            return false;
        } 
        return true;
      }
    }


    // find the number to increment in the path.
    function determinePath(path){
      
      path.match(relurl) ? path.match(relurl)[2] : path; 

      // there is a 2 in the url surrounded by slashes, e.g. /page/2/
      if ( path.match(/^(.*?)\b2\b(.*?$)/) ){  
          path = path.match(/^(.*?)\b2\b(.*?$)/).slice(1);
      } else 
        // if there is any 2 in the url at all.
        if (path.match(/^(.*?)2(.*?$)/)){
          
          // page= is used in django:
          //   http://www.infinite-scroll.com/changelog/comment-page-1/#comment-127
          if ( path.match(/^(.*?page=)2(\/.*|$)/) ){
            path = path.match(/^(.*?page=)2(\/.*|$)/).slice(1);
            return path;
          }
          
          debug('Trying backup next selector parse technique. Treacherous waters here, matey.');
          path = path.match(/^(.*?)2(.*?$)/).slice(1);
      } else {
          
        // page= is used in drupal too but second page is page=1 not page=2:
        // thx Jerod Fritz, vladikoff
        if (path.match(/^(.*?page=)1(\/.*|$)/)) {
          path = path.match(/^(.*?page=)1(\/.*|$)/).slice(1);
          return path;
        }  

        debug('Sorry, we couldn\'t parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.');    
        props.isInvalidPage = true;  //prevent it from running on this page.
      }
      
      return path;
    }


    // 'document' means the full document usually, but sometimes the content of the overflow'd div in local mode
    function getDocumentHeight(){
      // weird doubletouch of scrollheight because http://soulpass.com/2006/07/24/ie-and-scrollheight/
      return opts.localMode ? ($(props.container)[0].scrollHeight && $(props.container)[0].scrollHeight) 
                                // needs to be document's height. (not props.container's) html's height is wrong in IE.
                                : $(document).height()
    }
    
    
        
    function isNearBottom(){
      
      // distance remaining in the scroll
      // computed as: document height - distance already scroll - viewport height - buffer
      var pixelsFromWindowBottomToBottom = 0 +
                getDocumentHeight()  - (
                    opts.localMode ? $(props.container).scrollTop() : 
                    // have to do this bs because safari doesnt report a scrollTop on the html element
                    ($(props.container).scrollTop() || $(props.container.ownerDocument.body).scrollTop())
                    ) - $(opts.localMode ? props.container : window).height();
      
      debug('math:',pixelsFromWindowBottomToBottom, props.pixelsFromNavToBottom);
      
      // if distance remaining in the scroll (including buffer) is less than the orignal nav to bottom....
      return (pixelsFromWindowBottomToBottom  - opts.bufferPx < props.pixelsFromNavToBottom);    
    }    
    
    function showDoneMsg(){
      props.loadingMsg
        .find('img').hide()
        .parent()
          .find('div').html(opts.donetext).animate({opacity: 1},2000).fadeOut('normal');
      
      // user provided callback when done    
      opts.errorCallback();
    }
    
    function infscrSetup(){
    
        if (props.isDuringAjax || props.isInvalidPage || props.isDone) return; 
        
        if ( !isNearBottom(opts,props) ) return; 
        
        $(document).trigger('retrieve.infscr');
                
                
    }  // end of infscrSetup()
          
  
      
    function kickOffAjax(){
        
        // we dont want to fire the ajax multiple times
        props.isDuringAjax = true; 
        
        // show the loading message and hide the previous/next links
        props.loadingMsg.appendTo( opts.contentSelector ).show();
        $( opts.navSelector ).hide(); 
        
        // increment the URL bit. e.g. /page/3/
        props.currPage++;
        
        debug('heading into ajax',path);
        
        // if we're dealing with a table we can't use DIVs
        box = $(opts.contentSelector).is('table') ? $('<tbody/>') : $('<div/>');  
        frag = document.createDocumentFragment();


        box.load( path.join( props.currPage ) + ' ' + opts.itemSelector,null,loadCallback); 
        
    }
    
    function loadCallback(){
        // if we've hit the last page...
        if (props.isDone){ 
            showDoneMsg();
            return false;    
              
        } else {
          
            var children = box.children().get();
            
            // if it didn't return anything
            if (children.length == 0){
              // fake an ajaxError so we can quit.
              return $.event.trigger( "ajaxError", [{status:404}] ); 
            } 
            
            // use a documentFragment because it works when content is going into a table or UL
            while (box[0].firstChild){
              frag.appendChild(  box[0].firstChild );
            }

           	$(opts.contentSelector)[0].appendChild(frag);
            
            // fadeout currently makes the <em>'d text ugly in IE6
            props.loadingMsg.fadeOut('normal' ); 

            // smooth scroll to ease in the new content
            if (opts.animate){ 
                var scrollTo = $(window).scrollTop() + $('#infscr-loading').height() + opts.extraScrollPx + 'px';
                $('html,body').animate({scrollTop: scrollTo}, 800,function(){ props.isDuringAjax = false; }); 
            }
        
            // previously, we would pass in the new DOM element as context for the callback
            // however we're now using a documentfragment, which doesnt havent parents or children,
            // so the context is the contentContainer guy, and we pass in an array
            //   of the elements collected as the first argument.
            callback.call( $(opts.contentSelector)[0], children );
        
            if (!opts.animate) props.isDuringAjax = false; // once the call is done, we can allow it again.
        }
    }
    
      
    // lets get started.
    $.browser.ie6 = $.browser.msie && $.browser.version < 7;
    
    var opts    = $.extend({}, $.infinitescroll.defaults, options),
        props   = $.infinitescroll, // shorthand
        box, frag;
        
    callback    = callback || function(){};
    
    if (!areSelectorsValid(opts)){ return false;  }
    
     // we doing this on an overflow:auto div?
    props.container   =  opts.localMode ? this : document.documentElement;
                          
    // contentSelector we'll use for our .load()
    opts.contentSelector = opts.contentSelector || this; 
    
    
    // get the relative URL - everything past the domain name.
    var relurl        = /(.*?\/\/).*?(\/.*)/,
        path          = $(opts.nextSelector).attr('href');
    
    
    if (!path) { debug('Navigation selector not found'); return; }
    
    // set the path to be a relative URL from root.
    path          = determinePath(path);
    

    // reset scrollTop in case of page refresh:
    if (opts.localMode) $(props.container)[0].scrollTop = 0;

    // distance from nav links to bottom
    // computed as: height of the document + top offset of container - top offset of nav link
    props.pixelsFromNavToBottom =  getDocumentHeight()  +
                                     (props.container == document.documentElement ? 0 : $(props.container).offset().top )- 
                                     $(opts.navSelector).offset().top;
    
    // define loading msg
    props.loadingMsg = $('<div id="infscr-loading" style="text-align: center;"><img alt="Loading..." src="'+
                                  opts.loadingImg+'" /><div>'+opts.loadingText+'</div></div>');    
     // preload the image
    (new Image()).src    = opts.loadingImg;
              

  
    // set up our bindings
    $(document).ajaxError(function(e,xhr,opt){
      debug('Page not found. Self-destructing...');    
      
      // die if we're out of pages.
      if (xhr.status == 404){ 
        showDoneMsg();
        props.isDone = true; 
        $(opts.localMode ? this : window).unbind('scroll.infscr');
      } 
    });
    
    // bind scroll handler to element (if its a local scroll) or window  
    $(opts.localMode ? this : window)
      .bind('scroll.infscr', infscrSetup)
      .trigger('scroll.infscr'); // trigger the event, in case it's a short page
    
    $(document).bind('retrieve.infscr',kickOffAjax);
    
    
    $(window).load(function(){
    
      if ($(opts.navSelector).offset().top < jQuery('div.foot:last').offset().top)
         $(document).trigger('retrieve.infscr');
    
    })
    
    
    return this;
  
  }  // end of $.fn.infinitescroll()
  

  
  // options and read-only properties object
  
  $.infinitescroll = {     
        defaults      : {
                          debug           : false,
                          preload         : false,
                          nextSelector    : "div.navigation a:first",
                          loadingImg      : "http://www.infinite-scroll.com/loading.gif",
                          loadingText     : "<em>Loading the next set of posts...</em>",
                          donetext        : "<em>Congratulations, you've reached the end of the internet.</em>",
                          navSelector     : "div.navigation",
                          contentSelector : null,           // not really a selector. :) it's whatever the method was called on..
                          extraScrollPx   : 150,
                          itemSelector    : "div.post",
                          animate         : false,
                          localMode      : false,
                          bufferPx        : 40,
                          errorCallback   : function(){}
                        }, 
        loadingImg    : undefined,
        loadingMsg    : undefined,
        container     : undefined,
        currPage      : 1,
        currDOMChunk  : null,  // defined in setup()'s load()
        isDuringAjax  : false,
        isInvalidPage : false,
        isDone        : false  // for when it goes all the way through the archive.
  };
  


})(jQuery);
