//---------------------------------------------
// OCP Framework
//
// Dropdown maintenance functions for multi-
// variant display.
//
//--------------------------------------------------------------------------

var __pvdsArray = new Array();

function __getDropdownSupport(listObj)
{
	var idx = 0;
	while (idx < __pvdsArray.length)
	{
		if (__pvdsArray[idx].__list == listObj)
			return __pvdsArray[idx];

		idx++;
	}

	return null;
}

function ProductVariantDropdownSupport(listName, productID, complimentaryLists, productVariants, callbackFunc, primary, selectedValue, defaultText, defaultValue) {
   return ProductVariantDropdownSupport(listName, productID, complimentaryLists, productVariants, callbackFunc, primary, selectedValue, defaultText, defaultValue, null);
}

//--------------------------------------------------------------------------
// Creating the support structure for a variant dropdown,
// specify the name of the dropdown, not the actual object
function ProductVariantDropdownSupport(listName, productID, complimentaryLists, productVariants, callbackFunc, primary, selectedValue, defaultText, defaultValue, indexId)
{
	// Private fields
   this.__attribCallback      = null;
   this.__arDefOpts           = new Array();

   this.__attributeName       = listName;
     
   if (indexId!=null) {
     this.__list                = document.getElementById(listName + productID + +indexId+ "Variants");
   } else {
     this.__list                = document.getElementById(listName + productID + "Variants");
   }
   this.__complimentaryLists  = complimentaryLists;
   this.__productVariants     = productVariants;
   this.__selectedValue       = selectedValue;

   this.__defaultText         = (arguments.length > 7 ? defaultText : "Select One");
   this.__defaultValue        = (arguments.length > 8 ? defaultValue : "");

	// Public fields
   this.isPrimary             = primary;
   this.productID             = productID;
   this.indexId               = indexId;


	// Add this directly to the list
	this.__list.productVariantDropdownSupport = this;

   // We use this global array because we need to find
   // the primary list for complimentary/dependent lists
   __pvdsArray[__pvdsArray.length] = this;

	// Register a formatter callback
	if (callbackFunc != "")
		this.setAttributeFormatCallback(callbackFunc);

	// Get the selected value for this dropdown
	var selVariant = this.__productVariants.getSelectedVariant();
	if (selVariant != null)
		this.__selectedValue = selVariant.getAttributeValue(this.__attributeName);

	// Load the data if this is the primary
	this.loadDropdown();

	// Register the event we want to respond to
	if (this.__list.attachEvent)
	{
		// This is Internet Explorer
		this.__list.attachEvent("onchange", this.updateLists);
	}
	else if (this.__list.addEventListener)
	{
	   // This is Mozilla/Firefox
		this.__list.addEventListener("change", this.updateLists, true);
	}
}

// Callback function when dropdowns are loaded
// The callback function should be in the form:
//
//   function cbFuncName(list, attribute, optionObj)
//
// When adding attributes to a dropdown, this method
// will pass to the callback the list object that is being
// modified, the VariantAttribute object, and the Option
// object that will be appended to the list
// The callback should return an Option object that
// will be added to the dropdown list.

function pvds_setAttributeFormatCallback(cbFuncPointer)
{
   if (cbFuncPointer == null)
      return;

   // Determine that the object pass in is a function
   if (typeof cbFuncPointer != "function")
   {
      // Throw an exception
      var err = new Error("The attribute format callback must be a function pointer");
      throw err;
   }

   // Check it's length (should be 3 parameters)
   if (cbFuncPointer.length != 3)
   {
      // Throw an exception
      var err = new Error("The attribute format callback must take 3 parameters");
      throw err;
   }

   // Function ok, set it
   this.__attribCallback = cbFuncPointer;

}

//--------------------------------------------------------------------------

// Clear a dropdown's options
function pvds_clearDropdown()
{
   while (this.__list.options.length > 0)
      this.__list.remove(0);
}

function pvds_addDefault()
{
	var dOpt = document.createElement("option");
	dOpt.text = this.__defaultText;
	dOpt.value = this.__defaultValue;
	try
	{
      // IE likes it this way
      this.__list.add(dOpt);
   }
   catch (ex)
   {
      // The W3C DOM specifies the second parameter is required
      this.__list.add(dOpt, null);
   }
}

