<?php
App::import('Model', 'CakeSession');
class ShoppingCartBase extends Model {

	public $useTable = false;

	public $orderInstance = null;
	public $itemInstance = null;

	public function __construct() {
		$this->orderInstance = ClassRegistry::init('Order');
		$this->itemInstance = ClassRegistry::init('CartItem');
	}

# Add item to cart.
	public function add($data) {
		# Validate fields.
		$validationStatus = $this->validateAddFields($data);

		# If validation is not true, then it is an array with validation errors.
		if($validationStatus !== true) {
			return $validationStatus;
		}

		# Create variables from data
		extract($data);

		# If there is no extras provided in data, make it be empty array
		$extras = array();
		if(isset($data['extras'])) {
			$extras = $data['extras'];
		}

		# Round count
		if($count < 0) return false;
		$count = round($count);

		try {
			$data = array('model' => $model, 'foreign_key' => $foreign_key, 'name' => $name, 'price' => $price, 'path' => $path, 'count' => $count, 'extra_fields' => $extras);
			# If there is alreadu order in session, update it.
			if(CakeSession::check('order')) {
				$sessionData = CakeSession::read('order');
				$preventSave = false;

				# Go thorugh all carts in session and if there is one with same model, fk and extras, just summ counts.
				foreach($sessionData['cart'] as $key => $value) {
					if($value['model'] == $data['model'] && $value['foreign_key'] == $data['foreign_key'] && $value['extra_fields'] == $data['extra_fields']) {
						$sessionData['cart'][$key]['count'] = $value['count'] + $data['count'];
						$preventSave = true;
						break;
					}
				}

				# If there is no same cart item, save new.
				if(!$preventSave) {
					$sessionData['cart'][] = $data;
				}
				# Write all to session
				CakeSession::write('order', $sessionData);
			} else {
				# If there is no order in session, save only this item.
				CakeSession::write('order', array('cart'=> array($data)));
			}

			return true;

		} catch (Exception $e) {
			return false;
		}
	}

# Remove item from cart.
	public function delete($data) {
		try {
			# Validate fields.
			$validationStatus = $this->validateDeleteFields($data);

			# If validation is not true, then it is an array with validation errors.
			if($validationStatus !== true) {
				return $validationStatus;
			}

			# Create variables from data
			extract($data);

			# If there is no extras provided in data, make it be empty array
			$extras = array();
			if(isset($data['extras'])) {
				$extras = $data['extras'];
			}

			$data = array('model' => $model, 'foreign_key' => $foreign_key, 'extra_fields' => $extras);
			if(CakeSession::check('order')) {
				$sessionData = CakeSession::read('order');
				$preventSave = false;
				# Remove item only if all params are same.
				foreach($sessionData['cart'] as $key => $value) {
					if($value['model'] == $data['model'] && $value['foreign_key'] == $data['foreign_key'] && (empty($data['extra_fields']) || $value['extra_fields'] == $data['extra_fields'])) {
						unset($sessionData['cart'][$key]);
						break;
					}
				}
				CakeSession::write('order', $sessionData);
				return true;
			}

		} catch (Exception $e) {
			return false;
		}
	}

# Check item in cart.
	public function check($data) {
		try {

			# Validate fields.
			$validationStatus = $this->validateCheckFields($data);

			# If validation is not true, then it is an array with validation errors.
			if($validationStatus !== true) {
				return $validationStatus;
			}

			# Create variables from data
			extract($data);

			$data = array('model' => $model, 'foreign_key' => $foreign_key);

			if(CakeSession::check('order')) {
				$sessionData = CakeSession::read('order');
				$searchResults = array();

				foreach($sessionData['cart'] as $key => $value) {
					if($value['model'] == $data['model'] && $value['foreign_key'] == $data['foreign_key']) {
						$searchResults[] = array('count' => $value['count'], 'extras' => $value['extra_fields']);
					}
				}
				# Return results.
				return $searchResults;
			}

		} catch (Exception $e) {
			return false;
		}
	}

# Edit item in cart.
	public function edit($data) {
		try {

			# Validate fields.
			$validationStatus = $this->validateEditFields($data);

			# If validation is not true, then it is an array with validation errors.
			if($validationStatus !== true) {
				return $validationStatus;
			}

			# Create variables from data
			extract($data);

			$data = array('model' => $model, 'foreign_key' => $foreign_key, 'extra_fields' => $extras);

			# Edit cart item with all same parameters, except count.
			if(CakeSession::check('order')) {
				$sessionData = CakeSession::read('order');
				$preventSave = false;

				foreach($sessionData['cart'] as $key => $value) {
					if($value['model'] == $data['model'] && $value['foreign_key'] == $data['foreign_key'] && (empty($data['extra_fields']) || $value['extra_fields'] == $data['extra_fields'])) {
						$sessionData['cart'][$key]['count'] = $count;
						break;
					}
				}
				CakeSession::write('order', $sessionData);
				return true;
			}

		} catch (Exception $e) {
			return false;
		}
	}

# Add additional data to cart contents.
	public function setHeader($data = array()) {
		if(!CakeSession::check('order')) return false;

		try {
			$sessionData = CakeSession::read('order');
			# If there is user in session, update its data.
			if(isset($sessionData['user'])) {
				foreach($data as $key => $value) {
					if($key == 'id') continue;
					$sessionData['user'][$key] = $value;
				}
				CakeSession::write('order', $sessionData);
				return true;
			# If there is no user in session, create new and write it to session.
			} else {
				if(!empty($sessionData['cart'])) {
					$allData = array('cart' => $sessionData['cart'], 'user' => $data);
					CakeSession::write('order', $allData);
					return true;
				}
			}
		} catch (Exception $e) {
			debug($e->getMessage());
			return false;
		}
	}

# Save order.
	public function commit() {
		# Get order data.
		$orderData = CakeSession::read('order');
		$this->orderInstance->create();

		# If there is no items in cart, don't save the order.
		if(empty($orderData['cart'])) {
			return false;
		}

		# Attach order to loggedin user.
		if(CakeSession::check('user.User.id')) {
			$orderData['user']['user_id'] = CakeSession::read('user.User.id');
		} else {
			return false;
		}

		# If order successfuly saved, delete all order items from database and insert new.
		if($orderData['user'] = $this->orderInstance->save($orderData['user'])) {
			# Delete all cart items in database associated with this order.
			$this->itemInstance->deleteAll(array('CartItem.order_id' => $this->orderInstance->id));

			# Populate database with cart items from session.
			$orderData['user']['id'] = $this->orderInstance->id;
			foreach($orderData['cart'] as $index => $cartItem) {
				$this->itemInstance->create();
				# Set order id.
				$cartItem['order_id'] = $this->orderInstance->id;
				$cartItem = $cartItem + $cartItem['extra_fields'];
				unset($cartItem['extra_fields']);
				# Save cart item.
				$this->itemInstance->save($cartItem);
				$orderData['cart'][$index]['id'] = $this->itemInstance->id;
			}
			# Write new order data in session, to preserve ids in case of change.
			CakeSession::write('order', $orderData);
			return true;
		} else {
			return false;
		}

	}



/* Validate input for cart item adding */
		public function validateAddFields($data) {
			# Check if all necesary fields are there
			foreach(array('model', 'foreign_key', 'count') as $field) {
				if(!isset($data[$field])) {
					return array('field' => $field, 'message' => __('Ovo polje je obavezno'));
				}
			}

			# Check if model is not empty
			if(strlen(trim($data['model'])) < 1) {
				return array('field' => 'model', 'message' => __('Ime modela mora imati bar jedan karakter'));
			}

			# Check if count is numeric
			if(!is_numeric($data['count'])) {
				return array('field' => 'count', 'message' => __('Količina mora biti broj'));
			}

			return true;
		}

/* Validate input for cart item deletion */
		public function validateDeleteFields($data) {
			# Check if all necesary fields are there
			foreach(array('model', 'foreign_key') as $field) {
				if(!isset($data[$field])) {
					return array('field' => $field, 'message' => __('Ovo polje je obavezno'));
				}
			}

			if(strlen($data['model']) < 1) {
				return array('field' => 'model', 'message' => __('Ime modela mora imati bar jedan karakter'));
			}

			if(!is_numeric($data['foreign_key'])) {
				return array('field' => 'count', 'message' => __('FK mora biti broj'));
			}

			return true;
		}


/* Validate input for cart item check */
		public function validateCheckFields($data) {
			# Check if all necesary fields are there
			foreach(array('model', 'foreign_key') as $field) {
				if(!isset($data[$field])) {
					return array('field' => $field, 'message' => __('Ovo polje je obavezno'));
				}
			}

			# Check if model is not empty
			if(strlen(trim($data['model'])) < 1) {
				return array('field' => 'model', 'message' => __('Ime modela mora imati bar jedan karakter'));
			}

			# Check if count is numeric
			if(!is_numeric($data['foreign_key'])) {
				return array('field' => 'count', 'message' => __('FK mora biti broj'));
			}

			return true;
		}


/* Validate input for cart item edit */
		public function validateEditFields($data) {
			# Check if all necesary fields are there
			foreach(array('model', 'foreign_key') as $field) {
				if(!isset($data[$field])) {
					return array('field' => $field, 'message' => __('Ovo polje je obavezno'));
				}
			}

			# Check if model is not empty
			if(strlen(trim($data['model'])) < 1) {
				return array('field' => 'model', 'message' => __('Ime modela mora imati bar jedan karakter'));
			}

			# Check if count is numeric
			if(!is_numeric($data['foreign_key'])) {
				return array('field' => 'count', 'message' => __('FK mora biti broj'));
			}

			return true;
		}


}
?>
