/**
 * Cost - Splits a cost in net, tax and vat.
 */
var Cost = function(net, tax, vat) {
  this.net = new EFloat(net).val;
  this.tax = new EFloat(tax).val;
  this.vat = new EFloat(vat).val;
  this.debug = ''; // Debug Calculation
  this.d = function(s) {
    this.debug += (s + '\n');
  };

  /**
   * Adds the cost object to this instance (this instance will change). Also returns a new Cost object.
   * @param c a Cost object
   * @param returnNewObject if true this function will return a new Cost instance as well as doing its regular duties.
   * @return object undefined or a new Cost object with the performed addition.
   */
  this.add = function(c, returnNewObject) {
    this.net += c.net;
    this.tax += c.tax;
    this.vat += c.vat;
    if (returnNewObject) {return new Cost(this.net, this.tax, this.vat);}
    return undefined;
  };

  this.getTotal = function() {
    return this.net + this.tax + this.vat;
  };

  this.negatedTotal = function() {
    return (-1) * this.getTotal();
  };

  /**
   * Clones the current instance and negates all values.
   */
  this.negate = function() {
    var retVal = new Cost(0, 0, 0);
    retVal.net = (-1) * this.net;
    retVal.tax = (-1) * this.tax;
    retVal.vat = (-1) * this.vat;
    return retVal;
  };

  /**
   * Returns a new object, does not affect instance
   */
  this.plus = function(cost) {
    var net = this.net,tax = this.tax,vat = this.vat;
    return new Cost(net + cost.net, tax + cost.tax, vat + cost.vat);
  };

  /**
   * Returns a new object, does not affect instance
   */
  this.minus = function(cost) {
    var net = this.net,tax = this.tax,vat = this.vat;
    //console.log([net - cost.net, tax - cost.tax, vat - cost.vat])
    return new Cost(net - cost.net, tax - cost.tax, vat - cost.vat);
  };

  /**
   * Returns a new object, does not affect instance
   */
  this.copy = function() {
    return new Cost(this.net, this.tax, this.vat);
  }
};

/**
 * @param id discount item id. can be a negative value which indicates that it is only used for display purposes.
 * @param selected is this discount selected
 * @param name a string which describes all selected discounts as one item (generic name for a set of selected discounts)
 * @param discountCost a Cost object - value/worth of this discount
 * @param prodCartId the id of the row where we will display the total for all the selected bonuses
 */
var DiscountItem = function(id, selected, name, discountCost, prodCartId, associatedCartItemId,
                            associatedCartItemCost) {
  this.id = id;
  this.selected = selected;
  this.name = name;
  this.discountCost = discountCost;
  this.prodCartId = prodCartId;
  this.associatedCartItemId = associatedCartItemId;
  this.associatedCartItemCost = associatedCartItemCost;
  this.overflowing = null;

  this.isSelected = function() {
    return isTrue(this.selected);
  };

  this.getDiscountCost = function() {
    return this.discountCost;
  };

  this.getCheckBoxElement = function() {
    return document.getElementById('discountItem_' + this.id + "");
  };

  this.select = function(selected) {
    this.selected = selected;
    var cb = this.getCheckBoxElement();
    if (cb) cb.checked = this.isSelected();
  };

  this.getAssociatedCartItemCost = function() {
    return this.associatedCartItemCost;
  };

  /**
   * Is this item on item which has enough bonuses to zero the price.
   */
  this.isOverflowing = function() {
    return this.overflowing;
  };

  this.setOverflowing = function(overflow) {
    this.overflowing = overflow;
  }
};

/**
 * cart.add(new CartItem(32,false,undefined,3,'Internetbank (${costTotal})',new Cost('0','0','0')));
 *
 * Represents a Cart Item for a selectable Product.
 */