// Returns the primary drop-down for any list provided
function pvds_getPrimary()
{
	if (this.isPrimary)
		return this;
	else
	{
		for (var x = 0; x < __pvdsArray.length; x++)
			if ((__pvdsArray[x].productID == this.productID) &&
				 (__pvdsArray[x].isPrimary))
				return __pvdsArray[x];
	}

	return null;
}

function pvds_getPrimarySelectedValue()
{
	var primary = this.getPrimary();
	return primary.__selectedValue;
}

// Load all of the unique attributes of a
// particular name into a dropdown list
function pvds_loadDropdown()
{
   // Clear the dropdown
   this.clearDropdown();

   // Add the default option
	this.addDefault();

	// All lists start out as disabled
	this.__list.disabled = true;

	// Primary lists are never disabled
	if (this.isPrimary)
		this.__list.disabled = false;

	// Enable a list that has a value selected
	if (this.__selectedValue != "")
		this.__list.disabled = false;

   var primarySelOpt = (this.getPrimarySelectedValue() != "");

	if (!this.isPrimary && primarySelOpt)
		this.__list.disabled = false;

	// Don't need to load the list if nothing selected and not primary and primary has no selected options
	if (!this.isPrimary && !primarySelOpt && (this.__selectedValue == ""))
		return;

   // Get all of the unique values
	var arAttributeList = null;
   if (!this.isPrimary && this.getPrimarySelectedValue() != "")
   {
      var arMatchingVariants = this.__productVariants.getVariantsMatching(this.getPrimary().__attributeName, this.getPrimarySelectedValue());
      arAttributeList = getAttributesWithNameFromVariants(arMatchingVariants, this.__attributeName)
   }
   else
      arAttributeList = this.__productVariants.getAttributesWithName(this.__attributeName);

   // Load the array of values
   for (var idx = 0; idx < arAttributeList.length; idx++)
   {
      // Create new element
      var opt = document.createElement("option");
      opt.text = arAttributeList[idx].value;
	  if (this.__attributeName=="Size") {
		 try {
			var attribs = new Array();
			attribs[0]=arAttributeList[idx];
			var selVariant = this.__productVariants.getVariantsMatching("Size",arAttributeList[idx].value);
			opt.text = selVariant[0].sizeDisplay;
		  }   catch (ex) {};
	  }     
      opt.value = arAttributeList[idx].value;

      // Give them a chance to modify the option object
      if (this.__attribCallback != null)
         opt = this.__attribCallback(this.__list, arAttributeList[idx], opt);

		try
		{
			// IE likes it this way
			this.__list.add(opt);
		}
		catch (ex)
		{
			// The W3C DOM specifies the second parameter is required (mozilla/firefox)
			this.__list.add(opt, null);
		}

		// Is this a selected option?
		if (this.__selectedValue == opt.value)
			opt.selected = true;
   }

	// Set the variant form field to the selected value
	this.setVariantField();
}

// Update dropdown lists, relative to a changed element
// in another list.  ie:
//    Change size from small to medium and update the
//    color dropdown to show all of the colors for
//    that size.
function pvds_updateLists(evt)
{
   var dropdown = (evt.target) ? evt.target : evt.srcElement;
   var thisObj = __getDropdownSupport(dropdown);

   var arDependentAttribs = thisObj.__complimentaryLists.split(",");

	// Anything to update??
	if (!(arDependentAttribs.length == 1 && arDependentAttribs[0] == ""))
	{
		// Get the variants which match the selected attribute
		var sAttribValue = thisObj.__list.options[thisObj.__list.selectedIndex].value;
		var arMatchingVariants = thisObj.__productVariants.getVariantsMatching(thisObj.__attributeName, sAttribValue);

		for (var lIdx = 0; lIdx < arDependentAttribs.length; lIdx++)
		{
			// The name of the list = [name]Variants
			if (thisObj.indexId!=null) {
			  var listName = arDependentAttribs[lIdx] + thisObj.productID + thisObj.indexId + "Variants";
			} else {
			  var listName = arDependentAttribs[lIdx] + thisObj.productID + "Variants";
			}

			// Refresh the proper list(s)
			var compList = document.getElementById(listName);

			// Get the ProductVariantDropdownSupport object
			var pvdsObj = __getDropdownSupport(compList);

			var sSelection = "";

			// 1) Enable list
			//    -or-
			//    If enabled, grab the selected option's name so we
			//    can retain that selection if possible
			if (compList.disabled)
				compList.disabled = false;
			else
				sSelection = compList.options[compList.selectedIndex].value;

			// 2) Clear the list
			pvdsObj.clearDropdown();

			// 3) Add default option
			pvdsObj.addDefault();

			// 4) Load the values
			var arAttribs = getAttributesWithNameFromVariants(arMatchingVariants, arDependentAttribs[lIdx]);
			for (var idx = 0; idx < arAttribs.length; idx++)
			{
				// Create new element
				var opt = document.createElement("option");
				opt.text = arAttribs[idx].value;
				opt.value = arAttribs[idx].value;

				// Give them a chance to modify the option object
				if (pvdsObj.__attribCallback != null)
					opt = pvdsObj.__attribCallback(compList, arAttribs[idx], opt);

				if (sSelection == arAttribs[idx].value)
					opt.selected = true;

				try
				{
					// IE likes it this way
					compList.add(opt);
				}
				catch (ex)
				{
					// The W3C DOM specifies the second parameter is required
					compList.add(opt, null);
				}
			}

			// Disable this list if there are no elements in the dropdown
			if (arAttribs.length == 0)
				pvdsObj.__list.disabled = true;
		}
	}

	// Set the variant form field to the selected value
	thisObj.setVariantField();
}

