sdk_Controls = {};
sdk_Controls.FacetedNav = Class.create({
	initialize : function(filterOptions, productsArray, sortingArray) {
		this.filterOptions = filterOptions; /* this is the array of options for the filters on the left */
		this.products = productsArray /* here's the copy of the product data we'll be working with */
		this.sortingOptions = sortingArray; /* this is the value for sorting at the top */
		this.activeSet = []; /* this is the array of products that are active from the filters - it is ordered according to the correct sorting method */
	
		/* Set up the filters */
		var paramsContainer = document.getElementsByClassName("sdk_FacetedNav_Params")[0]; /* here we get the container for the filters */
		paramsContainer.select(".sdk_FacetedNav_ClearBtn")[0].observe("click", this.resetFilter.bind(this)); /* on the clearbutton's click we run the method resetFilter */
		for (var i = 0, len = this.filterOptions.length; i<len; i++) { /* looping through the filter opions */
			 this.filterOptions[i].optionsMod = []; /* here we're creating an aray that will contain objects that extend the array attached to the filteroption's property option (filterOption[n].optionsMod is a modified version of filerOption[n].options) */
				if(this.filterOptions[i].name=='Product Use')
				{
					var sortingCategoryNode = new Element("div", {"class": "sdk_FacetedNav_Category_crcl"});
				}
				else
				{
					var sortingCategoryNode = new Element("div", {"class": "sdk_FacetedNav_Category"}); /* we create the title and attach it */
				}
			paramsContainer.appendChild(sortingCategoryNode);
			sortingCategoryNode.innerHTML = '<h3 class="sdk_FacetedNav_CategoryTitle">' + this.filterOptions[i].name + '</h3>';
			
			for (var j = 0, jLen = this.filterOptions[i].options.length; j<jLen; j++) { /* now we lop through all of the filterOption's options */
				if(this.filterOptions[i].name=='Product Use')
				{
					var sortingCheckBox = new Element("div", {"class": "sdk_FacetedNav_Option_crcl"});
				}
				else
				{
					var sortingCheckBox = new Element("div", {"class": "sdk_FacetedNav_Option"}); /* here's the element that contains the label and responds to the click  */
				}
				sortingCategoryNode.appendChild(sortingCheckBox);
				sortingCheckBox._isDisabled = false; /* it's on by default */
				sortingCheckBox._isChecked = false; /* and is unchecked */
				
				this.filterOptions[i].optionsMod[j] = { /* here we're creating the object that is atached to the optionsMod array */
					value : this.filterOptions[i].options[j], /* reference to the value*/
					checkNode : sortingCheckBox, /* and checkbox */
					onSet : [] /* this is the set of product objects that this option has a positive value for. it's values will be set in a few lines */
				};
				sortingCheckBox.observe("click", this.registerOptionClick.bind(this, this.filterOptions[i].optionsMod[j] )); /* when the text is clicked, we run the method registerOptionClick with the this optionsMod object as an argument */
			}
		}
		for (var i = 0, len = this.products.length; i<len; i++) {
			/* here we loop through the products, add to them slightly and attach them to the proper filters */
			var prd = this.products[i];
			prd.domNode = $(prd.nodeId); /* this is the DOM node that we will be turning on and off - this is very important */
			prd.isAvailable = true; /* this means it's part of the activeSet defined above  */
			
			for (var j = 0, jLen = prd.filterValues.length; j<jLen; j++) { /* here we go through the _product's_ filtervalues that are set in the HTML */
				var filterVal = prd.filterValues[j]; 
				for (var k = 0, kLen = this.filterOptions.length; k<kLen; k++) { /* and we compare it to every one of the filteroptions that we set above to find the correct catagory */
					filter = this.filterOptions[k]; 
					if (filter.name == filterVal.name) { /* we found the filter category that that matches the one from the product that we're looping through with j */
						for (var l = 0, lLen = filterVal.values.length; l<lLen; l++) {	 /* now we loop through all of the values that the product has defined */
							var value = filterVal.values[l];
							for (var m = 0, mLen = filter.options.length; m<mLen; m++) {  /* and compare it to the filter category's option  */
								var option = filter.optionsMod[m];
								if (option.value == value) { /* if it matches, then we add it to the option's onSet array */
									option.onSet.push(prd);
								}
							}
						}
					}
				}
			}
			this.activeSet.push(prd); /* since all products are on by default we add the product to the active set */
		}
		this.updateFilterOptions(); /* this method turns the filters on and off and updates the counts after the filters */
		
		/* Set up the pagination */
		
		this.atPage = 0; /* we start at the first page */ 
		/* here we're going to get some references to the HTML nodes */
		var paginationControlsContainer = document.getElementsByClassName("sdk_FacetedNav_ResultsControls")[0];
		this.paginationControls = {
			"prevBtn" : paginationControlsContainer.select('.sdk_FacetedNav_PaginationControlsPrev')[0],
			"nextBtn" : paginationControlsContainer.select('.sdk_FacetedNav_PaginationControlsNext')[0],
			"currentVisibleText" : paginationControlsContainer.select('.sdk_FacetedNav_PaginationVisible')[0],
			"totalPotentialVisible" : paginationControlsContainer.select('.sdk_FacetedNav_PaginationTotal')[0]
		};
		this.paginationControls.nextBtn.observe("click", this.paginateNext.bind(this)); /* on the previous/next button clicks we run the paginateNext,paginatePrev methods respectivly */
		this.paginationControls.prevBtn.observe("click", this.paginatePrev.bind(this));
		this.setPagination(this.atPage); /* we set the pagingation controls based on the first page */
		
		/* Set up the sorting */ 
		this.sortMethod = "default";  /* since doing the sorting will be a little pricy, we use this to find out if the user has requested sorting */
		this.productContainer = document.getElementsByClassName("sdk_FacetedNav_ProductResults")[0];  /* we get some references */
		var sortControlsContainer = document.getElementsByClassName("sdk_FacetedNav_SortControls")[0];
		
		sortControlsContainer.innerHTML = "<div style=\"float: left;\">Sort By</div> "; /* and set the label */
		
		var selectBoxContainer = new Element("div", {"style" : "float: left; width: 100px; margin: 0 0 0 10px;"}); /* we will create some dom nodes based on the values that have come in from the HTML. THis is the same structure that we use elswhere for the custom select box  */
		sortControlsContainer.appendChild(selectBoxContainer);
		
		var sortLabel = new Element("label");
		selectBoxContainer.appendChild(sortLabel);
		sortLabel.innerHTML = "Select";
		
		this.selectNode = new Element("select");
		selectBoxContainer.appendChild(this.selectNode);
		for (var i=0, len = this.sortingOptions.length; i<len;i++){
			var option = this.sortingOptions[i];
			var optionNode = new Element("option", {"value" : option});
			this.selectNode.appendChild(optionNode);
			optionNode.innerHTML = option;
		}
//		this.selectNode.observe("change", this.registerSortChange.bind(this)); /* if we were going to just use a standard HTML select box we would use this line to watch the change evet and set a method */
		
		var prettySelectBox = new sdk_Controls.SelectBox(selectBoxContainer); /* Now we've got a standards select box, and we are using the selectbox control that we've defined below in this document */
		prettySelectBox.registerChangeCallback(this.doSortChange.bind(this)); /* this is like using an event listener - when the custom select box is changed the method doSortChange will be run. this exists because we can't progamatically fire the select box's onchange event */
	}, 
	updateFilterOptions : function () { /* this method turns filters on the left on and off, and updates the numbers after the labels */
		for (var i = 0, len = this.filterOptions.length; i<len; i++) { /* we go through the filter options (categories) */ 
			var filter = this.filterOptions[i];
			for (var j = 0, jLen = filter.optionsMod.length; j<jLen; j++) { /* and look at each of the options  */
				var option = filter.optionsMod[j];
				var count = 0; /* we start the count at 0 */
				for (var k = 0, kLen = option.onSet.length; k<kLen; k++) { /* we look at all of the products in the onset */
					var product = option.onSet[k];
					if (product.isAvailable == true) { /* if it's available, we bump up the count  */ 
						count++;
					}
				}
				if (count == 0) { /* if there are no items available, we disable the option and remove the numbers, otherwise we add it in */
					option.checkNode.innerHTML = '<span class="sdk_FacetedNav_OptionTitle">' + option.value + '</span>';			
					this.disableOption(option.checkNode);
				}
				else {
					option.checkNode.innerHTML = '<span class="sdk_FacetedNav_OptionTitle">' + option.value + ' [' + count + ']</span>';			
					this.unDisableOption(option.checkNode);
				}
			}
		}
	},
	doFilter : function () { /* this changes the items in the available set based on which filters on the left are selected */
		var doReset = true; /* We assume that we have no filters selected and that we will need to do a reset */
		var tempVisibleSet = null; /* this is an array with which we will replace the active set */
		for (var i = 0, len = this.filterOptions.length; i<len; i++) { /* we go through the filter options (category) */
			var filter = this.filterOptions[i]; /* we will create one of these for every category  so that a correct set will be the one that matches ( category1 - matches any value  ) and (category2 - matches any value) */
			var filterVisibleSet = null; /* here we initialize this variable - it will be an array, but we need to do a test on it later*/
			for (var j = 0, jLen = filter.optionsMod.length; j<jLen; j++) { /* we're going through the options */
				var option = filter.optionsMod[j];
				if (option.checkNode._isChecked == true && option.checkNode._isDisabled == false) { /* found a filter set that's on */
					if (filterVisibleSet == null) {
						filterVisibleSet = option.onSet.clone(); /* if there hasn't been a filtering yet in this category then we make the filterVisibleSet a copy of the on set (note that this is different than having a filterVisibleSet with no items, which might occur if we need to do multiple filters) */
					} else { /* we have more than one options in the category selected on the left  */
						for (var k=0, kLen = option.onSet.length; k<kLen; k++){ /* we go through the second option's onset */
							var product = option.onSet[k];
							if (filterVisibleSet.indexOf(product) == -1 ) { /* and add it if it's not in there yet */
								filterVisibleSet.push(product);
							}
						}
					}
				}
			}
			if (filterVisibleSet != null) { /* if we've found the first active category */
				if ( tempVisibleSet == null) { /* so the active set will become that set */
					tempVisibleSet = filterVisibleSet.clone();
				} else { /* we've found a second active category, so we need to reduce it to the membrs that are in both sets */
					var tempSet = []; /* this is a set that will match all that are orret for category1 and category2 */
					for (var j=0, jLen = filterVisibleSet.length; j<jLen; j++){
						var product = filterVisibleSet[j];
						if (tempVisibleSet.indexOf(product) > -1 ) { /* it is in both the forst and the second set */
							tempSet.push(product); /* so add it to the temporary holded  */
						}
					}
					tempVisibleSet = tempSet.clone(); /* and set the temporary set (which will become the active st) */
				}
			}
		}
		if (tempVisibleSet == null) { /* in this case we have no filters selected, so we need to make them all active */
			this.resetFilter(); 
		} else  { /* or here where we need to go through all of the products and create a new active set */
			this.activeSet = [];
			for (var i = 0, len = this.products.length; i<len; i++) {
				var product = this.products[i];
				var includeProduct = (tempVisibleSet.indexOf(product) > -1) /* boolean - the product is in the active set */
				
				product.domNode.setStyle({"display": (includeProduct == true) ? "block": "none" }); /* turn it on or off, depending  */
				product.isAvailable = includeProduct; /* sets this for the update Filters above */
				if (includeProduct == true) {  
					this.activeSet.push(product); /* and add it to the active set */
				}
			}
			this.setPagination(0); /* we've got a new set so we start at the first page */
			if (this.sortMethod != "default") { /* if a sort has been requested by the user, then we apply it to the active set here */
				this.updateSort();
			}			
			this.updateFilterOptions(); /* we set the text and availability for the current filter */
		}
	},
	resetFilter: function () { /* this function resets all filters and makes all products active */
		for (var i = 0, len = this.filterOptions.length; i<len; i++) { /* go through the filter options catagories */
			var filter = this.filterOptions[i];
			for (var j = 0, jLen = filter.optionsMod.length; j<jLen; j++) { /* and the filters on the left */
				var option = filter.optionsMod[j]; 
				this.unCheckOption(option.checkNode); /* and make it unchecked */
			}
		}
		this.activeSet = []; /* we reset the active set */
		for (var i = 0, len = this.products.length; i<len; i++) { /* loop though the products, making it visible */ 
			var product = this.products[i];
			product.domNode.setStyle({"display" : "block"});
			product.isAvailable = true;
		}
		this.activeSet = this.products.clone(); /* remake the active set wil all products, set the filter states and  sort the resutls if needed and set the pagingation at the first page */
		this.updateFilterOptions();
		if (this.sortMethod != "default") { /* if a sort has been requested by the user, then we apply it to the active set here */
			this.updateSort();
		}
		this.setPagination(0);
	},
	
	/* CheckBoxBehavior */
	registerOptionClick : function (opt) { /* this is the method that responds to the click of the checkbox */
		var node = opt.checkNode; 
		if (node._isDisabled == false) { /* if it's not disabled, then toggle its state */
			if (node._isChecked == false) {
				this.checkOption(node);
			} else {
				this.unCheckOption(node);
			}
			/* and perfom the filter */
			this.doFilter();
		} 
	},
	checkOption : function (node) { /* sets the checkbox state as checked  */
		node.removeClassName("sdk_Disabled");
		node.addClassName("sdk_Checked");
		node._isChecked = true;
	},
	unCheckOption : function (node) { /* sets the checkbox state as unchecked */
		node.removeClassName("sdk_Checked");
		node._isChecked = false;
	},
	disableOption : function (node) { /* sets the checkbox state as inactive  */
		node._isDisabled = true;
		node.addClassName("sdk_Disabled");
	},
	unDisableOption : function (node) { /*sets the checkbox state as active */
		node._isDisabled = false;
		node.removeClassName("sdk_Disabled");
		if (node._isChecked == true) { /* set it back to it's checked sate */
			this.checkOption(node);
		} else {
			this.unCheckOption(node);
		}
	},
	/* Pagingation */
	setPagination : function (toPage) { /* this sets up the paginationelements toPage is zero based index of the page that we want to go to */
		var totalPerPage = 12; /* the total number of products per page */
		var totalPages = Math.ceil((this.activeSet.length) / totalPerPage); 
		
		toPage = (toPage > (totalPages - 1))? totalPages-1 : toPage ; /* safety */
		
		var startShowing = (toPage * totalPerPage);
		var stopShowing = ( (toPage+1) * totalPerPage >= this.activeSet.length) ? this.activeSet.length -1 : ((toPage+1) * totalPerPage) - 1 ;
	
		for (var i = 0; i < this.activeSet.length; i++) { /*sort through the active set, checking if the item is within our bounds */
			if ( i == startShowing) {  /* this is the first item we wnt to show */
				this.activeSet[i].domNode.setStyle({"display": "block"});
				/* turn on the next/prev buttons if needed  */
				if (toPage > 0) {
					this.paginationControls.prevBtn.setStyle({"display": "inline"});
				} else {
					this.paginationControls.prevBtn.setStyle({"display": "none"});
				}
				if ((toPage +1) == totalPages || totalPages == 1) {
					this.paginationControls.nextBtn.setStyle({"display": "none"});
				} else {
					this.paginationControls.nextBtn.setStyle({"display": "inline"});
				}
				
				/* here we set the "shoing x - x of x" text atthe top */
				var tailVisible =  ( ( (toPage + 1) * totalPerPage) > this.activeSet.length ) ? this.activeSet.length : ((toPage+1) * totalPerPage);
				this.paginationControls.currentVisibleText.innerHTML = ((toPage * totalPerPage) + 1) + " - " + tailVisible;
				this.paginationControls.totalPotentialVisible.innerHTML = this.activeSet.length;
				
			} else if ( i > startShowing && i <= stopShowing ){ /* it's within the bounds*/
				this.activeSet[i].domNode.setStyle({"display": "block"});
			} else { /* it's not so we turn it off */
				this.activeSet[i].domNode.setStyle({"display": "none"});
			}
		} 
		this.atPage = toPage;
	},
	paginateNext : function () {
		this.setPagination(this.atPage + 1);
	},
	paginatePrev : function () {
		this.setPagination(this.atPage - 1);
	},
	
	/*Sorting*/
	doSortChange : function () { /* this gets run when the select box is changesd  */
		this.sortMethod = this.selectNode.getValue();
		this.updateSort();
	},
	
	updateSort : function () {
		
		/*first we need to determine the sort order*/
		var newOrder = []; /* this array will containe a list of indexes that will reflect the new order of our activeSet*/
		var comparisionArray = []; /* this array will contain the values against which we will compare the product's sortingValue*/
		
		/*sort through all of the products in the active set*/
		for (var i = 0, len = this.activeSet.length; i<len; i++) {
			var product = this.activeSet[i];
			/* sorth through that products sortingValues to find the one that matches our current sortingMethod*/
			for (var j = 0, jLen = product.sortingValues.length; j<jLen; j++) {
				var sortingVal =  product.sortingValues[j];
				/* find the product's sort method that matches our current sortingMethod*/
				if (this.sortMethod == sortingVal.name) { 
					/* if there's nothin in our newOrder Array, then set this object as the first item in the comparisonArray and newOrder*/
					if (newOrder.length == 0) {
						newOrder[0] = i;
						comparisionArray[0] = sortingVal.value;
					} else {
						/* otherwise, compare the product's value to the existing values we've already */
						/* added to the comparisonArray and put them in an array, large to small*/
						for (var k = 0; k<comparisionArray.length; k++) {
							/* it's bigger or the same, so add it before */
							if (sortingVal.value > comparisionArray[k] || sortingVal.value == comparisionArray[k]) { 
								comparisionArray.splice(k, 0, sortingVal.value);
								newOrder.splice(k, 0, i);
								break;
							} 
							/* we're at the end, so attach it there*/
							if (k + 1 == comparisionArray.length) { 
								comparisionArray.push(sortingVal.value);
								newOrder.push(i);
								break;
							}
						}
					}
				}
			}
		}
		
		var tempActiveArray = [];
		
		/*go through the products and assign them to the correct position in the active set*/
		for (var i = 0, len = newOrder.length; i<len; i++) {
			var product = this.activeSet[newOrder[i]];
			this.productContainer.appendChild(product.domNode);			
			if (product.isAvailable == true) {
				tempActiveArray.push(product);
			}
		}
		/* this only changes the order of the active set, nothing else */
		this.activeSet = [];
		this.activeSet = tempActiveArray;
		this.setPagination(this.atPage);
	}
});

