var accessoriesController;
var AccessoriesController = function() {
}
AccessoriesController.prototype = {
initialize: function() {
this.container = document.getElementById("accessories-wrapper");
this.widgetContent = true;
if (this.container == null) this.widgetContent = false;
this.itemsSelected = {};      // array of ASINs selected by user, initialized to empty 
this.itemsSelectedCount = 0;  // count of ASINs selected  
this.suppressBuyBox = document.getElementById("accessories_suppressBuyBox_flag").value; // boolean ... should we show add to cart buttons
this.humbler = document.getElementById("accessories_humbler_flag").value; // boolean ... should we show the humbler version 
this.isGlance = document.getElementById("accessories_glanceView_flag").value; // boolean ... is this the glance view
this.scrollInterval = 50; // how often to scroll in milliseconds
this.scrollDistanceMax = 150; // max amount of pixels to scroll in one iteration
this.scrollDistanceDefault = 25; // default amount of pixels to scroll in one iteration
this.scrollDistance = this.scrollDistanceDefault; // actual amount of pixels to scroll in one iteration
this.scrollDistanceIncreaseAmount = 5; // how many pixels to increase scrolling by
this.scrollDistanceIncreaseInterval = 1; // increase every this many iterations
this.scrollTimer = null; // timer object for the scroller
this.targetOffset = null; // amount of pixels from the left of the scrolling area, for a given target element
this.currentlyScrolling = false; // keep track of whether it is currently scrolling or not
this.distanceToScroll = null; // amount of pixels to scroll	for a given scrollTo() action	
this.scrollCounter = 0; // how many times the scroll has occured for a given scrollTo() action
this.scrollerDivOuter = document.getElementById("accessories-scroller-outer");
if (this.scrollerDivOuter) {  // may not be defined for alt view 
this.scrollerDivOuter.scrollLeft = 0; // must initialize to 0 for scrollLeft() and scrollRight() to work
this.scrollerDivOuter.onmouseover = function(){ accessoriesController.trimInnerScrollWidth() };
this.scrollerDivOuter.onmouseout = function(){ accessoriesController.trimInnerScrollWidth() };
}
this.scrollerDivInner = document.getElementById("accessories-scroller-inner");
if ( this.scrollerDivInner )
this.minimumInnerScrollerWidth = this.scrollerDivInner.offsetWidth;
var itemData = document.getElementById("accessories_itemData").value;  // all ASIN level data that we need 
this.itemData = eval('(' + itemData + ')');
var imageData = document.getElementById("accessories_imageData").value;	// some image urls for JS 
this.imageData = eval('(' + imageData + ')');
var imageAltData = document.getElementById("accessories_imageAltData").value;
this.imageAltData = eval('(' + imageAltData + ')');
this.checkForSafari();
this.updateAccessories();
},
checkForSafari: function() {
if (navigator.userAgent.indexOf("Safari") > -1) {
this.container.className += " safari";
}
},
registerEventHandlers: function() {
if (this.suppressBuyBox == 0) {
this.addWindowClickEventHandler(this.checkToHidePopup);
}
},
updateAccessories: function() { // calls all update functions
if (this.suppressBuyBox == 0) {
this.updateItemsSelected();
}
if (this.isGlance == 1) {
this.normalizeRowHeightsForGlance(0, "h4", "");
this.normalizeRowHeightsForGlance(0, "h5", "product-title");
var availabilityRowHeight = this.normalizeRowHeightsForGlance(0, "p", "availability");
this.normalizeRowHeightsForGlance(0, "span", "accessory-price-row");
this.normalizeRowHeightsForGlance(0, "span", "accessory-ppu-row");
var sideBarElementId = "accessories-box-sidebar";
if ( this.humbler )
sideBarElementId = "accessories-main-item";
var sideBarHeight = document.getElementById( sideBarElementId ).offsetHeight;
var categoriesHeight = document.getElementById( "accessories-scroller-inner" ).offsetHeight;
if ( sideBarHeight > categoriesHeight )
this.normalizeRowHeightsForGlance(sideBarHeight - categoriesHeight + availabilityRowHeight, "p", "availability");
} 
else {			
this.normalizeRowHeightsForAlt(0, "h5", "product-title");
this.normalizeRowHeightsForAlt(0, "p", "availability");
this.normalizeRowHeightsForAlt(0, "span", "accessory-price-row");
this.normalizeRowHeightsForAlt(0, "span", "accessory-ppu-row");			
}
},
updateItemsSelected: function() {
var itemsSelectedCountElement = document.getElementById("items-selected-count");
itemsSelectedCountElement.innerHTML = this.itemsSelectedCount;
this.updateItemsSelectedPopup();
var buybox = document.getElementById("accessories-buy-box");
var addSelectedToCart = document.getElementById("add-selected-to-cart");
var popoverTrigger = document.getElementById("items-selected-trigger");
if ( this.itemsSelectedCount > 0 ) {
buybox.className = "acc_enabled";
addSelectedToCart.src = this.getImageURL("button-add-selected-to-cart");
popoverTrigger.src = this.getImageURL("button-items-selected-trigger-active");
} else {
buybox.className = "";
addSelectedToCart.src = this.getImageURL("button-add-selected-to-cart-grey");
popoverTrigger.src = this.getImageURL("button-items-selected-trigger");
this.hidePopup();
}
},
updateItemsSelectedPopup: function() {  // generates/updates the HTML of the items selected popup
var htmlString = "";
var priceTotal = 0;
var index=0;
for (var asinString in this.itemsSelected) {
var asinObject = this.itemData[asinString];
var style=(index==this.itemsSelectedCount-1)?" style='border:none'":"";
htmlString += "<div class='selected-item'"+style+">";
htmlString += "<span class='product-title'>";
htmlString += "<a href='#' onclick='accessoriesController.removeItem(\"" + asinString + "\"); return false; ' ><img src='" + this.getImageURL("button-close") + "' class='selected-items-remove' alt='' /></a>";
htmlString += asinObject.title;
htmlString += "</span>";
htmlString += "<span class='price'>";
htmlString += this.priceFormatter.formatPrice( asinObject.price );
htmlString += "</span>";
htmlString += "<div style='clear: both; height: 0; line-height: 0;'>&nbsp;</div>"; // clear fix. (cause parent container to expand)
htmlString += "</div>";
priceTotal += asinObject.price;
index++;
}
document.getElementById("selected-items").innerHTML = htmlString;
priceTotal = this.priceFormatter.formatPrice( priceTotal );
document.getElementById("cart-subtotal-price").innerHTML = priceTotal; // update price
if (this.itemsSelectedCount > 4) {
document.getElementById("selected-items").className = "scrollbars";
} else {
document.getElementById("selected-items").className = "";
}
},
addWindowClickEventHandler: function(eventHandler) { // takes a function to trigger when user clicks window
var method = window.onmousedown;
if (navigator.userAgent.indexOf("MSIE")>-1) {
if (typeof method == 'function') {
document.getElementsByTagName("body")[0].onmousedown = function(e) {
method(e);
if (accessoriesController.widgetContent) eventHandler(e);
}
} else {
document.getElementsByTagName("body")[0].onmousedown = function(e) {
if (accessoriesController.widgetContent) eventHandler(e);
}
}
} else {
if (typeof method == 'function') {
window.onmousedown = function(e) {
method(e);
if (accessoriesController.widgetContent) eventHandler(e);
}
} else {
window.onmousedown = function(e) {
if (accessoriesController.widgetContent) eventHandler(e);
}
}
}
},
selectItem: function(asin, button) {  // takes ASIN as a string, and button <img>
this.itemsSelected[asin] = button; // add ASIN to list of selected items
button.src = this.getImageURL("button-remove-this-item");	// change button from "select" to "remove"
button.alt = this.imageAltData["remove"];
button.onclick = function() { // update onclick to reflect new button
accessoriesController.removeItem(asin);	
}
this.itemsSelectedCount++;
this.updateItemsSelected();
},
removeItem: function(asin) {
var button = this.itemsSelected[asin];
button.src = this.getImageURL("button-select-this-item");	// change button from "remove" to "select"
button.alt = this.imageAltData["select"];
button.onclick = function() { // update onclick to reflect new button
accessoriesController.selectItem(asin, button);
}
var itemsSelected = {}; // create local var to store new list of ASINs
for (var selectedAsin in this.itemsSelected) {
if (selectedAsin != asin) {
itemsSelected[selectedAsin] = this.itemsSelected[selectedAsin];
}
}
this.itemsSelected = itemsSelected;
this.itemsSelectedCount--;		
this.updateItemsSelected();
},
clearAll: function() {  // removes all selections
for (var selectedAsin in this.itemsSelected) {
this.removeItem(selectedAsin);		
}
},
checkToHidePopup: function(e) { 
var popup = document.getElementById("items-selected-popup");
if( typeof e == 'undefined' )
e = event;
var myPos = accessoriesController.findPos(popup);
var cLeft = myPos[0];
var cRight = cLeft + popup.scrollWidth + 25; // compensate for scrollbars
var cTop = myPos[1];
var cBottom = cTop + popup.offsetHeight + 25; // compensate for trigger wrapper area
var ex = e.clientX;
var ey = e.clientY;
if ( ex < cLeft || ex > cRight || (ey+myPos[3]) < cTop || (ey+myPos[3]) > cBottom ) {
accessoriesController.hidePopup();
}		
},
hidePopup: function() {
this.togglePopup( false );
},
togglePopup: function( showing ) {
if (this.itemsSelectedCount < 1) {
showing = false;
}
var wrapper = document.getElementById( "cart-wrapper" );
if ( showing == undefined ) 
showing = wrapper.className != "acc_showing";
wrapper.className = showing ? "acc_showing" : "";
document.getElementById("items-selected-wrapper").style.backgroundImage = (showing) ? "url(" + this.getImageURL("items-selected-button-repeat") + ")" : "";
document.getElementById("items-selected-wrapper-left").style.backgroundImage = (showing) ? "url(" + this.getImageURL("items-selected-button-left") + ")" : "";
document.getElementById("items-selected-wrapper-right").style.backgroundImage = (showing) ? "url(" + this.getImageURL("items-selected-button-right") + ")" : "";
},
scrollTo: function(id) { // takes the id of the element to scroll to
if (this.currentlyScrolling == true) {
return false;
}
var targetElement = document.getElementById(id);
this.targetOffset = this.findPos(targetElement)[0] - document.getElementById("accessories-box-sidebar").offsetWidth - 40; // CSS dependent 
this.distanceToScroll = Math.abs(this.scrollerDivOuter.scrollLeft - this.targetOffset);
this.currentlyScrolling = true;
if (this.targetOffset > this.scrollerDivOuter.scrollLeft) { // right scroll
this.scrollTimer = setInterval(function() {
var currentScrollLeft = accessoriesController.scrollerDivOuter.scrollLeft;			
accessoriesController.scrollRight();
if (accessoriesController.targetOffset <= (accessoriesController.scrollerDivOuter.scrollLeft + accessoriesController.scrollDistance)
|| accessoriesController.scrollerDivOuter.scrollLeft == currentScrollLeft) { 
accessoriesController.setScrollOffset( accessoriesController.targetOffset );
accessoriesController.stopScrolling();
}
}, this.scrollInterval);
} else {	// left scroll 
this.scrollTimer = setInterval(function() {
accessoriesController.scrollLeft();
if (accessoriesController.targetOffset >= (accessoriesController.scrollerDivOuter.scrollLeft - accessoriesController.scrollDistance)
|| accessoriesController.scrollerDivOuter.scrollLeft == 0) {
accessoriesController.setScrollOffset(  accessoriesController.targetOffset );
accessoriesController.stopScrolling();
}
}, this.scrollInterval);
}		
},
scrollRight: function() {
this.setScrollOffset(this.scrollerDivOuter.scrollLeft + this.scrollDistance);
this.scrollCounter++;		
this.adjustScrollDistance();
},
scrollLeft: function() {
this.setScrollOffset(this.scrollerDivOuter.scrollLeft - this.scrollDistance);
this.scrollCounter++;
this.adjustScrollDistance();		
},
adjustScrollDistance: function() {
if (this.scrollCounter % this.scrollDistanceIncreaseInterval == 0) {
if (Math.abs(this.targetOffset - this.scrollerDivOuter.scrollLeft) <= this.distanceToScroll / 2) { 
this.scrollDistance -= this.scrollDistanceIncreaseAmount;							
if (this.scrollDistance < this.scrollDistanceDefault) {
this.scrollDistance = this.scrollDistanceDefault;
}
} else { // increase scrollDistance as you get closer to target
this.scrollDistance += this.scrollDistanceIncreaseAmount;			
if (this.scrollDistance > this.scrollDistanceMax) {
this.scrollDistance = this.scrollDistanceMax;
}
}
}
},
stopScrolling: function() {
clearInterval(accessoriesController.scrollTimer); // stop scrolling
this.currentlyScrolling = false;
accessoriesController.scrollCounter = 0;
accessoriesController.scrollDistance = accessoriesController.scrollDistanceDefault;		
},
setScrollOffset: function( offset ) {
var maximumScrollOffset = this.minimumInnerScrollerWidth - this.scrollerDivOuter.offsetWidth;
if (offset > maximumScrollOffset)
this.scrollerDivInner.style.width = (offset + this.scrollerDivOuter.offsetWidth) + 'px';
else
this.scrollerDivInner.style.width = this.minimumInnerScrollerWidth + 'px';
this.scrollerDivOuter.scrollLeft = offset;
},
trimInnerScrollWidth: function() {
if ( this.scrollerDivInner.offsetWidth > this.minimumInnerScrollerWidth &&
this.scrollerDivOuter.scrollLeft < this.scrollerDivInner.offsetWidth - this.scrollerDivOuter.offsetWidth )
{
this.scrollerDivInner.style.width = Math.max(this.scrollerDivOuter.scrollLeft + this.scrollerDivOuter.offsetWidth, this.minimumInnerScrollerWidth) + 'px';
}
this.delayedScrollEventTimer = null;
},
getImageURL: function(image) { // takes file name without extension
return (this.imageData[image] != null) ? this.imageData[image] : "";  // return empty string if image URL not found
},
findPos: function(obj) { // utility function that returns x and y coordinates for a given HTML object
var curleft = curtop = scrolltop = scrollleft = 0;
if (obj == null) return;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
scrolltop = obj.scrollTop;
scrollleft = obj.offsetLeft;
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
if (scrolltop < obj.scrollTop) scrolltop += obj.scrollTop;
if (scrollleft < obj.offsetLeft) scrollleft += obj.offsetLeft;
}
}
if (navigator.userAgent.indexOf("Safari") > -1) { // only for Safari
var dataString = navigator.userAgent;
var verString = "Version/";
var index = dataString.indexOf(verString);
if (parseFloat(dataString.substring(index+verString.length)) < 3) {
scrolltop = 0; 	// only for versions less than 3 
}
}
return [curleft,curtop,scrollleft,scrolltop];
},
normalizeCells: function(maxRowHeight, cells, className) { // helper function for normalizing heights 
var maxHeightOverride = 1000; //really high number, ie (MAX_INT)
if ( className == 'product-title' )
maxHeightOverride = 42; // 3 lines * 14px line height :: limit this to 3 lines.
for (var i = 0; i < cells.length; i++) {
if ( typeof cells[i].className != "undefined" && 
cells[i].className == className && 
cells[i].innerHTML.replace(/^\s+|\s+$/g,'').length > 0 ) { //ensure that cell has content, if we're gonna give it height
cells[i].style.height = "auto";
if (cells[i].offsetHeight > maxRowHeight) {
maxRowHeight = Math.min(cells[i].offsetHeight, maxHeightOverride);
} 				
}
}
for (var i = 0; i < cells.length; i++) {
if (typeof cells[i].className != "undefined" && cells[i].className == className) {
if ( maxRowHeight == 0 )
cells[i].style.display = "none";
else
cells[i].style.height = maxRowHeight + "px";
}
}
return maxRowHeight;
},
normalizeRowHeightsForGlance: function(maxRowHeight, tagName, className) { // input is known max height of row
var allCells = document.getElementById("accessories-scroller-inner").getElementsByTagName(tagName);
return accessoriesController.normalizeCells(maxRowHeight, allCells, className);
},
normalizeRowHeightsForAlt: function(maxRowHeight, tagName, className) { // input is known max height of row
var binNum;
for (binNum=1; binNum<=9; binNum++) {
var categoryDiv = document.getElementById("accessory-category-" + binNum);
if (categoryDiv == null) continue ;
var allCells = categoryDiv.getElementsByTagName(tagName);
accessoriesController.normalizeCells(maxRowHeight, allCells, className);
}
},
accessoriesFormSubmit: function() {  
var accessoriesForm = document.getElementById("accessories.handleBuy");
var htmlString = "";
if (this.itemsSelectedCount < 1) { // nothing selected ...
return false;
}
for (var asinString in this.itemsSelected) {
var asinObject = this.itemData[asinString];
htmlString += "<input type='text' name='offeringID." + asinObject.type + "." + asinString + "' value='" + asinObject.offeringid + "' />";
}
var formFields = document.getElementById("accessories-form-fields");
if (accessoriesForm && formFields) 
{
formFields.innerHTML = htmlString;
accessoriesForm.submit();
} else {
return false;
}
}
};
function constructAccessoriesController( currencyCode ) {
accessoriesController = new AccessoriesController();
accessoriesController.priceFormatter = new CurrencyFormatter( currencyCode );
accessoriesController.initialize();
accessoriesController.registerEventHandlers();	
}
function onAjaxUpdate_accessories_and_compatible_products(childASIN) {
if (!accessoriesController) constructAccessoriesController();
else accessoriesController.initialize();
}
function onCacheUpdate_accessories_and_compatible_products(childASIN) {
if (!accessoriesController) constructAccessoriesController();
else accessoriesController.initialize();
}
