





function removeChildNodes(element){
while(element.hasChildNodes()){
element.removeChild(element.firstChild);
}
}


var SearchFrame=Class.create();

SearchFrame.prototype={

searchElement:null,
resultsFrame:null,
searching:false,
lastSearchTerm:null,
lastSearchType:null,
resultsLimit:24,

initialize:function(elementId,resultsFrame){

this.searchElement=document.getElementById(elementId);

this.resultsFrame=resultsFrame;

},


search:function(){

var searchField=this.searchElement.getElementsByTagName("input")[0];
var term=searchField.value;

var searchTypeField=this.searchElement.getElementsByTagName("select")[0];
var searchType=searchTypeField.value;


if(!this.searching&&((term!=this.lastSearchTerm)||
(searchType!=this.lastSearchType))&&(term!=="")){

searchField.blur();

this.lastSearchTerm=term;
this.lastSearchType=searchType;
this.searching=true;

var url="/itunes/scripts/itmsSearch.php?searchTerm="+escape(term)+"&searchType="+escape(searchType);

function showResults(searchFrame){

return(function(request){
searchFrame.display(request);
});
}

var showResultsCallback=showResults(this);

new Ajax.Request(url,{
method:"get",
onComplete:showResultsCallback
});

this.resultsFrame.renderLoading(term);
}
},


display:function(request){

if(request.readyState==4){

var found=0;

try{

var rawResponse=request.responseText;



var response=eval('('+rawResponse.replace("\"\"\"\"","\"\"")+')');

found=response.resultCount;

var collection=this.createCollection(response.results);

}catch(exception){

if(exception instanceof SyntaxError){




var searchField=this.searchElement.getElementsByTagName("input")[0];
searchField.focus();

}else{
throw exception;
}

}finally{
this.resultsFrame.render(collection,this.lastSearchTerm,found);
}

this.searching=false;
}
},


createCollection:function(results){

var items=[];

var limit=(results.length<this.resultsLimit)?results.length:this.resultsLimit;

for(var i=0;i<limit;i++){

var result=results[i];

var artist=(typeof(result.artistDisplayName)==="undefined")?result.artistName:result.artistDisplayName;
var title=(typeof(result.itemCensoredName)==="undefined")?result.itemName:result.itemCensoredName;

items[i]=new GalleryItem(
artist,
title,
result.artworkUrl60,
result.itemLinkUrl);
}

return items;
}

};

var GalleryItem=Class.create();

GalleryItem.prototype={

listItem:null,
artistName:null,
albumName:null,
artworkUrl:null,
albumUrl:null,

initialize:function(artistName,albumName,artworkUrl,albumUrl){

this.artistName=artistName;
this.albumName=albumName;
this.artworkUrl=artworkUrl;
this.albumUrl=albumUrl;

var albumLink=document.createElement("a");
albumLink.setAttribute("href",this.albumUrl);
albumLink.setAttribute("title",this.albumName);

var artworkImage=document.createElement("img");
artworkImage.setAttribute("src",this.artworkUrl);
artworkImage.setAttribute("alt",this.albumName+" by "+this.artistName);

albumLink.appendChild(artworkImage);

this.listItem=document.createElement("li");
this.listItem.appendChild(artworkImage);

}
};




var GalleryFrame=Class.create();