sdk_Controls.ProductComparison = Class.create({
	CONSTANTS : {
		indicatorImageOnSrc : "images/ProductComaprison_ArrowPreview.gif", /* here are the mouseover images */
		indicatorImageOffSrc : "images/ProductComaprison_Ball.gif"
	},
	initialize : function(container) { 
		this.selectedIndex = 0;
		this.cellGroups = [];
		
		var rows = container.select("tbody tr");

		for( var i=0, len = rows.length; i<len; i++ ) {
			/* go through the rows and get the cells */
			var cells = rows[i].select("td");
			for( var j=0, jLen = cells.length; j<jLen; j++ ) {
				var cell = cells[j];
				if (i == 0) {
					/* if it's the first pass, then set up the cell group */
					this.cellGroups[j] = {
						indicatorImage : cell.select(".sdk_ProductComaprison_indicatorImage")[0],
						cells : []
					};
				}
				if (cell.hasClassName("sdk_Selected") == false) { /*if it's selected, we ignore it */
					cell.observe("mouseover", this.previewProduct.bind(this, j)); /* on the mouseover/out we run the method previewProduct/unPreviewProduct with the index as an arg */
					cell.observe("mouseout", this.unPreviewProduct.bind(this, j));
				}			
				this.cellGroups[j].cells.push(cell);
			}
		}
	},
	previewProduct : function(index) {
		/* switches the image src and adds a class */
		var cg = this.cellGroups[index];
		cg.indicatorImage.setAttribute("src", this.CONSTANTS.indicatorImageOnSrc);
		for(i=0, len = cg.cells.length; i<len;i++) {
			var cell = cg.cells[i].addClassName("sdk_Selected");
		}
	},
	unPreviewProduct : function(index) {
		/* switches the image src and removes a class */
		var cg = this.cellGroups[index];
		cg.indicatorImage.setAttribute("src", this.CONSTANTS.indicatorImageOffSrc);
		for(i=0, len = cg.cells.length; i<len;i++) {
			var cell = cg.cells[i].removeClassName("sdk_Selected");
		}
	}
});

