  function showShopcart(shopcartdata, readonly) {

    // Remove all old lines
    $('.shopitemtr').remove();
    
    effectiveNumberOfItems = 0;
    $.each(shopcartdata.items, function(i, item) {
      if (item.itemCount > 0) {
        effectiveNumberOfItems += item.itemCount;
      } else if (item.itemCount == 0 && item.abonneeonly == 'true') {
        effectiveNumberOfItems += 1;
      }
    });

    if (effectiveNumberOfItems == 0) {
      $("#checkout-form-temp").hide();
      $("#link-continue-checkout").hide();
      $("#checkout-form").hide();
      $("#checkout-form-noitems").show();
      return;
    }

    $('.shoppingcart-sales').remove();
    
    $.each(shopcartdata.items, function(i, item) {
      addShopcartItem(item, readonly, shopcartdata.isMember, shopcartdata.isLoggedIn);
    });

    $('.shopping-items tr.shopitemtr:last').after(addSubTotal(shopcartdata.subTotalPrice, shopcartdata.subTotalPriceDiscount,shopcartdata.isMember));
    $('.shopping-items tr.shopitemtr:last').after(addShippingCost(shopcartdata.shippingCost));
    $('.shopping-items tr.shopitemtr:last').after(addPackagingCost(shopcartdata.packagingCost));
    
    if (shopcartdata.packagingPrice != undefined && shopcartdata.packagingPrice > 0.0) {
      // calculate new total price and total price discount based on packaging cost and format.
      var newprice = parseFloat(shopcartdata.totalPrice.replace(",", "."));
      newprice = newprice + shopcartdata.packagingPrice;
      newprice = newprice.toFixed(2).replace(".", ",");
      
      var newpricedc = parseFloat(shopcartdata.totalPriceDiscount.replace(",", "."));
      newpricedc = newpricedc + shopcartdata.packagingPrice;
      newpricedc = newpricedc.toFixed(2).replace(".", ",");
      
      $('.shopping-items tr.shopitemtr:last').after(addTotal(newprice, newpricedc,shopcartdata.isMember));
    } else {
      $('.shopping-items tr.shopitemtr:last').after(addTotal(shopcartdata.totalPrice,shopcartdata.totalPriceDiscount,shopcartdata.isMember));
    }

    if (shopcartdata.isMember != 'true' && shopcartdata.memberDiscount != '0,00') {
      $('#customer-discount-amount').html('&euro; ' + shopcartdata.memberDiscount);
      $('#codes-discount').show();
    } else {
      $('#codes-discount').hide();
    }

    // Show the shopcart after loading...
    $("#checkout-form-temp").hide();
    $("#checkout-form").show();
  }

  function showShopcartSmall(shopcartdata) {
    // Remove all old lines
    $('.preview .item').remove();
    // Set total number of items
    $('#itemcounttext').html(shopcartdata.totalItemCountText);
    // Set total price
    $('#totalprice').html('&euro; ' + shopcartdata.totalPrice);

    if (shopcartdata.totalItemCount > 0) {
      $(".button-action-small-white-blue").show();
    }
  }

  function addShopcartItemSmall(shopcartItem) {
    $('#shopping-cart .content #shopcartitems').html("<div class=\"item\">" +shopcartItem.description+ " ("+shopcartItem.itemCount+")</div>");
  }

  function addShopcartItem(shopcartItem, readonly, isMember, isLoggedIn) {
    if (shopcartItem.type == 'paydeskoffer' && shopcartItem.itemCount == 0) {
      $('#shoppingcart-sales').after(addSalesItem(shopcartItem, isMember));
    } else {
      var maxItems = shopcartItem.maxItems;
      if (shopcartItem.type == 'paydeskoffer') {
        maxItems = 1;
        if (shopcartItem.messages.length > 0) {
          for (i=0;i<shopcartItem.messages.length;i++) {
            if (shopcartItem.messages[i].code == 'paydeskoffer') {
              maxItems = shopcartItem.messages[i].value;
            }
          }
        }
      }
      
      trclass = "shopitemtr";
      if (shopcartItem.abonneeonly == 'true') {
        if (isLoggedIn == 'true') {      
          if (isMember != 'true') {
            trclass = trclass + " abonnee-only-disabled";
          }
        } else {
          trclass = trclass + " abonnee-only";
        }
      }
      
      $('.shopping-items tr:last').after("<tr class=\""+trclass+"\" id=\""+shopcartItem.identifier+"\">" +
        addImage(-1, -1, 0, shopcartItem.image, shopcartItem.url) +
        addArticleName(shopcartItem.description, shopcartItem.subdescription,shopcartItem.itemPrice,shopcartItem.itemPriceDiscount,isMember,shopcartItem.url, shopcartItem.type, shopcartItem.packagingAllowed, shopcartItem.abonneeonly, shopcartItem.abonneeonlytext, isLoggedIn) +
        addQuantity(shopcartItem.itemCount, maxItems, shopcartItem.identifier, readonly) +
        addDelivery(shopcartItem.deliveryDescription) +
        addSubPrice(shopcartItem.price) +
        addSubPriceDiscount(shopcartItem.priceDiscount) +
        addRemoveItem(shopcartItem.identifier,readonly) +
        "</tr>")
     }
  }
  
  function addSalesItem(shopcartItem, isMember) {
    var strSalesItem = "";
    strSalesItem = strSalesItem + "<div class=\"shoppingcart-sales\">";
    strSalesItem = strSalesItem + "  <div class=\"top\"></div>";
    strSalesItem = strSalesItem + "    <div class=\"content\"><img src=\""+shopcartItem.imagelarge+"\" alt=\""+shopcartItem.description+"\" width=\"100\" height=\"100\" />";
    strSalesItem = strSalesItem + "      "+$('#shoppingcart-sales-header').html();    
          
    strSalesItem = strSalesItem + "      <div class=\"product-title\">"+shopcartItem.description;
    if (shopcartItem.subdescription != '') {
      strSalesItem = strSalesItem + " "+shopcartItem.subdescription;
    }
    
    strSalesItem = strSalesItem + "      <div class=\"product-subtitle\">voor</div> <div class=\"product-price\">&euro; "+shopcartItem.itemPrice+"</div></div>";
    strSalesItem = strSalesItem + "      "+$('#shoppingcart-sales-description').html(); 
    strSalesItem = strSalesItem + "      <div class=\"product-description\">"+shopcartItem.longdescription+"</div><br /><br />";
    strSalesItem = strSalesItem + "      <div class=\"radiocheck-wrap\"><input name=\"shoppingsale\" type=\"checkbox\" value=\"ja\" onclick=\"updateItem('"+shopcartItem.identifier+"', 1);\"/></div>";
    strSalesItem = strSalesItem + "      <div class=\"radiocheck-wrap\">"+$('#shoppingcart-sales-buttontext').html()+"</div>";
    strSalesItem = strSalesItem + "    </div>";
    strSalesItem = strSalesItem + "  <div class=\"bottom\"></div>";
    strSalesItem = strSalesItem + "</div>";

    return strSalesItem;
  }

  function addSubTotal(total, totalDiscount, isMember) {
    var strSubTotal = "";
    strSubTotal = strSubTotal + "<tr class=\"shopitemtr\">";
    strSubTotal = strSubTotal + "<td colspan=\"4\" class=\"td-total-description\">Subtotaal</td>";
    strSubTotal = strSubTotal + "<td class=\"td-total\">&euro; "+total+"</td>";
    strSubTotal = strSubTotal + "<td class=\"td-total-abonnee\">&euro; "+totalDiscount+"</td>";
    strSubTotal = strSubTotal + "<td class=\"td-noremove\">&nbsp;</td>";
    strSubTotal = strSubTotal + "</tr>";

    return strSubTotal
  }

    function addShippingCost(shippingCost) {
    var strShipping = "";
    strShipping = strShipping + "<tr class=\"shopitemtr\">";
    strShipping = strShipping + "<td colspan=\"4\" class=\"td-costs-description\">Verzendkosten</td>";    
    strShipping = strShipping + "<td class=\"td-costs\">&euro; "+shippingCost+"</td>";
    strShipping = strShipping + "<td class=\"td-costs-abonnee\">&euro; "+shippingCost+"</td>";
    strShipping = strShipping + "<td class=\"td-noremove\">&nbsp;</td>";
    strShipping = strShipping + "</tr>";

    return strShipping;
    }
    
    function addPackagingCost(packagingCost) {
      if (typeof packagingCost == 'string') {
        packagingCost = packagingCost.replace(",", ".");
      }
      packagingCost = parseFloat(packagingCost);
      if (isNaN(packagingCost) || packagingCost <= 0.0) {
        $('input[name=enable_packaging]').attr('checked', false);
        return "";
      }
      $('input[name=enable_packaging]').attr('checked', true);
      var formattedPackagingCost = packagingCost.toFixed(2).replace(".", ",");
      var strPackaging = "<tr class=\"shopitemtr packaging\">";
      strPackaging = strPackaging + "<td colspan=\"4\" class=\"td-costs-description\">Cadeauservice</td>";    
      strPackaging = strPackaging + "<td class=\"td-costs\">&euro; " + formattedPackagingCost + "</td>";
      strPackaging = strPackaging + "<td class=\"td-costs-abonnee\">&euro; " + formattedPackagingCost + "</td>";
      strPackaging = strPackaging + "<td class=\"td-noremove\">&nbsp;</td>";
      strPackaging = strPackaging + "</tr>";
      return strPackaging
    }

    function addTotal(total, totalDiscount, isMember) {
    var strTotal = "";
    strTotal = strTotal + "<tr class=\"shopitemtr\">";
    strTotal = strTotal + "<td colspan=\"4\" class=\"td-total-description\">TOTAAL</td>";   
    strTotal = strTotal + "<td class=\"td-grand-total\">&euro; "+total+"</td>";
    strTotal = strTotal + "<td class=\"td-grand-total-abonnee\">&euro; "+totalDiscount+"</td>";
    strTotal = strTotal + "<td class=\"td-noremove\">&nbsp;</td>";
    strTotal = strTotal + "</tr>";

    return strTotal;
    }

  function addImage(width, height, border, url, detailUrl) {
    var strImage = "<td class=\"image\"><a href=\""+detailUrl+"\"><img src=\""+url+"\" border=\""+border+"\" ";
    if (width > 0) {
      strImage = strImage + "width=\""+width+"\" ";
    }
    if (height > 0) {
      strImage = strImage + "height=\""+height+"\" ";
    }
    strImage = strImage + "/></a></td>";
    return strImage;
  }

  function addArticleName(product, productVariant,itemPrice,itemPriceDiscount,isMember,detailUrl, type, packagingAllowed, abonneeonly, abonneeonlytext, isLoggedIn) {
    var strProduct = "<td class=\"item-description\"><a href=\""+detailUrl+"\">"+product+"</a>"+productVariant + "<br/><br/>";
    
    if (itemPrice == itemPriceDiscount) {
      strProduct = strProduct + "<br /><strong>";
      strProduct = strProduct + "Prijs: &euro; " +itemPrice;
      strProduct = strProduct + "</strong>";
      
      if (type == 'paydeskoffer') {
        strProduct = strProduct + " (kassakoopje)";
      }
    } else {
      if (isMember  == 'false') {
        strProduct = strProduct + "<strong>";
      }
      strProduct = strProduct + "Prijs : &euro; " +itemPrice+ "<br/>";
      if (isMember == 'false') {
        strProduct = strProduct + "</strong>";
      }
      
      if (isMember == 'true') {
        strProduct = strProduct + "<strong>";
      }
        strProduct = strProduct + "Prijs Abonnee: &euro; " +itemPriceDiscount;
      if (isMember == 'true') {
        strProduct = strProduct + "</strong>";
      }
      
    }
    
    showpackagingoption = packagingAvailable;
    if (abonneeonly == 'true') {
      if (isLoggedIn == 'true') {      
        if (isMember != 'true') {
          showpackagingoption = false;
          strProduct = strProduct + "<div class=\"warning\">"+abonneeonlytext+"</div>";
        }
      } else {
        strProduct = strProduct + "<div class=\"warning\">"+abonneeonlytext+"</div>";
      }
    }
    
    if (showpackagingoption && packagingAllowed == 'false') {
          strProduct = strProduct + "<div class=\"no-giftwrap\">Met dit product in uw bestelling is een cadeauverpakking helaas niet mogelijk.</div>";
    }
    
    strProduct = strProduct + "</td>";
    return strProduct
  }

  function addQuantity(itemCount, maxItems, identifier, readonly) {
    var strQuantity = "<td class=\"td-deliverable\"><div class=\"field-wrap\">";

    if (!readonly && maxItems > 1 && itemCount > 0) {
    
    
      if (maxItems < 5) {
        strQuantity = strQuantity + "<div class=\"tipwrap\"><span class=\"tooltip\"><span class=\"tiptext\">Van dit product kunt u slecht een gelimiteerd aantal bestellen.</span></span></div>";
      }
            
      strQuantity = strQuantity + "<select name=\"quantity\" id=\"quantity\" onchange=\"updateItem('"+identifier+"', this.value);\">";
      for (i=1 ; i<=maxItems; i++) {
        var selected = "";
        if (itemCount == i) {
          selected = "selected=\"selected\"";
        }
        strQuantity = strQuantity + "<option "+selected+" value=\""+i+"\">"+i+"</option>";
      }
      strQuantity = strQuantity + "</select></div></td>";
    } else if (!readonly && maxItems > 1) {
      strQuantity = strQuantity + "<select name=\"quantity\" id=\"quantity\" disabled=\"disabled\"><option selected=\"selected\">0</option>";      
      strQuantity = strQuantity + "</select></div></td>";
    } else {
      strQuantity = strQuantity + itemCount + "</div></td>";
    }
    return strQuantity;
  }

  function addDelivery(deliverydescription) {
    var strDelivery = "<td class=\"td-deliverable\">"+deliverydescription+"</td>";
    return strDelivery;
  }

  function addSubPriceDiscount(price) {
    var strPriceDiscount = "<td class=\"td-deliverable-abonnee\">&euro; "+price+"</td>";
    return strPriceDiscount;
  }

  function addSubPrice(price) {
    var strPriceDiscount = "<td class=\"td-deliverable\">&euro; "+price+"</td>";
    return strPriceDiscount;
  }

  function addRemoveItem(identifier, readonly) {
    var strRemoveItem = "";
    if (!readonly) {
      var strRemoveItem = "<td class=\"td-remove\"><a href=\"javascript:removeItem('"+identifier+"');\"><span class=\"tooltip\"><span class=\"tiptext\">Verwijderen</span></span></a></td>";
    }
    return strRemoveItem;
  }
  
  /**
   * Update the packaging view.
   */
  function showPackagingOption(update) {
      if (packagingAvailable) {
        if ( update === undefined ) {
          update = true;
        }
        $('#packaging-info').show();

        if (packagingAllowed == 'toomany') {
          $('#packaging-info-notpossible').hide();
          $('#packaging-info-toomanyproducts').show();
          $('#packaging-info-price').hide();
          removePackagingOption(update);
        } else if (packagingAllowed == 'notpossible') {
          $('#packaging-info-notpossible').show();
          $('#packaging-info-toomanyproducts').hide();
          $('#packaging-info-price').hide();
          removePackagingOption(update);
        } else if (packagingAllowed == 'noproducts') {
          $('#packaging-info-notpossible').show();
          $('#packaging-info-toomanyproducts').hide();
          $('#packaging-info-price').hide();
          removePackagingOption(update);
        } else {
          $('#packaging-info-notpossible').hide();
          $('#packaging-info-toomanyproducts').hide();
          $('#packaging-info-price').show();
        }
     }
  }
  
  /**
   * Hides and disables the packaging option. Also sends an AJAX request to the server to remove
   * selected packaging (if any).
   */
  function removePackagingOption(update) {
      if ( update === undefined ) {
        update = true;
      }
      
      var input = $('#packaging-info input');    
      $(input).attr('value', -1);
      $(input).attr('checked', false);
      $(input).hide();
  
      if (update) {
        setPackaging(0);
      }
  }
  
  
  /**
   * iterates through all products in the shopping cart. If one of the products cannot be packaged,
   * hide and disable the packaging option to the user. if all products can be packaged, display
   * the packaging options again.
   * Make sure to call this method from all methods that change something in the shopping cart.
   */
  function updatePackagingAllowed(maximumAllowed, shopcartData, update) {
      var falsecount = 0;
      var itemcount = 0;    
      $.each(shopcartData.items, function(i, item) {
          if (item.packagingAllowed == 'false' && parseInt(item.itemCount) > 0) {
              falsecount++;
          }
          itemcount += parseInt(item.itemCount);
      });
      if (itemcount > maximumAllowed) {
          packagingAllowed = 'toomany';
          showPackagingOption(update);
      } else if (falsecount > 0) {
          packagingAllowed = 'notpossible';
          showPackagingOption(update);
      } else if (itemcount == 0) {
          packagingAllowed = 'noproducts';
          showPackagingOption(update);
      } else {
          packagingAllowed = 'true';
          // re-display packaging options.
          getPackaging();
          showPackagingOption(update);
      }
  }
