/* ***********************************************************************************************************************************
    pricing manager
 *********************************************************************************************************************************** */

// Component that helps juggle the various price objects
function pricingManager(kingCartproductInstance, woodSelectionManagerInstance) {
    this.productInstance = kingCartproductInstance;
    this.woodSelectionManagerInstance = woodSelectionManagerInstance;
    this.quantity = 1;
    this.elPriceEstimateDisplayElement;

    this.initialize();
}
pricingManager.prototype.initialize = function() {
    this.initializePriceEstimateDisplayElement();
    this.initializeProductInstance();
    this.initializeWoodSelectionManager();
    this.initializeQuantityElement();

    this.setDisplayPriceForTheFirstTime();
};
pricingManager.prototype.setDisplayPriceForTheFirstTime = function() {
    var validWoodSelectionManager = !this.woodSelectionManagerInstance || (this.woodSelectionManagerInstance && this.woodSelectionManagerInstance.onReadyForUse.hasFired());
    if (this.productInstance.onReadyForUse.hasFired() && validWoodSelectionManager)
        this.setDisplayPrice();
};
pricingManager.prototype.initializePriceEstimateDisplayElement = function() {
  this.elPriceEstimateDisplayElement = $("#currentPrice");
};
pricingManager.prototype.initializeQuantityElement = function() {
  var oThis = this;
  var el = $("#quantitySelector");
  if (!this.productInstance.isMultiplePricing || !this.woodSelectionManagerInstance) {
    el
      .attr("name", this.productInstance.idFullText)
      .attr("value", "1")
      .attr("size", "4")
      .addClass("qty") // need more generic class name...
      .keyup(function() { oThis.singlePricingQuantityChanged(el.get(0)); }, false);
  } else {
    this.quantity = 0;
    el.val(this.quantity);
    var p = el.parent()
    p.addClass("hide");
    $(".multiplePricingQuantityField").each(function() {
      $(this).blur(function() { oThis.multiplePricingQuantityChanged(this); }, false);
    });
  }
};
pricingManager.prototype.initializeProductInstance = function() {
    if (this.productInstance) {
        this.productInstance.onReadyForUse.add(this.setDisplayPriceForTheFirstTime);
        this.productInstance.selectedOptionsChanged = this.getSelectedOptionChanged();
    }
};
pricingManager.prototype.initializeWoodSelectionManager = function() {
    if (this.woodSelectionManagerInstance) {
        this.woodSelectionManagerInstance.onReadyForUse.add(this.setDisplayPriceForTheFirstTime);
        if (!this.productInstance.isMultiplePricing)
          this.woodSelectionManagerInstance.woodSelectionChanged = this.getSelectedOptionChanged();
    }
};
pricingManager.prototype.multiplePricingQuantityChanged = function(srcElement) {
    if (srcElement.value.length == 0) return;

    var n = srcElement.value;
    var isValidChar = true;
    var oThis = this;
    if (isNaN(n)) {
        n = (isNaN(parseInt(n)) ? 1 : parseInt(n));
        srcElement.value = n;
        isValidChar = false;
    }

    this.quantity = 0;
    $(".multiplePricingQuantityField").each(function(i) {
      if ($(this).attr("name") != "")
        oThis.quantity += parseInt(this.value);
    });
    var el = $("#quantitySelector").val(this.quantity);
    this.setDisplayPrice();

    return isValidChar;
};
pricingManager.prototype.singlePricingQuantityChanged = function(srcElement) {
    if (srcElement.value.length == 0) return;

    var n = srcElement.value;
    var isValidChar = true;
    if (isNaN(n)) {
        n = (isNaN(parseInt(n)) ? 1 : parseInt(n));
        srcElement.value = n;
        isValidChar = false;
    }

    if (n == 0)
        n = 1;
    if (this.quantity != n) {
        this.quantity = n;
        this.setDisplayPrice();
    }

    return isValidChar;
};

pricingManager.prototype.getSelectedOptionChanged = function() {
    var oThis = this;
    return function() { oThis.setDisplayPrice(); }
};
pricingManager.prototype.setDisplayPrice = function() {
  if (this.elPriceEstimateDisplayElement.length == 0) 
    return;
  var unitPrice = this.productInstance.getQuantityPrice(this.quantity);
  var woodPrice = 0;
  var optionPrice = this.productInstance.getSelectedOptionsPrice();
  var displayValue = 0;

  if (this.woodSelectionManagerInstance) {
      this.woodSelectionManagerInstance.updateOptionDisplayPrice(unitPrice);
      if (this.woodSelectionManagerInstance.selectedOption)
          woodPrice = this.woodSelectionManagerInstance.selectedOption.price;
  }

  displayValue = formatDollar((unitPrice + woodPrice + optionPrice) * this.quantity);
  
  this.elPriceEstimateDisplayElement.text(displayValue);
};

/* ***********************************************************************************************************************************
    Product
 *********************************************************************************************************************************** */
// Creates an instance of a "King Cart Product"
var kingCartProductInstance;
function createKingCartProduct(productIdString) {
    try {
        kingCartProductInstance = new product(productIdString);
    } catch(err) {
        if (debug) alert(err);
    }
}