sdk_Controls.ProductPurchaser = Class.create({
	initialize : function(container) {
		/* we get the items and set the default selection */
		this.selectorItems = container.select(".sdk_ProductPurchaser_SelectorItem");
		var selectedIndex = 0;
		/* here's where we get the nodes that we will be writing the values to */
		this.selectionTitle = container.select(".sdk_ProductPurchaser_SelectionTitleValue")[0];
		this.selectionItemNumber = container.select(".sdk_ProductPurchaser_SelectionItemNumberValue")[0];
		this.selectionPriceContainer= container.select(".sdk_ProductPurchaser_SelectionPrice")[0];
		this.selectionPrice= container.select(".sdk_ProductPurchaser_SelectionPriceValue")[0];
		this.selectionSalePriceContainer = container.select(".sdk_ProductPurchaser_SelectionSaleNewPrice")[0];
		this.selectionSalePrice = container.select(".sdk_ProductPurchaser_SelectionSaleNewPriceValue")[0];
		this.selectionShippingTime = container.select(".sdk_ProductPurchaser_SelectionShippingTimeValue")[0];
		
		for( var i=0, len = this.selectorItems.length; i<len; i++ ) {
			/* we go throught the selectors and pull out some values and get some node references */
			var item = this.selectorItems[i];
			item.selectionValues = {
				radioBtn : item.select(".sdk_ProductPurchaser_RadioButton")[0], /* THIS IS INCLUDED SO THAT THE PAGE CAN BU USED LIKE A NORMAL FORM - it is hidden default*/
				title : item.select(".sdk_ProductPurchaser_Size")[0].innerHTML,
				itemNumber : item.select(".sdk_ProductPurchaser_Number")[0].innerHTML,
				shippingTime : item.select(".sdk_ProductPurchaser_ShippingTime")[0].innerHTML,
				price : item.select(".sdk_ProductPurchaser_Price")[0].innerHTML,
				salePrice : null
			};
			/* if the sale price is set, then we do set the value and make sure that the non-sale price has the correct clasname */
			if (item.select(".sdk_ProductPurchaser_SalePrice").length >= 1) {
				item.select(".sdk_ProductPurchaser_Price")[0].addClassName("sdk_ProductPurchaser_PriceOnSale");
				item.salePrice = item.select(".sdk_ProductPurchaser_SalePrice")[0].innerHTML
			}
			/* if it's selected, the we'll put the reference here */
			if (item.hasClassName("sdk_Selected") == true) {
				selectedIndex = i;
			}
			/* when the item is moused over or out then we run the method preview/unPreview method respectivly with the index as a variable  */
			item.observe("mouseover", this.previewProduct.bind(this, i));
			item.observe("mouseout", this.unPreviewProduct.bind(this, i));
			item.observe("click", this.selectProduct.bind(this, i)); /* on the click we run the selectProduct method with the index as the variable */
		}
		this.selectProduct(selectedIndex); /*select the selectedIndex*/
	},
	previewProduct : function(index) {
		/*add the preview classname*/
		if (index != this.selectedIndex) {
			this.selectorItems[index].addClassName("sdk_Previewed");
			
		}
	},
	unPreviewProduct : function(index) {
		/*remove the preview classname*/
		if (index != this.selectedIndex) {
			this.selectorItems[index].removeClassName("sdk_Previewed");
			
		} 
	},
	selectProduct: function(index) {
		for( var i=0, len = this.selectorItems.length; i<len; i++ ) {
			/* go through the items and if it matches the index */
			var item = this.selectorItems[i];
			if (index == i) {
				/* Check the radiobutton and update the values below*/
				item.selectionValues.radioBtn.checked = true; 
				this.selectionTitle.innerHTML = item.selectionValues.title;
				this.selectionItemNumber.innerHTML = item.selectionValues.itemNumber;
				this.selectionPrice.innerHTML = item.selectionValues.price;
				this.selectionShippingTime.innerHTML = item.selectionValues.shippingTime;	
				/* here we're going through the price values based on whether or not the sale proce is set above */
				if (item.salePrice != null) {
					this.selectionPriceContainer.removeClassName("sdk_ProductPurchaser_SelectionPrice");
					this.selectionPrice.removeClassName("sdk_ProductPurchaser_SelectionPriceValue");
					this.selectionPriceContainer.addClassName("sdk_ProductPurchaser_SelectionSaleOrigPrice");
					this.selectionPrice.addClassName("sdk_ProductPurchaser_SelectionSaleOrigPriceValue");
					this.selectionSalePriceContainer.setStyle({"display": "block"});
					this.selectionSalePrice.innerHTML = item.salePrice;
				} else {
					this.selectionPriceContainer.addClassName("sdk_ProductPurchaser_SelectionPrice");
					this.selectionPrice.addClassName("sdk_ProductPurchaser_SelectionPriceValue");
					this.selectionPriceContainer.removeClassName("sdk_ProductPurchaser_SelectionSaleOrigPrice");
					this.selectionPrice.removeClassName("sdk_ProductPurchaser_SelectionSaleOrigPriceValue");
					this.selectionSalePriceContainer.setStyle({"display": "none"});
				}
				
				/* make sure that it's not prviewed and make it selected */ 
				this.unPreviewProduct(i);
				item.addClassName("sdk_Selected");
				
			} else {
				/* otherwise make sure that it's not selected off */
				item.removeClassName("sdk_Selected");
			}
		}
	}
});