// Set the hidden form field that is tied to this variant with
// the value of the combined variant attributes.
function pvds_setVariantField()
{
   // Find the variant that matches this type
   var variantArray = this.__productVariants.getVariantGroup();
   var attribs = new Array();
   for (var x = 0; x < variantArray.length; x++)
   {
           if (this.indexId!=null) {
           	   var pvds = document.getElementById(variantArray[x] + this.productID + this.indexId + "Variants").productVariantDropdownSupport;
           } else {
             	   var pvds = document.getElementById(variantArray[x] + this.productID + "Variants").productVariantDropdownSupport;
           }
		if (pvds)
			attribs[attribs.length] = new VariantAttribute(variantArray[x], pvds.getSelectedOption().value);
   }

   var selVariant = this.__productVariants.getVariant(attribs);

   // Set the form field
   try {
      //alert(this.__productVariants.getFormField()+" set to "+ selVariant.getId());
      document.getElementById(this.__productVariants.getFormField()).value = selVariant.getId();
      //custom to mason

      document.getElementById(this.__productVariants.getFormField()+'defaultPrice').value = selVariant.defaultPrice;
      document.getElementById(this.__productVariants.getFormField()+'clearancePrice').value = selVariant.clearancePrice;
      document.getElementById(this.__productVariants.getFormField()+'msrp').value = selVariant.msrp;
      //call a function to update the display on the page.
      if ( typeof window.updateDisplay == "function" ) {
        window.updateDisplay(this.__productVariants.getFormField());
      }
   }
   catch (ex)
   {
		// They've probably selected something invalid... or haven't selected from this yet
		//alert(ex.name+"-"+ex.message);
		document.getElementById(this.__productVariants.getFormField()).value = "";
   }
}

function pvds_getSelectedOption()
{
	return this.__list.options[this.__list.selectedIndex];
}

function pvds_getProductVariants()
{
	return this.__productVariants;
}

ProductVariantDropdownSupport.prototype.setAttributeFormatCallback   = pvds_setAttributeFormatCallback;
ProductVariantDropdownSupport.prototype.clearDropdown                = pvds_clearDropdown;
ProductVariantDropdownSupport.prototype.addDefault                   = pvds_addDefault;
ProductVariantDropdownSupport.prototype.loadDropdown                 = pvds_loadDropdown;
ProductVariantDropdownSupport.prototype.updateLists                  = pvds_updateLists;
ProductVariantDropdownSupport.prototype.getSelectedOption            = pvds_getSelectedOption;
ProductVariantDropdownSupport.prototype.getPrimary                   = pvds_getPrimary;
ProductVariantDropdownSupport.prototype.getPrimarySelectedValue      = pvds_getPrimarySelectedValue;
ProductVariantDropdownSupport.prototype.getProductVariants           = pvds_getProductVariants;
ProductVariantDropdownSupport.prototype.setVariantField              = pvds_setVariantField;