var CartItem = function(id, selection, validationErrorSelection, groupId, groupExclusive, name, cost) {
  this.id = id;
  this.selection = selection;
  this.validationErrorSelection = validationErrorSelection;
  this.groupId = groupId;
  this.groupExclusive = groupExclusive;
  this.name = name;
  this.cost = cost;

  this.getValidationErrorSelection = function() {
    var sel = this.validationErrorSelection;
    return sel == undefined ? sel : isTrue(sel);
  };

  this.isSelected = function() {
    return isTrue(this.selection);
  };

  this.isGroupExclusive = function() {
    return isTrue(this.groupExclusive);
  };

  this.hasSelection = function() {
    return this.selection != undefined;
  };

  this.getCost = function() {
    return this.cost;
  };

  this.getYesElement = function() {
    return document.getElementById('cartitem_' + this.id + "_true");
  };

  this.getNoElement = function() {
    return document.getElementById('cartitem_' + this.id + "_false");
  };

  this.select = function(selected) {
    this.selection = selected;
    var yElem = this.getYesElement(),
      nElem = this.getNoElement(),
      isSelected = this.isSelected(),
      id = this.id;
    if (isSelected) {
      $('#prodRowInfo_' + id).fadeIn('fast');
      $('#prodAdditionalInfo_' + id).slideDown('fast');
    } else {
      $('#prodRowInfo_' + id).hide();
      $('#prodAdditionalInfo_' + id).slideUp('fast');
    }
    if (yElem) yElem.checked = this.isSelected();
    if (nElem) nElem.checked = !this.isSelected();
  };

};

/**
 * var cart = new ShoppingCart(new Cost('36310c', '3eb52', '0'), new Cost('0', '0', '0'), 0, ',');
 * cart.add(new CartItem('VI', false, undefined, 3, true, 'VI', new Cost('75648', '0', '0')));
 * cart.add(new CartItem('CA', false, undefined, 3, true, 'CA', new Cost('5f6b8', '0', '0')));
 * cart.add(new CartItem('EC', false, undefined, 3, true, 'EC', new Cost('75648', '0', '0')));
 * cart.add(new CartItem(30, true, undefined, 3, true, 'Kontokort/kreditkort', new Cost('0', '0', '0')));
 * cart.add(new CartItem(32, false, undefined, 3, true, 'Internetbank (${costTotal})', new Cost('0', '0', '0')));
 *
 * This mama is mutable.
 */
