//! ################################################################
//! 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;},ajaxResultTransformer: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,suppressPaginationOnLoad:false,maxCellsPerPage:0};$.extend(this,defaultOptions,options||{});this.rootUl=$(this.rootUlSelector,domElement);this.allCells=[];this.numCellsPerPage=0;this.updateCellStats();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.rootContentCache=$('<div class="shoveler-cell-cache" style="display:none" />').appendTo(this.root);this.generator=function(){var ret=generator.apply(this,arguments);if(!ret&&typeof ret!=='string'&&!ret instanceof Array&&ret!==true){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).children();});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.suppressPaginationOnLoad){var pagination=$(self.paginationSelector,self.root);pagination.show();self.suppressPaginationOnLoad=false;}
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.suppressPaginationOnLoad){var pagination=$(self.paginationSelector,self.root);pagination.show();self.suppressPaginationOnLoad=false;}
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(false,false);});this.updateUI(false,false);};$.extend(Shoveler.prototype,{updateUI:function(triggerOnPageChangeComplete,suppressUpdate){this.adjustNumLisInDom();this.getNewCellsIfNeeded();if(!suppressUpdate){this.updateVisibleCellsImmediately(this.currentCell);}
this.updateStats();if(triggerOnPageChangeComplete){this.onPageChangeCompleteHandler();}
var buttons=$(this.prevButtonSelector,this.root).add($(this.nextButtonSelector,this.root));buttons[this.shouldShowScrollButtons()?'show':'hide']();},shouldShowScrollButtons:function(){return this.getNumPages()>1||this.currentCell!==0;},updateStats:function(){var pagination=$(this.paginationSelector,this.root);pagination[(this.shouldShowScrollButtons()&&!this.suppressPaginationOnLoad)?'show':'hide']();var pageNumber=$('.page-number',this.root);var numPages=$('.num-pages',this.root);var cellNumber=$('.cell-number',this.root);var numVisible=$('.num-visible',this.root);if(pageNumber.text()!=((1+Math.floor(this.getCurrentPage()))+" ")){$('.page-number',this.root).text((1+Math.floor(this.getCurrentPage()))+" ");}
if(numPages.text()!=(this.getNumPages()+" ")){$('.num-pages',this.root).text(this.getNumPages()+" ");}
if(cellNumber.text()!=(""+this.currentCell)){$('.cell-number',this.root).text(""+this.currentCell);}
if(numVisible.text()!=(""+this.getNumCellsPerPage())){$('.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 Math.floor(this.currentCell/this.numCellsPerPage);},isMidPage:function(){return!!(this.currentCell%this.numCellsPerPage);},isLastPage:function(){return this.currentCell+this.numCellsPerPage>=this.numCellsTotal;},isFirstPage:function(){return this.getCurrentPage()===0;},getNumCellsPerPage:function(){return this.numCellsPerPage;},getNumPages:function(){return Math.ceil(this.numCellsTotal/this.numCellsPerPage);},getAllCells:function(){return this.allCells;},updateCellStats:function(){this.allCells=this.rootUl.find('> li');this.numCellsPerPage=this.allCells.size();},adjustNumLisInDom:function(){if(this.getAllCells().size()===0){this.rootUl.append($('<li>'));this.updateCellStats();}
var totalWidth=this.rootUl.width();var cellWidth=this.getAllCells().width();if(cellWidth===0){return;}
cellWidth+=this.horizPadding;var cellsPerPage=Math.floor(totalWidth/cellWidth);if(cellsPerPage<1){cellsPerPage=1}
if((this.maxCellsPerPage>0)&&(cellsPerPage>this.maxCellsPerPage)){cellsPerPage=this.maxCellsPerPage;}
var remainingSpace=totalWidth-cellsPerPage*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 > div.shoveler-cell').appendTo(this.rootContentCache);this.rootUl.find('> li:last').remove();difference++;}
this.updateCellStats();var margin=Math.floor(remainingSpace/cellsPerPage/2);margin+=(this.horizPadding/2);var origmargin=this.getAllCells().css("margin-left");if(origmargin!=(margin+'px')){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,wasVisible){if(!this.animInProgress()&&wasAjax&&wasVisible){this.updateUI(true,false);}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(data instanceof Array){this.updateCache(originalStartIndex,false,data,false);}
else if(typeof data==="string"){log.info("making ajax call to %s",data);var self=this;$.ajax({url:data,dataType:"json",timeout:self.ajaxTimeout,error:function(XMLHttpRequest,textStatus,errorThrown){log.warn("failed ajax request to %s: %s %s",data,textStatus,errorThrown);},success:function(jsonObjArray){jsonObjArray=self.ajaxResultTransformer(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;var hasNoPendingCells=!(self.getAllCells().hasClass("shoveler-progress"));self.updateUI(self.pendingAsyncDataRequiresPageRefresh,hasNoPendingCells);};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;var self=this;function tryShowCell(){if(count!=0)return;li.children('div.shoveler-cell').appendTo(self.rootContentCache);li.empty().append(html).removeClass("shoveler-progress");html.show();}
images.each(function(){var preload=new Image();preload.src=$(this).attr('src');if(preload.complete){count--;tryShowCell();}else{preload.onload=function(){count--;tryShowCell();};}});tryShowCell();}}
else if(currentCacheIndex>=this.numCellsTotal){li.children('div.shoveler-cell').appendTo(this.rootContentCache);li.html('<span class="empty"/>').removeClass("shoveler-progress");}
else{li.children('div.shoveler-cell').appendTo(this.rootContentCache);li.html('<span class="empty"/>').addClass("shoveler-progress");}},updateCache:function(originalStartIndex,isHtml,data,wasAjax){if(data.length===0){return;}
var self=this;var wasVisible=(originalStartIndex<this.currentCell+this.getNumCellsPerPage());var didUpdate=false;$.each(data,function(index,value){var originalCacheIndex=originalStartIndex+index;if(self.isCacheEmpty(originalCacheIndex)){var toStore=$('<div class="shoveler-cell"/>').appendTo(self.rootContentCache);if(isHtml){toStore.append(value);}
else{var html=self.cellTransformer(value);toStore.html(html);}
var index=$.inArray(originalCacheIndex,self.cache);if(index>=0){self.cache[index]={data: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{this.cacheUpdated(wasAjax,wasVisible);}},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());if(typeof ret==='object'&&typeof ret['remove']==='function'){ret.remove();}
return ret;},removeItemByPageIndex:function(pageIndex){TypeChecker.assertTypeIs(pageIndex,'number');return this.removeItemByCurrentCacheIndex(this.currentCell+pageIndex);},addToLeft:function(html){TypeChecker.assertTypeIs(html,'string');var toStore=$('<div class="shoveler-cell"/>').appendTo(this.rootContentCache);html=this.cellTransformer(html);toStore.html(html);this.cache.unshift({data:toStore});this.numCellsTotal++;this.gotoPage(this.getCurrentPage());},size:function(){return this.numCellsTotal;}});amznJQ.declareAvailable('amazonShoveler');})(jQuery);