sdk_Controls.Rating = Class.create({ /* THIS CONTROL NEEDS TO BE UPDATED ONCE RATING FUNTIONALITY IS SET */
	CONSTANTS : {
		onImageSrc : "images/Rating_on.gif", /* here are the locations of the images that we will use for replacing the ones that are there */
		offImageSrc : "images/Rating_off.gif",
		halfImageSrc : "images/Rating_half.gif",
		userOnImageSrc : "images/Rating_on.gif"
	},
	initialize : function(container) {
		if (container.hasClassName("sdk_isDisabled") == false) {
			this.isRatedByUser = false;
			this.ratingStars = [];
			this.ratingsText = container.select(".sdk_Rating_Label")[0];
			var starContainer = container.select(".sdk_Rating_Indecator")[0];
			
			var stars = starContainer.select("img");
			for (var i = 0, len = stars.length; i<len;i++ ) {
				var star = stars[i];
				star.origSrc = star.getAttribute("src");
				star.observe("mouseover", this.previewRating.bind(this, i));
				star.observe("click", this.registerRating.bind(this, i));
				this.ratingStars.push(star);
			}
			starContainer.observe("mouseout", this.resetRating.bind(this));
		}				
	},
	previewRating : function(index) {
		if (this.isRatedByUser == false) {
			for(var i =0, len = this.ratingStars.length; i<len; i++) {
				var star = this.ratingStars[i];
				if(i <= index) {
					star.setAttribute("src", this.CONSTANTS.userOnImageSrc);
				} else {
					star.setAttribute("src", this.CONSTANTS.offImageSrc);
				}
			}
		}
		
	},
	
	resetRating : function () {
		if (this.isRatedByUser == false) {
			for(var i =0, len = this.ratingStars.length; i<len; i++) {
				var star = this.ratingStars[i];
				star.setAttribute('src', star.origSrc);
			}
		}
	},
	
	registerRating : function(index) {
		this.isRatedByUser = false;
		this.previewRating(index);
		this.isRatedByUser = true;
		this.ratingsText.innerHTML = "Your Rating";
		// PERFORM AJAX CALL HERE
	}
});


