<?php

class cart
{
    public $data     = array();

    public $products = array();

    public $subtotal = 0;

    public $taxes    = array();

    public $total    = 0;

    public $stock    = TRUE;

    public $shipping = FALSE;

    public $total_weight = 0;

    public function __construct(&$locator)
    {
        $this->locator =& $locator;

        $this->reconstruction();
    }

    public function reconstruction()
    {
        $this->products = array();

        $this->subtotal = 0;

        $this->taxes    = array();

        $this->total    = 0;

        $this->stock    = TRUE;

        $this->shipping = FALSE;

        $this->total_weight = 0;

        date_default_timezone_set('Asia/Hong_Kong');

        $this->config   =& $this->locator->get('config');

        $this->database =& $this->locator->get('database');

        $this->language =& $this->locator->get('language');

        $this->tax      =& $this->locator->get('tax');

        $this->session  =& $this->locator->get('session');

        $this->weight   =& $this->locator->get('weight');

        $this->image    =& $this->locator->get('image');

        if ($this->session->has('cart')) {
              $this->data = $this->session->get('cart');
        }
//   	var_dump($this->data);
        foreach ($this->data as $key => $value) {

              $array  = explode(':', $key);
              
              if(!is_numeric($array[0])){
              	unset($this->data[$key]);
              	$this->session->set('cart', $this->data);
             	continue;
             }

              $product_id = $array[0];            

              $quantity   = $value;

              $options = array();

              if (count($array)>1 && !empty($array[1])) {
                $options = explode('.', $array[1]);
              }

              $product = $this->database->getRow("select p.*, pd.name, i.filename from product p left join product_description pd on (p.product_id = pd.product_id) left join image i on (p.image_id = i.image_id) where p.product_id = $product_id and p.status = 1");

            if ($product) {

                  $option_price = 0;

                  $option_data = array();

                  foreach ($options as $product_to_option_id) {

                    $option = $this->database->getRow("select o.name as name, ov.name as `value`, p2o.price, p2o.prefix from product_to_option p2o left join `option` o on p2o.option_id = o.option_id left join option_value ov on p2o.option_value_id = ov.option_value_id where p2o.product_to_option_id = $product_to_option_id and product_id = $product_id");

                    if ($option['prefix'] == '+') {

                          $option_price = $option_price + $option['price'];

                    } elseif ($option['prefix'] == '-') {

                          $option_price = $option_price - $option['price'];
                    }

                    $option_data[] = array(

                          'product_to_option_id' => $product_to_option_id,

                          'name'                 => $option['name'],

                          'value'                => $option['value'],

                          'prefix'               => $option['prefix'],

                          'price'                => $option['price']

                    );

                  }

                $discount_rows =$this->database->getRows("select * from discount_setting order by sort asc");
                $discount=0; $start_unit_set=array();$end_unit_set=array();$discount_set=array();
                foreach ($discount_rows as $f_discount) {
                    $start_unit_set[]=$f_discount['start_unit'];
                    $end_unit_set[]=$f_discount['end_unit'];
                    $discount_set[]=$f_discount['discount'];
                    if ($quantity>=$f_discount['start_unit']&&$quantity<=$f_discount['end_unit']) {
                         $discount = $f_discount['discount'];
                    }
                }
                if ($quantity<min($start_unit_set)) { $discount = 1.0; }
                if ($quantity>max($end_unit_set)) { $discount = min($discount_set); }

                  $this->products[$key] = array(

                    'product_key'     => $key,

                    'product_id'      => $product['product_id'],

                    'thumb'           => $this->image->resize($product['filename'], 125, 125),

                    'name'            => $product['name'],

                    'shipping'        => $product['shipping'],

                    'image'           => $product['filename'],

                    'option'          => $option_data,

                    'quantity'        => $quantity,

                    'stock'        => $product['quantity'],

                    'price'           => $product['price'] + $option_price,

                    'discount_price'  => ($product['price'] + $option_price)*$discount,

                    'total'           => ($product['price'] + $option_price)*$discount*$quantity,

                    'tax_class_id'    => $product['tax_class_id'],

                    'weight'          => $product['weight'],

                    'weight_class_id' => $product['weight_class_id']

                  );
                $this->total_weight += $product['weight']*$quantity;
                $this->subtotal += $this->tax->calculate((($product['price'] + $option_price)*$discount) * $quantity, $product['tax_class_id']);

                if (!isset($this->taxes[$product['tax_class_id']])) {

                    $this->taxes[$product['tax_class_id']] = ((($product['price'] + $option_price)*$discount) * $quantity) * $this->tax->getRate($product['tax_class_id']);

                } else {
                    $this->taxes[$product['tax_class_id']] += ((($product['price'] + $option_price)*$discount) * $quantity) * $this->tax->getRate($product['tax_class_id']);
                }

                $this->total += $this->tax->calculate((($product['price'] + $option_price)*$discount) * $quantity, $product['tax_class_id']);

                if ($quantity > $product['quantity']) {

                    $this->stock = FALSE;
                }

                if ($product['shipping']) {

                    $this->shipping = TRUE;
                }

            } else {

                $this->remove($key);
            }
        }
 //   	print_r($this->products); exit;
    }
    public function add($product_id, $qty = 1, $options = array())
    {
    	if(!is_numeric($product_id)){
    		return false;
    	}
    	
        if (!empty($options)) {
            $key = $product_id . ':' . implode('.', $options);
        } else {
              $key = $product_id;
        }
        if (!isset($this->data[$key])) {

              $this->data[$key] = (int) $qty;

        } else {

              $this->data[$key] += (int) $qty;
        }

        $this->session->set('cart', $this->data);
        $this->reconstruction();  
        return true;    
    }