GalleryFrame.prototype={

targetFrame:null,

collection:null,

layoutStrategy:null,
maxSubsets:4,
numSubsets:0,
currentSubsetIndex:0,
inspectedItem:null,

viewPanel:null,
infoPanel:null,
galleryList:null,
navPanel:null,
pagerPanel:null,
isNavigable:false,


initialize:function(targetFrameId,maxSubsets){

this.targetFrame=$(targetFrameId);

if(this.targetFrame!=null){
Element.hide(this.targetFrame);
}

this.maxSubsets=(typeof(maxSubsets==="undefined"))?this.maxSubsets:maxSubsets;

this.viewPanel=document.createElement("div");
this.viewPanel.className="viewPanel";
this.viewPanel.setAttribute("class","viewPanel");

this.infoPanel=document.createElement("div");
this.infoPanel.className="infoPanel";
this.infoPanel.setAttribute("class","infoPanel");

this.closeButton=document.createElement("div");
Element.addClassName(this.closeButton,"closeButton");
Event.observe(this.closeButton,"mousedown",this.ignore.bindAsEventListener(this));

this.loadingPlaceholder=document.createElement("div");
Element.addClassName(this.loadingPlaceholder,"loadingPlaceholder");

var spinner=document.createElement("img");
spinner.setAttribute("src","http://images.apple.com/itunes/images/sidebar_search_waitanimation20060912.gif");
spinner.setAttribute("border","0");
this.loadingPlaceholder.appendChild(spinner);

this.loadingPlaceholder.appendChild(document.createTextNode("Searching... "));


Element.hide(this.loadingPlaceholder);
this.targetFrame.parentNode.insertBefore(this.loadingPlaceholder,this.targetFrame);


this.layoutStrategy=this.layoutVertical;
},


render:function(collection,searchTerm,resultsAvailable){

this.collection=collection;

Element.show(this.targetFrame);

if(typeof(this.collection)==="undefined"
||this.collection==null
||this.collection.length===0){

this.renderError(searchTerm);
return false;
}

this.clear();


this.targetFrame.appendChild(this.infoPanel);
Element.hide(this.infoPanel);

this.targetFrame.appendChild(this.closeButton);
Element.hide(this.closeButton);


this.galleryList=document.createElement("ul");
this.viewPanel.appendChild(this.galleryList);
this.targetFrame.appendChild(this.viewPanel);


this.viewPanel.appendChild(this.createResultsNotice(resultsAvailable));


this.numSubsets=this.layoutStrategy(this.collection,
this.galleryList,
this.viewPanel,
this.maxSubsets);


this.navPanel=new NavigationPanel(this);
this.targetFrame.appendChild(this.navPanel.navList);

this.pagerPanel=new PaginationPanel(this.numSubsets,this);
this.targetFrame.appendChild(this.pagerPanel.pageList);

this.setCurrentSubsetIndex(0);

if(!this.isNavigable){
var navigateCallBack=this.navigateAsResponseTo.bindAsEventListener(this);
Event.observe(document,'keypress',navigateCallBack);
this.isNavigable=true;
}

new Effect.Appear(this.targetFrame,{
to:1.0,
duration:0.2});

new Effect.Appear(this.galleryList,{
to:1.0,
duration:0.2});

},


createResultsNotice:function(resultsFound){

var resultsNotice=document.createElement("div");
Element.addClassName(resultsNotice,"resultsInfo");

var found=resultsFound==100?100+"+":resultsFound;
resultsNotice.innerHTML="Found <strong>"+found+"</strong> Results";

return resultsNotice;
},


insertItem:function(item,galleryList){


function inspectItem(gallery,item){
return(function(){
gallery.inspect(item);
});
}

var callback=inspectItem(this,item);

Event.observe(item.listItem,'mousedown',callback);

galleryList.appendChild(item.listItem);
},


layoutHorizontal:function(collection,galleryList,view,maxSubsets){

var viewerWidth=Element.getDimensions(view).width;
var galleryPaddingLeft=parseInt(Element.getStyle(galleryList,"padding-left"),10);

var availableWidth=maxSubsets*viewerWidth;
var children=galleryList.childNodes;

var necessaryWidth=0;

for(var i=0;i<collection.length;i++){

this.insertItem(collection[i],galleryList);

var elementWidth=Element.getDimensions(children[i]).width;

necessaryWidth+=elementWidth;

if(necessaryWidth>availableWidth){
necessaryWidth-=elementWidth;
}
}

var numSubsets=Math.ceil(necessaryWidth/viewerWidth);

Element.setStyle(galleryList,{"width":(numSubsets*viewerWidth)+"px"});

return numSubsets;
},


layoutVertical:function(collection,galleryList,view,maxSubsets){

var viewerDimensions=Element.getDimensions(view);

var availableWidth=maxSubsets*viewerDimensions.width;
var galleryPaddingLeft=parseInt(Element.getStyle(galleryList,"padding-left"),10);
var galleryPaddingTop=parseInt(Element.getStyle(galleryList,"padding-top"),10);

var children=galleryList.childNodes;

var necessaryWidth=0;

var nextX=galleryPaddingLeft;
var nextY=galleryPaddingTop;

for(var i=0;i<collection.length;i++){

var newItem=collection[i].listItem;

this.insertItem(collection[i],galleryList);

var newItemDimensions=Element.getDimensions(newItem);
Element.setStyle(newItem,{"position":"absolute"});
Element.setStyle(newItem,{"top":nextY+"px"});
Element.setStyle(newItem,{"left":nextX+"px"});

nextY+=newItemDimensions.height;

if(nextY>=viewerDimensions.height){
nextY=galleryPaddingTop;
nextX+=newItemDimensions.width;
}

if(nextX+newItemDimensions.width>=availableWidth){
break;
}

}



var offset=(nextY==galleryPaddingTop)?0:Element.getDimensions(children[0]).width;
necessaryWidth=nextX+offset;

var numSubsets=Math.ceil(necessaryWidth/viewerDimensions.width);

Element.setStyle(galleryList,{"width":(numSubsets*viewerDimensions.width)+"px"});

return numSubsets;

},


navigateAsResponseTo:function(e){

target=e.target?e.target:e.srcElement;

if(target.tagName=="INPUT"){
return true;
}else{

switch(e.keyCode){
case Event.KEY_LEFT:
this.moveBack();
Event.stop(e);
break;
case Event.KEY_RIGHT:
this.moveForward();
Event.stop(e);
break;
case Event.KEY_ESC:
this.ignore();
break;
case 73:
if(this.inspectedItem==null){
this.moveTo(0);
this.inspect();
}else{
this.ignore();
}
break;
}

}
},


setCurrentSubsetIndex:function(newSubsetIndex){

this.pagerPanel.currentPage(this.currentSubsetIndex,newSubsetIndex);
this.currentSubsetIndex=newSubsetIndex;

},


nextSubsetIndex:function(){
return(this.currentSubsetIndex!=this.numSubsets-1)?this.currentSubsetIndex+1:0;

},


previousSubsetIndex:function(){
return(this.currentSubsetIndex!==0)?this.currentSubsetIndex-1:this.numSubsets-1;
},


moveTo:function(newSubsetIndex){

if(this.currentSubsetIndex==newSubsetIndex){
return false;
}

var distance=newSubsetIndex-this.currentSubsetIndex;

function updateIndex(gallery,newIndex){
return(function(){
gallery.setCurrentSubsetIndex(newIndex);
});
}

var updateIndexCallback=updateIndex(this,newSubsetIndex);


this.ignore();
this.shiftBy(distance,updateIndexCallback);

},


moveForward:function(){
if(this.inspectedItem==null){
this.moveTo(this.nextSubsetIndex());
}else{



var currentItemIndex=this.collection.indexOf(this.inspectedItem);
var nextItemIndex=(currentItemIndex==this.collection.length-1)?0:currentItemIndex+1;

this.inspect(this.collection[nextItemIndex]);
}
},


moveBack:function(){
if(this.inspectedItem==null){
this.moveTo(this.previousSubsetIndex());
}else{

var currentItemIndex=this.collection.indexOf(this.inspectedItem);
var prevItemIndex=(currentItemIndex===0)?this.collection.length-1:currentItemIndex-1;

this.inspect(this.collection[prevItemIndex]);
}
},


clear:function(){

Element.hide(this.loadingPlaceholder);

if(this.galleryFrame!=null){
removeChildNodes(this.galleryFrame);
}

removeChildNodes(this.targetFrame);
removeChildNodes(this.viewPanel);
},


renderLoading:function(term){

this.ignore();

new Effect.Fade(this.targetFrame,{
to:0.1,
duration:0.2});

Element.show(this.loadingPlaceholder);

},


renderError:function(term){


if(this.galleryList!=null){
new Effect.Appear(this.galleryList,{
to:1.0,
duration:0.2});
}

if(this.targetFrame!=null){
new Effect.Appear(this.targetFrame,{
to:1.0,
duration:0.2});
}


this.clear();

var placeholder=document.createElement("div");
Element.addClassName(placeholder,"errorPlaceholder");

var apology=document.createElement("p");
apology.appendChild(document.createTextNode("Sorry, no results found."));

var title=document.createElement("strong");
title.appendChild(document.createTextNode(" "+term+" "));

var feedbackLink=document.createElement("a");
feedbackLink.setAttribute("href","http://www.apple.com/feedback/itunes.html");
feedbackLink.setAttribute("target","_blank");
feedbackLink.appendChild(document.createTextNode("Report"));

var text=document.createTextNode("as missing?");


placeholder.appendChild(apology);
placeholder.appendChild(feedbackLink);
placeholder.appendChild(title);
placeholder.appendChild(text);

this.targetFrame.appendChild(placeholder);
},


shiftBy:function(steps,updateIndex){

if(typeof(steps)==="undefined"){
steps=1;
}

var galleryPaddingLeft=parseInt(Element.getStyle(this.galleryList,"padding-left"),10);
var padding=steps*(galleryPaddingLeft*2);

var viewerWidth=Element.getDimensions(this.viewPanel).width;
var distance=((viewerWidth*-1)*steps)+padding;

new Effect.MoveBy(this.galleryList,0,distance,{
transition:Effect.Transitions.sinoidal,
queue:'end',
scope:'galleryFrame',
limit:4,
beforeStart:updateIndex});

},


inspect:function(galleryItem){

if(typeof(galleryItem)==="undefined"){
galleryItem=this.collection[0];
}

this.inspectedItem=galleryItem;

removeChildNodes(this.infoPanel);

var albumArt=galleryItem.listItem.firstChild.cloneNode(false);
this.infoPanel.appendChild(albumArt);

var albumTitleNode=document.createElement("strong");
Element.addClassName(albumTitleNode,"albumTitle");
albumTitleNode.appendChild(document.createTextNode(galleryItem.albumName));

var artistNameNode=document.createElement("p");
Element.addClassName(artistNameNode,"artistName");
artistNameNode.appendChild(document.createTextNode(galleryItem.artistName));

var albumLink=document.createElement("a");
albumLink.setAttribute("href",galleryItem.albumUrl);
albumLink.setAttribute("title",galleryItem.albumName);
albumLink.appendChild(document.createTextNode("Listen in iTunes"));

this.infoPanel.appendChild(albumArt);
this.infoPanel.appendChild(albumTitleNode);
this.infoPanel.appendChild(artistNameNode);
this.infoPanel.appendChild(albumLink);

new Effect.Fade(this.galleryList,{
to:0.1,
duration:0.2});

Element.addClassName(this.navPanel.navList,"inspecting");

Element.show(this.infoPanel);
Element.show(this.closeButton);
},


ignore:function(){

if(this.inspectedItem==null){
return false;
}

this.inspectedItem=null;

new Effect.Appear(this.galleryList,{
to:1.0,
duration:0.2});

new Effect.Appear(this.targetFrame,{
to:1.0,
duration:0.2});

Element.removeClassName(this.navPanel.navList,"inspecting");

Element.hide(this.infoPanel);
Element.hide(this.closeButton);
}
};


