<?php

class ShoppingCart {


protected $products = null;
protected $slots = 0;


public function __construct(DataStorage $products) {
$this->products = $products;
}


public function setNumberOfSlots($slots) {
if(is_null($slots) || false === is_int($slots) || $slots <= 0) {
throw new DomainException(sprintf("Invalid product limit specified %s", (string)$slots));
}
$this->slots = $slots;
}


public function getRemainingSlots() {
return $this->slots - $this->countProducts();
}


public function hasRemainingSlots() {
return $this->getRemainingSlots() > 0;
}


public function add(Product $product, $quantity = 1) {
if(isset($this->storage[$product->getId()])) {
$this->products[$product->getId()]['quantity'] += $quantity;
}
else {
if(false === $this->hasRemainingSlots()) {
throw new DomainException("No more items can be added to the shopping cart");
}
$this->products[$product->getId()] = array(
'product' => $product,
'quantity' => $quantity
);
}
}


public function remove(Product $product) {
if(false === isset($this->products[$product->getId()])) {
throw new DomainException(sprintf("Product with id %d is not in the shopping cart", $product->getId()));
}

unset($this->products[$product->getId()]);
}


public function removeAllProducts() {
$this->products->removeAll();
}

public function countProducts() {
return count($this->products);
}


public function getProductsAndQuantities() {
return $this->products;
}


public function getTotal() {
$sum = 0;
foreach($this->products as $product) {
$sum += $product['product']->getPrice() * $product['quantity'];
}

return $sum;
}
}