<?php
namespace Hautelook;

class 
Cart
{
    private 
$products = array();
    private 
$subtotal 0;
    private 
$totalWeight 0;
    private 
$shipping 0;
    private 
$couponPercent 0;
    private 
$total 0;

    private 
$shippingCeiling 100;
    private 
$heavyWeight 10;
    private 
$heavyCost 20;
    private 
$flatRate 5;

    private 
$isSubtotalStale false;
    
// no $isShippingStale since it's only updated with total
    
private $isTotalStale false;

    public function 
subtotal()
    {
        if (
$isSubtotalStale) {
            
updateSubtotal();
        }
        return 
$this->subtotal;
    }

    public function 
total()
    {
        if (
$isSubtotalStale) {
            
updateSubtotal();
        }
        if (
$isTotalStale) {
            
$this->updateShipping();
            
$this->updateTotal();
        }
        return 
$this->total;
    }

    public function 
addProduct($product) {
        if (
$product instanceof Product) {
            
$this->products[] = $product;
            
$isSubtotalStale true;
            
$isTotalStale true;
            return 
true;
        }
        return 
false;
    }

    public function 
getQuantityByName($name) {
        
$quantity 0;
        foreach (
$this->products as $product) {
            if (
$product->getName() == $name) {
                
$quantity++;
            }
        }
        return 
$quantity;
    }

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

    
// Takes an integer and stores it as a percentage
    
public function applyCouponCode($couponPercent) {
        
$this->couponPercent $couponPercent/100;
        
$this->applyCouponToSubtotal();
        
$isSubtotalStale true;
        
$isTotalStale true;
    }

    private function 
updateSubtotal() {
        
$subtotal 0;
        foreach (
$this->products as $product) {
            
$subtotal += $product->getPrice();
        }
        
$this->subtotal $subtotal;
        
$this->applyCouponToSubtotal();
        
$isSubtotalStale false;
        
$isTotalStale true;
    }

    private function 
applyCouponToSubtotal() {
        if (
$this->couponPercent) {
            
$this->subtotal -= $this->subtotal $this->couponPercent;
            
$isTotalStale true;
        }
    }

    private function 
updateShipping() {
        
$shipping 0;
        
$totalWeight 0;
        
$numberHeavy 0;
        foreach (
$this->products as $product) {
            
$weight $product->getWeight();
            
$totalWeight += $weight;
            if (
$weight >= $this->heavyWeight) {
                
$numberHeavy++;
                
$shipping += $this->heavyCost;
            }
        }

        if (
$numberHeavy != count($this->products)) {
            if (
$this->subtotal $this->shippingCeiling) {
                
$shipping += $this->flatRate;
            }
        }
        
$this->shipping $shipping;
        
$this->totalWeight $totalWeight;
        
$isTotalStale true;
    }

    private function 
updateTotal() {
        
$this->total $this->subtotal $this->shipping;
        
$isTotalStale false;
    }