sdk_Controls.SelectBox = Class.create({
/* this control creates a custom select box, from a standrd HTML select box - it preserves that select box and changes it's value when the custom box is changed so that it is used by forms in the standard way */
	initialize : function(container) {
		this.mainElement = container; /* here we're keeping a reference to the main container element */
		
		this.sel = container.select("select")[0]; /* and getting an reference to the select elemnt  */
		this.sel.setStyle({"display":"none"}); /*  We're going to hide that select box */
		this.options=[]; /* here's the collection of objects that has the references to the custom and non-custom select boxes */ 
		this.isOpen = false; /* by default the box is going to be closed  */
		this.isDisabled = false; /* and ins enabled - we'll be checking this of an override in a few lines */
		 
		this.onChangeCallBacks = []; /* we can't progamatically fire the select box's chage evet - only a user interaction can do that - we're going to creat an array of functions and fire all each of those functions when a custom option is selected */
		this.sel.observe("change", this._onChange.bind(this)); /* and make sure that those functions get run in the event of a user select  */
		/* he're we're going to look for a label - if it's there then we'll put it in the selecte box so that it appears to be the first */		
		var dl = container.select("label");
		var defaultLabelNode = ( dl.length > 0 ) ? dl[0] : null;
		/*now we're going to get all of the option nodes */
		var optionNodes = container.select("option");
		
		var customContainer = new Element("div", {"class": "sdk_SelectBox_CustomContainer"}); /*here we're creating a node that will contain all out custom select box and attaching it at the end of the container */
		container.appendChild(customContainer);
		
		this.labelNode = new Element("div", {"class": "sdk_SelectBox_CutomClosedLabel"}); /*here we're creating a node that will contain the label of the custom select box */
		customContainer.appendChild(this.labelNode);
		
		this.optionsContainer = new Element("div", {"class": "sdk_SelectBox_CustomContainerOptions"}); /* this will contain the custom options */
		customContainer.appendChild(this.optionsContainer); 
		
		var initSelection = 0; /* with this we're going to be checking to see which item is selected - it's the firt one by default */
		
		for (var i=0, len = optionNodes.length; i<len; i++) { /* going through all of the (non-custom) options */
			var on = optionNodes[i];
			var customNode = new Element("div", {"class": "sdk_SelectBox_CustomItem" }); /*we create a new custom node and set it's contents to be the same as new non-custom option's content */
			customNode.innerHTML = on.innerHTML;
			this.options[i] = { /*this object contains the references to the custom and non-custom nodes */
				"optionNode" : on,
				"optionCustomNode" : customNode
			};
			if (on.selected == "selected" || on.selected == true) { initSelection = i; } /* if it's selected, then we set the init selct value */
			this.optionsContainer.appendChild(customNode); /* ading it to the dom  */
			customNode.observe("click", this.selectOption.bind(this, i)); /* on the custom options node's click, then we run the method select option with the proper index */
		}
		
		this.labelNode.observe("click", this.toggleBox.bind(this)); /* on the labels click we toggle the select box state */
		
		/* here we are setting the width of the custom container to be 2 px less than the main container */
		this.optionsContainer.setStyle({"width": customContainer.getWidth() - 2 + "px" })
		
		/* if we don't have a label then we select the initSelection */
		if (defaultLabelNode == null ) {
			this.selectOption(initSelection);
		} else { /* otherwise we set the lable to be the default text */ 
			this.labelNode.innerHTML = defaultLabelNode.innerHTML;
			defaultLabelNode.setStyle({"display": "none"}); /*and hide the label and close up the box */
			this.closeBox();
		}
		/* if the original select box i disabled, then we disable the custombox */
		if (this.sel.getAttribute("disabled") == "disabled" || this.sel.disabled == true || this.sel.hasClassName("sdk_Disabled") == true) {
			this.doDisable();
		}
		
		this.mainElement.observe("mouseout", this.registerMouseleave.bindAsEventListener(this));
		
	},
	registerMouseleave : function (e) {
		if (!e) var e = window.event;
		var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;
		
		while (reltg != this.mainElement && reltg.nodeName != 'BODY')
			reltg= reltg.parentNode
		if (reltg== this.mainElement) return;

		this.closeBox();

	},
	registerChangeCallback : function (func) {
		/* here we just add a function to the array */
		if (typeof(func) == "function") {
			this.onChangeCallBacks.push(func);
		}
	},
	_onChange : function () {
		/* this gets called from the selectOption method */
		for (var i=0; i<this.onChangeCallBacks.length; i++) {
			/* we call all of the functions */
			this.onChangeCallBacks[i]();
		}
	},
	selectOption : function(index) {
		/*go through the options */
		for (var i=0, len = this.options.length; i<len; i++) {
			var opt = this.options[i];
			if (i == index) { /* if it's selected, then we set the label's content to be the label and make sure that the hidden non-custom select box's selection get's updated too, so that it can be used in forms normally */
				this.labelNode.innerHTML = opt.optionCustomNode.innerHTML;
				opt.optionNode.selected = true;
				this.sel.selectedIndex = index;
			} else {
				/* otherwise turn it off */
				opt.optionNode.selected = false;
			}
		}
		/* fire the callbacks and close up the box */
		this._onChange();
		this.closeBox();
	},
	toggleBox : function () {
		/* as long as the box isn't disabled, open it if it's closed, and close it if it's opn */
		if (this.isDisabled == false) {
			if (this.isOpen == false) {
				this.openBox();	
			} else {
				this.closeBox();
			}
		}		
	},
	openBox : function() {
		/* we get the position and height of the label node and set the conainer's position */
		var os = this.labelNode.positionedOffset();
		this.optionsContainer.setStyle({"top": (os[1]) + this.labelNode.getHeight() - 4 + "px", "left": os[0] + "px", "position": "absolute", "display": "block"});
		this.isOpen = true;
	},
	closeBox : function() {	
		/* simply hide it */
		this.optionsContainer.setStyle({"display": "none"});
		this.isOpen = false;
	},
	doDisable : function () {
		/*this changes it visually and prevents it from responding to clicks */ 
		this.isDisabled = true;
		this.mainElement.addClassName("sdk_Disabled");
		this.closeBox();
	},
	doUnDisable : function () {
		
		this.mainElement.removeClassName("sdk_Disabled"); /* changes the style and starts responding to clicks */
		this.isDisabled = false;
	}
});