    public function update($key, $qty)
    {
        if ($qty) {

              $this->data[$key] = $qty;

        } else {

            $this->remove($key);

        }

        $this->session->set('cart', $this->data);
        $this->reconstruction();
    }

    public function remove($key)
    {
        if (isset($this->data[$key])) {

             unset($this->data[$key]);
        }

        $this->session->set('cart', $this->data);
        $this->reconstruction();
    }

    public function restore($product)
    {
        foreach ($product as $key => $value) {

            $this->data[$key] = $value;
        }

        $this->session->set('cart', $this->data);
        $this->reconstruction();
    }

    public function clear()
    {
        $this->data = array();
        $this->session->set('cart', $this->data);
        $this->reconstruction();
    }

    public function getData()
    {
        return $this->data;
    }

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

    public function getWeight()
    {
        $weight_total = 0;

        foreach ($this->products as $product) {

              $weight_total += $this->weight->convert($product['weight'] * $product['quantity'], $product['weight_class_id'], $this->config->get('config_weight_class_id'));

        }

        return $weight_total;

    }

    public function getSubtotal()
    {
//		return round($this->subtotal,2);
        return number_format($this->subtotal, 2, '.', '');
    }

    public function getTaxes()
    {
        return $this->taxes;

    }

    public function getTotal()
    {
        return number_format($this->total, 2, '.', '');

//		return round($this->total,2);
    }

    public function increaseTotal($value)
    {
        $this->total += $value;
    }

    public function decreaseTotal($value)
    {
        $this->total -= $value;
 /*       echo "<script>alert('total=$this->total');window.history.back(-1);</script>";	*/
    }

    public function addTax($tax_class_id, $value)
    {
        if (!isset($this->taxes[$tax_class_id])) {

            $this->taxes[$tax_class_id] = $value;

        } else {
            $this->taxes[$tax_class_id] += $value;
        }
    }

    public function countProducts()
    {
        $product_total = 0;

        foreach ($this->data as $key => $value) {

            $product_total += $value;

        }

        return $product_total;
    }

    public function hasProducts()
    {
        return count($this->data);
    }

    public function hasStock()
    {
        return $this->stock;
    }

    public function hasShipping()
    {
        return $this->shipping;
    }
}
