/*
CamjOM (Camjax Order Management)
Current Version: 2.5 (17/05/2010)
Release Notes: Added extra order-related functionality
Dependencies: Camjax 2.82+, json2

Previous Releases:
	v2.0, 26/03/2010 <redeveloped to work with json>
	v1.0, 03/02/2010 (known as Ajax Order Management) <Not backward compatible>


The CamjOM JavaScript library may be used by BHC e-commerce applications
to change aspects of an order without leaving the page, and retrieve appropriate 
information in return after order totals etc. are recalculated as the result of changes.

*/

if(!camjaxController || camjaxController == 'undefined')
{
	alert("Warning: Camjax Controller has not been initialised. CamjOM library will not function.");
}

function CamjOM()
{
	this.cartActionParameter = 'cartAction';
	this.enableDebug = false;
	this.lastChangeTimes = new Array();
	this.changeDelay = 0.5;
	this.shoppingCartActionUrl = '/shop/ajaxShoppingCart.do';

	//System Functions
	this.debug = debug;
	this.submitRequest = submitRequest;
	this.parseJSONResponse = parseJSONResponse;
	this.getMatchingValueIndexInArray = getMatchingValueIndexInArray;
	
	//Add To Cart functions
	this.addToCart = addToCart;
	this.addToCartReturn = addToCartReturn;
	
	//Remove order line function
	this.removeFromCart = removeFromCart;
	this.removeFromCartReturn = removeFromCartReturn;
	
	//Clear cart functions
	this.clearAllFromCart = clearAllFromCart;
	this.clearAllFromCartReturn = clearAllFromCartReturn;
	
	//Change Order Line Quantity Functions
	this.changeOrderLineQuantity = changeOrderLineQuantity;
	this.checkChangeOrderLineQuantity = checkChangeOrderLineQuantity;
	this.changeOrderLineQuantityReturn = changeOrderLineQuantityReturn;
	
	//User configurable update functions
	this.updateFunction_changeOrderLineQuantity = null;
	this.updateFunction_addToCart = null;	
	this.updateFunction_removeFromCart = null;
	this.updateFunction_clearAllFromCart = null;
	
	/****************************
	* CamjOM System Functions
	*****************************/
	
	function debug(text)
	{
		if(this.enableDebug)
		{
			camjaxController.log("CamjOM Debug: " + text);
		}
	}
	
	function submitRequest(action, parameters, camjOMReturnFunction, optionalReturnFunctionParameters)
	{
		if(parameters == null)
		{
			parameters = this.cartActionParameter + '=' + action;
		}
		else
		{
			parameters = parameters + '&' + this.cartActionParameter + '=' + action;
		}
		
		this.debug("submitRequest: request is: " + camjOM.shoppingCartActionUrl + "?" + parameters);
		camjaxController.sendAjax(camjOM.shoppingCartActionUrl, parameters, camjOM.parseJSONResponse, [camjOMReturnFunction, optionalReturnFunctionParameters]);
	}
	
	function parseJSONResponse(responseText, camjOMReturnFunction, optionalReturnFunctionParameters)
	{	
		try
		{	
			var order = JSON.parse(responseText);
			camjOM.debug("parseJSONResponse: Order data parsed. Order total is: " + order.total);
			if(camjOMReturnFunction != null)
			{
				try
				{
					camjOM.debug("parseJSONResponse: About to camjOMReturnFunction(order)...");
					camjOMReturnFunction(order, optionalReturnFunctionParameters);
				}
				catch(camjOMReturnFunctionError)
				{
					alert("camjOM error: No success executing camjOMReturnFunction. \n\nError Message: " + camjOMReturnFunctionError + "\n\nReturn Function: \n\n" + camjOMReturnFunction);
				}
			}
		}
		catch(jsonParseError)
		{
			alert("camjOM error: Unable to parse JSON response. Error message was: " + jsonParseError);
		}
	}
	
	function getMatchingValueIndexInArray(value, array)
	{
		for(var i = 0; i < array.length; i ++)
		{
			if(array[i] == value)
			{
				return i;
			}
		}
	
		return -1;
	}
	
	/******************************************
	ADD TO CART FUNCTIONS
	******************************************/
	
	function addToCart(productId, quantity)
	{
		this.debug("addToCart: hit with productId, quantity = " + productId + "," + quantity);
		var validQuantity = getValidQuantityFromFieldValue(quantity);
		var parameters = 'productId=' + productId + '&quantity=' + validQuantity;
		this.debug("addToCart: about to submitRequest");
		this.submitRequest('addToCart', parameters, camjOM.addToCartReturn, [productId]);
	}
	
	function addToCartReturn(order, args)
	{
		camjOM.debug("addToCartReturn: args is: " + args);
		
		if(order.modifiedOrderLine)
		{
			if(camjOM.updateFunction_addToCart != null)
			{
				try
				{
					camjOM.updateFunction_addToCart(order, order.modifiedOrderLine);
				}
				catch(camjOMUpdateFunctionException)
				{
					alert("No success executing user configured update function for addToCart. Please ensure method takes following parameters: order, changedOrderLine");
				}
			}
			else
			{
				camjOM.debug("No add to cart update function configured");
			}
		}
		else
		{
			camjOM.debug("No modified order line on order");
		}
	}
	
	/******************************************
	REMOVE ORDER LINE
	******************************************/
	
	function removeFromCart(orderLineId)
	{
		this.submitRequest('removeFromCart', 'orderLineId=' + orderLineId, camjOM.removeFromCartReturn, [ orderLineId ]);
	}
	
	function removeFromCartReturn(order, removedOrderLineId)
	{
		camjOM.updateFunction_removeFromCart(order, removedOrderLineId);
	}
	
	/******************************************
	CLEAR ALL FROM CART
	******************************************/

	function clearAllFromCart()
	{
		this.submitRequest('clearCart', null, camjOM.clearAllFromCartReturn, null);
	}

	function clearAllFromCartReturn(order)
	{
		camjOM.updateFunction_clearAllFromCart(order);
	}
	
	/******************************************
	ORDER LINE QUANTITY FUNCTIONS
	******************************************/
	
	function changeOrderLineQuantity(orderLineId, newQuantity)
	{
		var validQuantity = getValidQuantityFromFieldValue(newQuantity);
		var changeTime = new Date().valueOf();
		
		camjOM.lastChangeTimes[orderLineId] = changeTime;
		
		setTimeout('camjOM.checkChangeOrderLineQuantity(' + changeTime + ',\'' + orderLineId + '\',' + validQuantity + ')', camjOM.changeDelay * 1000);
	}
	
	function changeOrderLineQuantityReturn(order)
	{
		
	}
	
	function getValidQuantityFromFieldValue(newQuantity)
	{
		if(isNaN(newQuantity) || parseInt(newQuantity) < 1)
		{
			return 1;
		}
		
		return parseInt(newQuantity);
	}
	
	function checkChangeOrderLineQuantity(changeTime, orderLineId, newQuantity)
	{
		if(changeTime == camjOM.lastChangeTimes[orderLineId])
		{
			submitChangeOrderLineQuantity(orderLineId, newQuantity);
		}
	}
	
	function submitChangeOrderLineQuantity(orderLineId, newQuantity)
	{
		var parameters = 'orderLineId=' + orderLineId;
		parameters += '&quantity=' + newQuantity;

		camjOM.submitRequest('changeOrderLineQuantity', parameters, camjOM.changeOrderLineQuantityReturn, [ orderLineId ]);
	}
	
	function changeOrderLineQuantityReturn(order, changedOrderLineId)
	{
		var changedOrderLine = null;
		var storedOrderLineIndex;
		
		for(var i = 0; i < order.orderLines.length; i ++)
		{
			if(order.orderLines[i].id == changedOrderLineId)
			{
				changedOrderLine = order.orderLines[i];
			}
		}
		
		//Order line being null is a valid case if the order line is removed before this response returns
		if(changedOrderLine != null && camjOM.updateFunction_changeOrderLineQuantity != null)
		{
			camjOM.updateFunction_changeOrderLineQuantity(order, changedOrderLine);
		}
	}
}

var camjOM = new CamjOM();