var PaginationPanel=Class.create();

PaginationPanel.prototype={

pageList:null,
totalPages:null,


initialize:function(totalPages,galleryFrame){

this.pageList=document.createElement("ul");
Element.addClassName(this.pageList,"pageNav");

this.totalPages=totalPages;

removeChildNodes(this.pageList);

for(var i=0;i<totalPages;i++){
var newPage=document.createElement("li");
var text=document.createTextNode(i);
newPage.appendChild(text);

function gotoPage(pageIndex,galleryFrame){

return(function(){
galleryFrame.moveTo(pageIndex);
});
}

var gotoPageCallback=gotoPage(i,galleryFrame);

newPage.onclick=gotoPageCallback;

this.pageList.appendChild(newPage);
}
},


currentPage:function(currentPageIndex,newPageIndex){

if(this.pageList.hasChildNodes()){


Element.removeClassName(this.pageList.childNodes[currentPageIndex],"current");


Element.addClassName(this.pageList.childNodes[newPageIndex],"current");
}
}

};


var NavigationPanel=Class.create();

NavigationPanel.prototype={

navList:null,
forwardNav:null,
backNav:null,

initialize:function(galleryFrame){

this.navList=document.createElement("ul");
Element.addClassName(this.navList,"nav");


function moveForward(galleryFrame){
return(function(){galleryFrame.moveForward();});
}

function moveBack(galleryFrame){
return(function(){galleryFrame.moveBack();});
}

var moveForwardCallBack=moveForward(galleryFrame);
var moveBackCallBack=moveBack(galleryFrame);

this.forwardNav=this.newNavOption("forward",moveForwardCallBack);
this.backNav=this.newNavOption("back",moveBackCallBack);

this.navList=document.createElement("ul");
Element.addClassName(this.navList,"nav");

this.navList.appendChild(this.forwardNav);
this.navList.appendChild(this.backNav);

},


newNavOption:function(label,onclick){

var nav=document.createElement("li");
Element.addClassName(nav,label+"Nav");
nav.onclick=onclick;
var labelText=document.createTextNode(label);
nav.appendChild(labelText);

return nav;
}
};





