//! ################################################################
//! Copyright (c) 2008 Amazon.com, Inc., and its Affiliates.
//! All rights reserved.
//! Not to be reused without permission
//! $Change: 313315 $
//! $Revision: #19 $
//! $DateTime: 2009/01/14 18:47:29 $
//! ################################################################
(function($){var TypeChecker={typeOf:function(value){var s=typeof value;if(s!=='object'){return s;}
if(!value){return'null';}
if(typeof value.length==='number'&&!value.propertyIsEnumerable('length')&&typeof value.splice==='function'){return'array';}
return s;},checkArgTypes:function(){var args=[].slice.apply(arguments);var callerArguments=args.shift();this.checkNumArgs(callerArguments);for(var i=0;i<args.length;i++){this.assertType(callerArguments[i],args[i]);}},checkNumArgs:function(callerArguments){if(callerArguments.callee.length!==callerArguments.length){throw'wrong number of args: got '+callerArguments.length+
' but expected '+callerArguments.callee.length;}},assertTypeIs:function(object,type){this.checkNumArgs(arguments);if(this.typeOf(object)!==type){throw'Type Error: got '+this.typeOf(object)+' but expected '+type;}},assertTypeIsOneOf:function(){var args=[].slice.apply(arguments);var object=args.shift();var self=this;if(!Boolean($.grep(args,function(elt){return self.typeOf(object)===elt;}).length)){throw'Type Error: got '+this.typeOf(object)+' but expected one of: '+args;}}};var ConsoleLogger=function(){this.level=ConsoleLogger.levels.debug;this.logMethodEntries=true;};ConsoleLogger.levels={debug:1,info:2,warn:3,error:4};$.extend(ConsoleLogger.prototype,{enter:function(methodName,args){if(this.logMethodEntries){var suffix="";if(args!==undefined){var args2=[];for(var i=0;i<args.length;i++){args2.push(args[i]===undefined?"undefined":args[i].toString());}
suffix=" with args: ["+args2+"]";}
this.info("Entering method %s%s",methodName,suffix);}},debug:function(){if(!window.console||!console.debug){return;}
if(this.level<=ConsoleLogger.levels.debug){console.debug.apply(console,arguments);}},info:function(){if(!window.console||!console.info){return;}
if(this.level<=ConsoleLogger.levels.info){console.info.apply(console,arguments);}},warn:function(){if(!window.console||!console.warn){return;}
if(this.level<=ConsoleLogger.levels.warn){console.warn.apply(console,arguments);}},error:function(){if(!window.console||!console.error){return;}
if(this.level<=ConsoleLogger.levels.error){console.error.apply(console,arguments);}}});var log=new ConsoleLogger();if($.fn.shoveler){log.warn("Shoveler already loaded!! Re-loading!!");}
$.fn.shoveler=function(generator,numCellsTotal,options){if(this.size()!==1){throw"must only init one shoveler at a time but you are trying to init "+this.size();}
return new Shoveler(this,generator,numCellsTotal,options);};var Shoveler=function(domElement,generator,numCellsTotal,options){if(this===window){throw new Error("Shoveler must be called with 'new'");}
if(!domElement||typeof domElement!=='object'){throw new Error("Must give a domElement object param to Shoveler");}
this.root=$(domElement);if(!this.root.hasClass('shoveler')){log.warn("jQuery must be initialized with an element with a class of 'shoveler'");}
if(!generator||typeof generator!=='function'){throw new Error("Must give a function generator param to Shoveler");}
var defaultOptions={cellTransformer:function(input){return input;},cellChangeSpeedInMs:50,ajaxTimeout:3000,onPageChangeCompleteHandler:function(){},paginationSelector:'.shoveler-pagination',rootUlSelector:'ul:first',prevButtonSelector:'div.prev-button',nextButtonSelector:'div.next-button',circular:true,preloadNextPage:false,horizPadding:0};$.extend(this,defaultOptions,options||{});this.rootUl=$(this.rootUlSelector,domElement);if(this.rootUl.size()!==1){throw new Error('Shovler must be initialized with an element with a single UL descendant');}
if(!$(this.paginationSelector,this.root).size()){throw new Error("Shoveler div must have a '"+this.paginationSelector+"'");}
this.generator=function(){var ret=generator.apply(this,arguments);if(!ret&&!ret instanceof'string'&&!ret instanceof Array){throw new Error("Generator should return string or array, but instead returned: "+ret.toString());}
return ret;};this.numCellsTotal=numCellsTotal;this.currentCell=0;this.cache=[];var data=this.getAllCells().map(function(){return $(this).html();});for(var i=this.cache.length;i<this.numCellsTotal;i++){this.cache[i]=i;}
this.updateCache(0,true,data,false);if(!$(this.paginationSelector,this.root).find('.page-number').size()||!$(this.paginationSelector,this.root).find('.num-pages').size())
{$(this.paginationSelector,this.root).prepend($('<span>Page '+
'<span class="page-number">???</span> of '+
'<span class="num-pages">???</span> '+
'<span class="start-over"> (<a href="">Start Over</a>) </span>'+
'<span class="debug-info"> '+
'cell:<span class="cell-number">0</span>, '+
'numVisible=<span class="num-visible">???</span>'+
'</span></span>'));}
var self=this;$('span.start-over',this.root).click(function(){self.gotoFirstPage();return false;});$(this.prevButtonSelector,this.root).click(function(){if(!self.isFirstPage()){self.gotoPage(Math.ceil(self.getCurrentPage()-1));}
else if(self.circular){self.gotoPage(self.getNumPages()-1,true);}});$(this.nextButtonSelector,this.root).click(function(){if(!self.isLastPage()){self.gotoPage(Math.floor(self.getCurrentPage()+1));}
else if(self.circular){self.gotoPage(0,true);}});$(this.prevButtonSelector,this.root).add($(this.nextButtonSelector,this.root))
.mousedown(function(){$(this).addClass('depressed');})
.mouseup(function(){$(this).removeClass('depressed');});$(window).resize(function(){self.updateUI();});this.updateUI();};$.extend(Shoveler.prototype,{updateUI:function(){this.adjustNumLisInDom();this.getNewCellsIfNeeded();this.updateVisibleCellsImmediately(this.currentCell);this.updateStats();var buttons=$(this.prevButtonSelector,this.root).add($(this.nextButtonSelector,this.root));buttons[this.shouldShowScrollButtons()?'show':'hide']();},alreadyInitedUI:false,initialUpdateUI:function(){if(!this.alreadyInitedUI){this.alreadyInitedUI=true;this.updateUI();}},shouldShowScrollButtons:function(){return this.getNumPages()>1||this.currentCell!==0;},updateStats:function(){var pagination=$(this.paginationSelector,this.root);pagination[this.shouldShowScrollButtons()?'show':'hide']();$('.page-number',this.root).text((1+Math.floor(this.getCurrentPage()))+" ");$('.num-pages',this.root).text(this.getNumPages()+" ");$('.cell-number',this.root).text(""+this.currentCell);$('.num-visible',this.root).text(""+this.getNumCellsPerPage());$('span.start-over',this.root).css('display',this.isFirstPage()?'none':'');if(!this.circular){$(this.nextButtonSelector,this.root)[this.isLastPage()?'addClass':'removeClass']('disabled');$(this.prevButtonSelector,this.root)[this.isFirstPage()?'addClass':'removeClass']('disabled');}},getCurrentPage:function(){return this.currentCell/this.getNumCellsPerPage();},isMidPage:function(){return!!(this.currentCell%this.getNumCellsPerPage());},isLastPage:function(){return this.currentCell+this.getNumCellsPerPage()>=this.numCellsTotal;},isFirstPage:function(){return this.getCurrentPage()===0;},getNumCellsPerPage:function(){return this.getAllCells().size();},getNumPages:function(){return Math.ceil(this.numCellsTotal/this.getNumCellsPerPage());},getAllCells:function(){return this.rootUl.find('> li');},adjustNumLisInDom:function(){if(this.getAllCells().size()===0){this.rootUl.append($('<li>'));}
var totalWidth=this.rootUl.width();var cellWidth=this.getAllCells().width();if(cellWidth===0){return;}
cellWidth+=this.horizPadding;var cellsPerPage=Math.floor(totalWidth/cellWidth);var remainingSpace=totalWidth%cellWidth;var actualCellsPerPage=this.getNumCellsPerPage();var difference=cellsPerPage-actualCellsPerPage;if(difference===0){}
while(difference>0){this.rootUl.append($('<li>'));difference--;}
while(difference<0){this.rootUl.find('> li:last').remove();difference++;}
var margin=Math.floor(remainingSpace/cellsPerPage/2);margin+=(this.horizPadding/2);this.getAllCells().css({'margin-left':margin+'px','margin-right':margin+'px'});},isCellEmpty:function(value){return typeof value==='undefined'||typeof value==='number';},isCacheEmpty:function(originalCacheIndex){return $.inArray(originalCacheIndex,this.cache)>=0;},cacheUpdated:function(wasAjax){if(!this.animInProgress()){this.updateVisibleCellsImmediately(this.currentCell);this.onPageChangeCompleteHandler();this.updateUI();}
else if(wasAjax){this.pendingAsyncDataRequiresPageRefresh=true;}},getNewCellsIfNeeded:function(){var numToFetch=this.getNumCellsPerPage();if(this.currentCell!=0&&this.preloadNextPage){numToFetch*=2;}
var slice=this.cache.slice(this.currentCell,this.currentCell+numToFetch);slice=$.grep(slice,function(item,index){return typeof item==='number';});if(!slice.length){return;}
var originalStartIndex=slice[0];var numCells=slice.pop()-originalStartIndex+1;var data=this.generator(originalStartIndex,numCells);if(typeof data!=="string"){this.updateCache(originalStartIndex,false,data,false);}
else{log.info("making ajax call to %s",data);var self=this;$.ajax({url:data,dataType:"json",timeout:self.ajaxTimeout,error:function(){log.warn("failed ajax request to %s",data);},success:function(jsonObjArray){log.info("Got json data by ajax: %s",jsonObjArray);if(!jsonObjArray||!jsonObjArray instanceof Array){throw"unexpected value returned from ajax call: "+
(jsonObjArray?(typeof jsonObjArray):jsonObjArray);}
if(jsonObjArray.length<numCells){log.error("Got less cells than expected. Got %s but expected %s",jsonObjArray.length,numCells);jsonObjArray.length=numCells;}
self.updateCache(originalStartIndex,false,jsonObjArray,true);}});}},switchVisibleCellsInterval:null,animInProgress:function(){return this.switchVisibleCellsInterval!==null;},switchVisibleCells:function(lastDirection,wrapped){if(this.animInProgress()){log.warn("animation already in progress");clearInterval(this.switchVisibleCellsInterval);this.switchVisibleCellsInterval=null;}
var animateFromRightToLeft=(lastDirection===1);var decrement=lastDirection;if(wrapped){animateFromRightToLeft=!animateFromRightToLeft;decrement*=-1;}
var indexWithinPage=animateFromRightToLeft?this.getNumCellsPerPage()-1:0;var endIndexWithinPage=animateFromRightToLeft?0:this.getNumCellsPerPage()-1;var startCell=this.currentCell;var self=this;var finishCellUpdate=function(){clearInterval(self.switchVisibleCellsInterval);self.switchVisibleCellsInterval=null;if(self.pendingAsyncDataRequiresPageRefresh){self.updateVisibleCellsImmediately(startCell);}
self.onPageChangeCompleteHandler();self.updateUI();};if(lastDirection===0){this.getAllCells().find(' > div').css('display','none');this.switchVisibleCellsInterval=setInterval(function(){for(var i=startCell;i<self.getNumCellsPerPage();i++){self.updateCellIfVisible(i);}
finishCellUpdate();},this.cellChangeSpeedInMs*2);}else{this.switchVisibleCellsInterval=setInterval(function(){var currentCacheIndex=startCell+indexWithinPage;self.updateCellIfVisible(currentCacheIndex);if(indexWithinPage===endIndexWithinPage){finishCellUpdate();return;}
indexWithinPage-=decrement;},this.cellChangeSpeedInMs);}},updateVisibleCellsImmediately:function(startCell){this.pendingAsyncDataRequiresPageRefresh=false;for(var i=0;i<this.getNumCellsPerPage();i++){var cacheIndex=startCell+i;this.updateCellIfVisible(cacheIndex);}},updateCellIfVisible:function(currentCacheIndex){var cellIndex=currentCacheIndex-this.currentCell;var li=this.getAllCells().eq(cellIndex);if(!this.isCellEmpty(this.cache[currentCacheIndex])){var html=this.cache[currentCacheIndex].data;if(html){var images=$('img',html);var count=images.length;images.each(function(){var preload=new Image();preload.src=$(this).attr('src');if(preload.complete){count--;if(count==0){li.html(html).removeClass("shoveler-progress");}}else{preload.onload=function(){count--;if(count==0){li.html(html).removeClass("shoveler-progress");}};}});}}
else if(currentCacheIndex>=this.numCellsTotal){li.html('<span class="empty"/>').removeClass("shoveler-progress");}
else{li.html('<span class="empty"/>').addClass("shoveler-progress");}},updateCache:function(originalStartIndex,isHtml,data,wasAjax){if(data.length===0){return;}
var self=this;var didUpdate=false;$.each(data,function(index,value){var originalCacheIndex=originalStartIndex+index;if(self.isCacheEmpty(originalCacheIndex)){var toStore=value;if(!isHtml){toStore=self.cellTransformer(value);}
var index=$.inArray(originalCacheIndex,self.cache);if(index>=0){self.cache[index]={data:$.trim(toStore)};}
didUpdate=true;}
else{log.warn("updating cache[%s], but it was already cached",originalCacheIndex);}});if(!didUpdate){log.warn("Didn't update cache at all in updateCache()");}
else{if(!isHtml){this.cacheUpdated(wasAjax);}}},gotoPage:function(pageNumber,wrapped){TypeChecker.assertTypeIs(pageNumber,'number');TypeChecker.assertTypeIsOneOf(wrapped,'boolean','undefined');if(pageNumber>=this.getNumPages()){log.warn("Can't go to page %s since there are only %s pages",pageNumber,this.getNumPages());pageNumber=this.getNumPages()-1;}
if(pageNumber<0){log.warn("Can't go to page %s, going to 0 instead",pageNumber);pageNumber=0;}
var lastDirection=(this.getCurrentPage()<pageNumber)?1:-1;this.currentCell=pageNumber*this.getNumCellsPerPage();this.updateStats();this.switchVisibleCells(lastDirection,wrapped);},gotoFirstPage:function(){this.currentCell=0;this.updateStats();this.switchVisibleCells(0,false);},removeItemByCurrentCacheIndex:function(cacheIndex){TypeChecker.assertTypeIs(cacheIndex,'number');var ret=this.cache.splice(cacheIndex,1)[0].data;this.numCellsTotal--;this.gotoPage(this.getCurrentPage());return ret;},removeItemByPageIndex:function(pageIndex){TypeChecker.assertTypeIs(pageIndex,'number');return this.removeItemByCurrentCacheIndex(this.currentCell+pageIndex);},addToLeft:function(html){TypeChecker.assertTypeIs(html,'string');this.cache.unshift({data:html});this.numCellsTotal++;this.gotoPage(this.getCurrentPage());},size:function(){return this.numCellsTotal;}});})(jQuery);