var ShoppingCart = function(_baseCost, _additionalCost, _decimals, _decimalSepa) {
  this.baseCost = _baseCost;
  this.additionalCost = _additionalCost;
  this.decimals = _decimals;
  this.decimalSepa = _decimalSepa;
  this.items = [];
  this.itemMap = {};
  // What card is currently selected.
  this.selectedCardType = undefined;
  this.paymentTypeCardId = undefined;
  this.selectedCardTypePrefix = undefined; // currently either "xxx" (default) or "ax" (for american express)
  // discount related variables
  this.discountItems = [];
  this.discountItemMap = {};
  this.discountItemAssociatedMap = {};
  this.selectedPaymentItem = undefined;

  this.setSelectedPaymentItem = function(item) {
    this.selectedPaymentItem = item;
  };

  this.getSelectedPaymentItem = function() {
    return this.selectedPaymentItem;
  };

  /**
   * Executed on page load.
   * returns {baseCost; additionalCost; discountCosts; discountMap; sumCost}
   */
  this.updatePrices = function() {
    var costs = this.getTotalCost();
    var baseCost = costs.baseCost;
    var baseCostTotal = baseCost.getTotal();
    $('#dynSum').html(fNum(baseCostTotal, this.decimals, this.decimalSepa, 'General.Currency.Format'));
    $('#dynVat').html(fNum(baseCost.vat, this.decimals, this.decimalSepa, 'General.Currency.Format'));

    var toPay = costs.sumCost.getTotal();
    if (toPay < 0) {
      this.handleAmountBelowZero(costs);
    } else {
      $('#dynSumTot').html(fNum(toPay, this.decimals, this.decimalSepa, 'General.Currency.Format'));
    }
    return costs;
  };

  /**
   * If user has selected enough discounts the price to pay on the page will be below zero.
   * We set amount to pay to zero in this case.
   * @param costs {baseCost; additionalCost; discountCosts; discountMap; sumCost}
   */
  this.handleAmountBelowZero = function(costs) {
    $('#dynSumTot').html(fNum(0, this.decimals, this.decimalSepa, 'General.Currency.Format'));
  };

  this.updateSelected = function() {
    for (var i = 0, l = this.items.length; i < l; i++) {
      var item = this.items[i];
      item.select(item.isSelected());
    }
  };

  this.addCardType = function() {

  };

  this.add = function(cartItem) {
    this.items.push(cartItem);
    this.itemMap['' + cartItem.id] = cartItem;
  };

  this.addDiscountItem = function(discountItem) {
    this.discountItems.push(discountItem);
    this.discountItemMap['' + discountItem.id] = discountItem;
    this.discountItemAssociatedMap['' + discountItem.associatedCartItemId] = discountItem;
  };
  /**
   *
   * @param id discountItemId
   */
  this.getDiscountItem = function(id) {
    return this.discountItemMap['' + id];
  };
  /**
   *
   * @param cartItemId associatedCartItemId
   */
  this.getDiscountItemFromCartItem = function(cartItemId) {
    return this.discountItemAssociatedMap['' + cartItemId];
  };

  this.selectDiscountItem = function(id, selected) {
    var item = this.getDiscountItem(id);
    if (item) item.select(selected);
    var costs = this.updatePrices();
    this.displayDiscountInfoAndCost(costs, item.prodCartId, item.name);
  };

  this.getItem = function(id) {
    return this.itemMap['' + id];
  };

  this.hasProduct = function(id) {
    return this.itemMap['' + id];
  };

  this.hasProductGroup = function(groupId) {
    return this.itemsInGrp(groupId).length > 0;
  };

  this.getForGroup = function(groupId) {
    var itemsInGrp = [];
    for (var i = 0, l = this.items.length; i < l; i++) {
      var item = this.items[i];
      if (item.groupId == groupId) {
        itemsInGrp[itemsInGrp.length] = item;
      }
    }
    return itemsInGrp;
  };
  this.getForExclusiveGroup = function(groupId) {
    var itemsInGrp = [];
    for (var i = 0, l = this.items.length; i < l; i++) {
      var item = this.items[i];
      if (item.groupId == groupId && item.isGroupExclusive()) {
        itemsInGrp[itemsInGrp.length] = item;
      }
    }
    return itemsInGrp;
  };

  this.getBaseCost = function() {
    var cost = new Cost(this.baseCost.net, this.baseCost.tax, this.baseCost.vat);
    for (var i = 0, l = this.items.length; i < l; i++) {
      var item = this.items[i];
      cost.d(item.name + '/' + item.cost.getTotal() + ' - ' + item.isSelected() + ' - ' + cost.getTotal());
      if (item.isSelected()) {
        cost.add(item.cost);
        cost.d('   - ADDED   ' + item.cost.getTotal() + ' => ' + cost.getTotal());
      }
    }
    return cost;
  };
  /**
   * @return object-literal object-literal with named properties as: {baseCost; additionalCost; discountCosts; discountMap; sumCost}
   * where sumCost is the final price when all of the previous costs have been added together - can be negative.
   */
  this.getTotalCost = function() {
    var sumCost = this.getBaseCost();
    sumCost.add(this.additionalCost);

    var discountMap = this._getCalculatedDiscountMap(), discountCosts = new Cost(0, 0, 0);
    for (var k in discountMap) {
      if (discountMap.hasOwnProperty(k)) {
        discountCosts.add(discountMap[k]);
        sumCost.add(discountMap[k]);
      }
    }

    sumCost.d('   - ADDED ADDITIONAL COST  ' + this.additionalCost.getTotal() + '\n SUM COST ' + sumCost.getTotal() + '\n DISCOUNT ' + discountCosts.getTotal());
    return {
      'baseCost':this.getBaseCost(),
      'additionalCost':this.additionalCost,
      'discountCosts':discountCosts,
      'discountMap':discountMap,
      'sumCost':sumCost
    };
  };
  /**
   * "Private method".
   * Return structure which associates reservationCartItems to calculated applicable discount values.
   * Checks which discount items are selected and adds discounts up to max value (the specific resCartItem's value).
   */
  this._getCalculatedDiscountMap = function() {
    var discountMap = {}, l = this.discountItems.length, i;
    for (i = 0; i < l; i++) {
      // init here so we don't have to do checks later on.
      discountMap['' + this.discountItems[i].associatedCartItemId] = new Cost(0, 0, 0);
    }
    for (i = 0; i < l; i++) {
      var item = this.discountItems[i];
      if (item.isSelected()) {
        var index = item.associatedCartItemId;
        var resItemAccumulatedDiscount = discountMap[index];
        var discountCost = item.getDiscountCost();
        resItemAccumulatedDiscount.add(discountCost);

        if (resItemAccumulatedDiscount.negatedTotal() > item.associatedCartItemCost.getTotal()) {
          discountMap[index] = item.associatedCartItemCost.negate();
          this._handleDiscountOverflow(item, true);
        } else {
          this._handleDiscountOverflow(item, false);
          discountMap[index] = resItemAccumulatedDiscount;
        }
      }
    }
    return discountMap;
  };

  /**
   * Change what is selectable for a specific discountItemGroup so that users cannot (in theory) "throw away" discounts.
   * @param discountItem item which causes zero value for product
   * @param overflowing enable or disable the input element(s), also value set for "overflowing" on associated items
   */
  this._handleDiscountOverflow = function(discountItem, overflowing) {
    var cartItemId = discountItem.associatedCartItemId;
    var prefix = "discountItem_", inputRowPrefix = "discRow_", discountItems = this.discountItems;
    for (var i = 0, l = discountItems.length; i < l; i++) {
      var item = discountItems[i];
      if (item.associatedCartItemId == cartItemId) {
        var input = document.getElementById(prefix + item.id);
        if (input) { // when payemtent page
          if (!input.checked) {
            input.disabled = overflowing;
          }
          var row = $("#" + inputRowPrefix + item.id);
          input.disabled ? row.removeClass("pointer") : row.addClass("pointer");
          input.value = input.checked ? "true" : "false";
          item.setOverflowing(overflowing);
        }
      }
    }
  };

  /**
   * Should be run on page reload to fix possible browser "quirks" remembering the state of check-boxes.
   */
  this._fixInitOverflowSimple = function() {
    var prefix = "discountItem_", discountItems = this.discountItems;
    for (var i = 0, l = discountItems.length; i < l; i++) {
      var item = discountItems[i];
      var input = document.getElementById(prefix + item.id);
      input.disabled = false;
    }
  };

  /**
   * Should be run on page reload to fix possible browser "quirks" remembering the state of check-boxes.
   * This version should be chosen over _fixInitOverflowSimple if a discount has been selected or updatePrices has been run,
   * as it makes checks to not make errors. (if _fixInitOverflowSimple works in all scenarios we can remove this function.)
   */
  this._fixInitOverflow = function() {
    var i, prefix = "discountItem_", groups = {}, discountItems = this.discountItems, item, k, l = discountItems.length;
    for (i = 0; i < l; i++) {
      item = discountItems[i];
      var input = document.getElementById(prefix + item.id);
      if (input.disabled) {
        groups["" + item.associatedCartItemId] = 'x';
      }
    }
    for (i in groups) { // for each product which has discounts.
      if (groups.hasOwnProperty(i)) {
        var enable = true;
        var groupItems = [];
        for (k = 0; k < l; k++) {
          item = discountItems[k];
          groupItems.push(item);
          if (item.isOverflowing()) {
            enable = false;
            break;
          }
        }
        if (enable) {
          for (k = 0; k < groupItems.length; k++) {
            item = groupItems[k];
            document.getElementById(prefix + item.id).disabled = false;
          }
        }
      }
    }
  };

  this.select = function(id, selected) {
    this.selectProductUpSell(id, selected);
    this.selectProductServicePackage(id, selected);
    this.selectCheckTarget(id, selected, null, false);
  };

  this.selectProductUpSell = function(id, selected) {
    updateUpSellBookSetUi(id, selected);
  };

  this.selectProductServicePackage = function(id, selected) {
    var textfieldDiv = $('#sp_' + id);
    if (isTrue(selected)) {
      textfieldDiv.slideDown('fast');
    } else {
      textfieldDiv.slideUp('fast');
    }
  };

  this.selectCheckTarget = function(id, selected, eventTarget, paymentTypeIsCard) {
    var item = this.getItem(id);

    selected = isTrue(selected);
    if (selected) {
      var itemsInGrp = this.getForExclusiveGroup(item.groupId);
      for (var i = 0, l = itemsInGrp.length; i < l; i++) {
        var tmpItem = itemsInGrp[i];
        tmpItem.select(false);
      }
    }
    item.select(selected);

    this.setSelectedPaymentItem(item);
    this._checkPaymentType(paymentTypeIsCard, id);
    this.updatePrices();

    if (eventTarget) eventTarget.checked = true;
  };

  /**
   * @param paymentTypeIsCard
   * @param id
   */
  this.initCardPayment = function(paymentTypeIsCard, id) {
    if (paymentTypeIsCard) {
      this._checkPaymentType(paymentTypeIsCard, id);
      $('#prodRowInfo_' + id).hide(); // Initially hide credit card information row.
    }
  };

  /**
   * @param id e.g. String code of the card type.
   */
  this._getCardTypeItem = function(id) {
    for (var i = 0, l = this.items.length; i < l; i++) {
      var item = this.items[i];
      if (item.id == id) {
        return this.items[i];
      }
    }
    return undefined;
  };

  /**
   * Include the card type in the cart item list, to be included in the total sum.
   *
   * @param id String, code of the card type.
   * @param selected boolean, set it as selected.
   */
  this.selectCardType = function(id, selected) {
    var item = this._getCardTypeItem(id);
    if (item) {
      if (this.selectedCardType == undefined) {
        this.selectedCardType = item;
      } else {
        this.selectedCardType.select(false);
      }
      item.select(selected);
      this.selectedCardType = item;
      this.selectedCardTypePrefix = (item && item.id == 'AX') ? "ax" : "xxx";
      this.updatePrices();
      this.displayCardPaymentInfoAndCost(item);
      this.showCreditCardInputElements();
    }
  };

  this.showCreditCardInputElements = function() {
    var cardType = this.selectedCardType.id, that = this, duration = 300;

    if (cardType == 'AX') {
      $("#defaultCCs").hide(0);
      $("#americanExpressCC").fadeIn(duration);
    } else {
      $("#americanExpressCC").hide(0);
      $("#defaultCCs").fadeIn(duration);
    }

    $(".cardNoPartsInput").bind({
                                  keypress: function(event) {
                                    that.nextOrPrev(event, parseInt($(this).attr("id").split("_")[2]));
                                  },
                                  keydown : function(event) {
                                    that.nextOrPrev(event, parseInt($(this).attr("id").split("_")[2]));
                                  },
                                  keyup : function(event) {
                                    that.nextOrPrev(event, parseInt($(this).attr("id").split("_")[2]));
                                  },
                                  blur : function() {
                                    that.updateCardNumber();
                                  }
                                });

    /**
     * Updates the card number string, that is, the complete card number.
     *
     * e.keyCode == 8 is "BACKSPACE"
     * e.keyCode == 37 is "LEFT_ARROW"
     *
     * @param e is a keyboard event.
     * @param index of type int, of the current input field.
     */
    this.nextOrPrev = function(e, index) {
      if (!e) e = window.event;

      this.updateCardNumber();

      var inputPrefix = this.selectedCardTypePrefix + '_cardNumber_';
      var current = getObj(inputPrefix + index);
      var next = getObj(inputPrefix + (index + 1));
      var prev = getObj(inputPrefix + (index - 1));

      if (prev && getPosition(current) == 0 && (e.keyCode == 8 || e.keyCode == 37)) {
        prev.focus();
        setPosition(prev, prev.value.length);
      } else {
        if (next && getPosition(current) == current.getAttribute("maxlength") && e.keyCode != 8 && e.keyCode != 37) {
          next.focus();
        }
      }
    };

    /**
     * Concatenates the card separated card numbers within the HTML input elements.
     */
    this.updateCardNumber = function() {
      var value = "", that = this;
      $(".cardNoPartsInput").each(function() {
        var e = $(this);
        if (e.attr("id").split("_")[0] == that.selectedCardTypePrefix) value += e.val();
      });
      $("#cardNumber").val(value);
    };

  };

  /**
   * When card payment is selected, and a card type was previously selected, then include the price in the total sum.
   */
  this._cardTypeIsSelected = function() {
    if (this.selectedCardType != undefined) {
      this.selectedCardType.select(true);
    } else {
      if (this.paymentTypeCardId) {
        // Hide credit card information row, since no card type is selected.
        $("#prodRowInfo_" + this.paymentTypeCardId).hide();
      }
    }
  };

  this._checkPaymentType = function(paymentTypeIsCard, id) {
    if (paymentTypeIsCard) {
      this.paymentTypeCardId = id;
      this._cardTypeIsSelected();
    } else {
      this.paymentTypeCardId = undefined;
    }
  };

  /**
   * @param item CreditCard Item
   */
  this.displayCardPaymentInfoAndCost = function(item) {
    var e = this.getItem(this.paymentTypeCardId);
    if (e) e.select(true);
    // update price in the summary component
    $('#prodRowAmountInfo_' + this.paymentTypeCardId).html(fNum(item.cost.getTotal(), this.decimals, this.decimalSepa, 'General.Currency.Format'));
    $('#prodRowDescriptionInfo_' + this.paymentTypeCardId).html(item.name);
  };

  /**
   * Discount Item
   * Finds out how we should display selected discounts in its own summary as well as the general cart summary.
   * @param costs {baseCost; additionalCost; discountCosts; discountMap; sumCost}
   * @param prodCartId the id of the row where we will display the total for all the selected bonuses
   * @param name the 'heading" for the sum of the selected discounts.
   */
  this.displayDiscountInfoAndCost = function(costs, prodCartId, name) {
    var cost = new Cost(0, 0, 0), displayRow = false;
    for (var i = 0, l = this.discountItems.length; i < l; i++) {
      var item = this.discountItems[i];
      cost.d(item.name + '/' + item.discountCost.getTotal() + ' - ' + item.isSelected() + ' - ' + cost.getTotal());
      if (item.isSelected()) {
        cost.add(item.discountCost);
        cost.d('   - ADDED DISCOUNT  ' + item.discountCost.getTotal() + ' => ' + cost.getTotal());
        displayRow = true;
      }
    }
    // display sum of all discounts in summary component
    if (displayRow) {
      $('#prodRowInfo_' + prodCartId).show();
      $('#prodRowAmountInfo_' + prodCartId).html(fNum(costs.discountCosts.getTotal(), this.decimals, this.decimalSepa, 'General.Currency.Format'));
      $('#prodRowDescriptionInfo_' + prodCartId).html(name);
    } else {
      $('#prodRowInfo_' + prodCartId).hide();
    }

    // update discount selection component prices
    this.updateDisplayedDiscounts(costs.discountMap);
  };

  this.updateDisplayedDiscounts = function(discountMap) {
    for (var cartItemId in discountMap) {
      if (discountMap.hasOwnProperty(cartItemId)) {
        // "calculate" beforeDiscountPrice, discountPrice, discountedTotalPrice.
        var cartItemCost = this.getDiscountItemFromCartItem(cartItemId).getAssociatedCartItemCost();
        var discountCost = discountMap[cartItemId];
        var tmp = new Cost(0, 0, 0);
        var discountedTotal = tmp.add(cartItemCost, true).add(discountCost, true);
        // display the prices
        $("#discountBefore_" + cartItemId).html(fNum(cartItemCost.getTotal(), this.decimals, this.decimalSepa, 'General.Currency.Format'));
        $("#dizcount_" + cartItemId).html((discountCost.getTotal() != 0 ? "-&nbsp;" : "") + fNum(discountCost.negate().getTotal(), this.decimals, this.decimalSepa, 'General.Currency.Format'));
        $("#discountedTotal_" + cartItemId).html(fNum(discountedTotal.getTotal(), this.decimals, this.decimalSepa, 'General.Currency.Format'));
      }
    }
  };

  this.ensureDiscountSelection = function() {
    this._fixInitOverflowSimple();
    var item, costs;
    for (var i = 0, l = this.discountItems.length; i < l; i++) {
      item = this.discountItems[i];
      item.select(item.isSelected());
    }
    costs = this.updatePrices();
    // item has two values which are the same for all items: prodcartid and name.
    this.displayDiscountInfoAndCost(costs, item.prodCartId, item.name);
  };

};

function updateUpSellBookSetUi(itemTypeId, selected) {
  var upsellBook = $('#upsell_book_' + itemTypeId);
  var upsellAlreadyBooked = $('#upsell_already_booked_' + itemTypeId);
  if (isTrue(selected)) {
    upsellAlreadyBooked.show();
    upsellBook.hide();
  } else {
    upsellBook.show();
    upsellAlreadyBooked.hide();
  }
}

function upSellClicked(itemTypeId, selected, noSelectionComponentUrl) {
  if (getExtraProductSelectionField(itemTypeId)) {
    cart.select(itemTypeId, selected);
  } else {
    setCookie('selectExtraProduct', itemTypeId);
    window.location = noSelectionComponentUrl;
  }
}

function getExtraProductSelectionField(itemTypeId) {
  return getObj("cartitem_" + itemTypeId + "_true");
}

function upSellIsInPaymentStep(itemTypeId) {
  return getExtraProductSelectionField(itemTypeId);
}