sdk_Controls.TabViewer = Class.create({
	initialize : function(container) { 
		var tabContainer = new Element("div", {"class" : "sdk_TabViewer_Tabs"}); /* here we create two stub elements, in which we will attach the tabs and panes */	
		var paneContainer = new Element("div", {"class" : "sdk_TabViewer_Panes"}); 
		container.appendChild(tabContainer);/* here we attach those two elements at the end of the continer */		
		container.appendChild(paneContainer); 
		this.pairings = [];/* we're creating an array for objects that will contian references to the  arrays for the tab and panes*/		
		/* this is were we're going to  be reorganizing the DOM and check to see which tab is on by default - the first on (0) is the default */		
		var selectIndex = 0;	 /* here we get the items that were loaded into the dom */		
		var tbs = container.select(".sdk_TabViewer_Content");
		for (var i = 0, len = tbs.length; i< len; i++) {
			var tb = tbs[i]; /*if it's got the selected classname, then we will be turning it on once the dom is reorganized*/			
			selectedIndex = (tb.hasClassName("sdk_Selected") == true) ? i : selectedIndex;  /* we ge the title node  */
			var tabItem = tb.select(".sdk_TabViewer_Title")[0]; /* when it gets clicked, then we run the method show tab */			
			tabItem.observe("click", this.showTab.bind(this, i)); /* and add it to the tabs array */			
			tabContainer.appendChild(tabItem);
			var contentItem = tb.select(".sdk_TabViewer_TabText")[0]; /* here we get the text content, and put it into the stub panes node */
			paneContainer.appendChild(contentItem);
			this.pairings.push({"tab": tabItem , "pane": contentItem}); /* here we add an object that has a reference to both the tab and the pane  */
		}
		this.showTab(selectIndex); /* and turn on the selected node from above - the first is the default */
	
	}, 
	showTab : function(index) {
		/* here we go through each of the pairings */
		for (var i = 0, len = this.pairings.length; i<len; i++)	 {
			var pr = this.pairings[i];			
			pr.tab.removeClassName("sdk_Selected");/* and turn off the tab and the pane */
			pr.pane.setStyle({"display": "none"}); 
		}
		this.pairings[index].tab.addClassName("sdk_Selected"); /* and turn on the tab and pane that's selected */
		this.pairings[index].pane.setStyle({"display": "block"});
	}
});

sdk_Controls.HelpBox = Class.create({
	initialize : function(container) {
		var selectBoxes = container.select(".sdk_Control_SelectBox"); /* here we look for the select boxes */	
		var selectBox1 = selectBoxes[0];
		var selectBox2 = selectBoxes[1];
		var prettySelectBox1 = new sdk_Controls.SelectBox(selectBox1);	/* and give them controlbox styles */
		var prettySelectBox2 = new sdk_Controls.SelectBox(selectBox2);	
		prettySelectBox1.registerChangeCallback(prettySelectBox2.doUnDisable.bind(prettySelectBox2));/* here we're maxing sure to enable the second select box when the first one is changed */
	}
});