// A King Cart Product object
function product(productIdString) {
    var parts = productIdString.split("|");

    this.idFullText = productIdString;
    this.id = parts[0];
    this.category = parts[1];
    this.basePrice = parts[2];
    this.name = parts[3];
    this.imageFile = parts[4];
    this.shippingWeight = parts[5];

    this.isMultiplePricing = false;
    this.options = new Array();
    this.pricingTable = new Array();
    this.onReadyForUse = new ClassEvent();

    this.selectedOptionsChanged = function() { };

    this.initialize();
    
    return this;
}
product.prototype.initialize = function() {
    var prices = this.basePrice.split(",");
    for (var i = 0; i < prices.length; i++)
        this.pricingTable[i] = new productPriceItem(prices[i]);
    this.isMultiplePricing = this.pricingTable.length > 1;
    this.initializeOptions();

    this.onReadyForUse.fire();
};
product.prototype.initializeOptions = function() {
    var inputElements = document.getElementsByTagName("input");

    for (var i = 0; i < inputElements.length; i++) {
        var item = inputElements[i];
        if (item.name && item.name.toLowerCase().indexOf("option|") > -1) {
            this.appendToOptionGroup(item);
        }
    }
};
product.prototype.parseProductId = function() {
    return this.id.replace("item-", "");
};
product.prototype.getQuantityPrice = function(quantity) {
    if (this.isMultiplePricing) {
        var max = this.pricingTable.length - 1;
        for (var i = 0; i < max; i++)
            if (quantity <= this.pricingTable[i].quantityThreshold)
                return this.pricingTable[i].publicPrice;
        return this.pricingTable[max].publicPrice // Cycled through them all; must be the last
    }
    else
        return this.pricingTable[0].publicPrice;

    return 0; // If we make it here something's not right; set to 0...
};
product.prototype.getSelectedOptionsPrice = function() {
    var t = 0;
    for (var i = 0; i < this.options.length; i++)
        t += this.options[i].selectedOption.price;
    return t;
};
product.prototype.appendToOptionGroup = function(item) {
    var ix;

    if (!(ix = this.containsOptionGroup(item.name))) {
        ix = this.options.length;
        this.options[ix] = new productOptionGroup(this, item.name);
    }

    this.options[ix].addOption(item);
};
product.prototype.containsOptionGroup = function(name) {
    for (var i = 0; i < this.options.length; i++)
        if (this.options[i].name == name)
            return i.toString(); // toString() prevents confusion between "false" and "0"
    return false;
};
// Represents all the permutations of a price that can exist...
function productPriceItem(priceText) {
    this.publicPrice;
    this.dealerPrice;
    this.quantityThreshold = 1;
    
    this.priceText = priceText;

    this.initialize();
    
    return this;
}
productPriceItem.prototype.initialize = function() {
    if (this.priceText.indexOf("&") > -1)
        this.setDealerPrice();
    if (this.priceText.indexOf("/") > -1) {
        this.setQuantityThreshold();
    }
    this.setPublicPrice();

    this.priceText = null;
};
productPriceItem.prototype.setDealerPrice = function() {
    var parts = this.priceText.split("&");
    this.priceText = parts[0];
    this.dealerPrice = this.parsePrice(parts[1]);
};
productPriceItem.prototype.setQuantityThreshold = function() {
    var parts = this.priceText.split("/");
    this.priceText = parts[0];
    this.quantityThreshold = parseInt(parts[1]);
};
productPriceItem.prototype.setPublicPrice = function() {
    this.publicPrice = this.parsePrice(this.priceText);
    if (!this.dealerPrice)
        this.dealerPrice = this.publicPrice
};
productPriceItem.prototype.parsePrice = function(text) {
    if (text && text.length > 0)
        return parseFloat(text.replace(" ea", ""));
    return 0;
};
// represents options that can be attached to a product
function productOptionGroup(parentProduct, name) {
    this.options = new Array();
    this.name = name;
    this.selectedOption;
    this.parentProduct = parentProduct;
}
productOptionGroup.prototype.addOption = function(option) {
    this.options[this.options.length] = new productOption(this, option);
};
productOptionGroup.prototype.setSelectedOption = function(option) {
    this.selectedOption = option;
    this.parentProduct.selectedOptionsChanged();
};

function productOption(parentGroup, option) {
    this.parentGroup = parentGroup;
    this.element = option;
    this.price = 0;

    this.initialize();
}
productOption.prototype.initialize = function() {
    if (this.element.value) {
        var parts = this.element.value.split("|");
        if (parts.length >= 1)
            this.price = parseFloat(formatDollar(parts[1]));
    }
    if (this.element.checked)
        this.parentGroup.selectedOption = this;

    $(this.element).click(this.getSelectFunction());
};
productOption.prototype.getSelectFunction = function() {
    var oThis = this;
    return function() {
        oThis.parentGroup.setSelectedOption(oThis);
    };
};

// Passthrough method for backwards-compatability w/ hard-coded options files
function updateOptionPrice(event) {}
