/*
 *  InventoryChecker JS to perform inventory checking functions
 */
var InventoryChecker = function() {

	var byPass;
	var catalogId;
	var basePath = "/cc";
	var successCallBack, failedCallBack;

	function singleItemToRealTimeCheckJSON(skuInnotracId, askingQty) {

		var inputJSONStr = "[";
		inputJSONStr += "{innotracId:" + skuInnotracId;
		inputJSONStr += ",askingQty:" + askingQty;
		inputJSONStr += "}";
		inputJSONStr += "]";
		return inputJSONStr;
	}
	function singleItemToAtgCheckJSON(skuId, askingQty) {

		var inputJSONStr = "[";
		inputJSONStr += "{skuId:" + skuId;
		inputJSONStr += ",askingQty:" + askingQty;
		inputJSONStr += "}";
		inputJSONStr += "]";
		return inputJSONStr;
	}
	function convertCartToRealTimeCheckJSON() {
		var inputJSONStr = "[";
		var i = 0;
		$("#cartShow #cart-tbl tr.cartitem").each(function(i) {
			if (i > 0) {
				inputJSONStr += ",";
			}
			var eachSku = this;
			var skuInnotracId = $(eachSku).attr("innotracId");
			var skuQuantity = $(eachSku).find(".checkoutQuantity").val();

			inputJSONStr += "{innotracId:" + skuInnotracId;
			inputJSONStr += ",askingQty:" + skuQuantity;
			inputJSONStr += "}";
			i++;
		});
		inputJSONStr += "]";
		return inputJSONStr;
	}

	function convertCartToAtgCheckJSON() {
		var inputJSONStr = "[";
		var i = 0;
		$("#cartShow #cart-tbl tr.cartitem").each(function(i) {
			if (i > 0) {
				inputJSONStr += ",";
			}
			var eachSku = this;
			var skuId = $(eachSku).attr("skuId");
			var skuQuantity = $(eachSku).find(".checkoutQuantity").val();

			inputJSONStr += "{skuId:" + skuId;
			inputJSONStr += ",askingQty:" + skuQuantity;
			inputJSONStr += "}";
			i++;
		});
		inputJSONStr += "]";
		return inputJSONStr;
	}

	function atgCheck(inputJSONStr, currSuccessCallBack, currFailedCallBack) {

		if (byPass) {
			InventoryChecker.handleCallBack([], currSuccessCallBack,
					currFailedCallBack);
		} else {
			$.post(basePath + "/checkout/include/inventoryCheck.jsp", {
				catId : catalogId,
				inputJSON : inputJSONStr
			}, function(result) {
				// alert("result: " + result);
				try {
					result = result.replace(/^\s\s*/, '').replace(/\s\s*$/, '')
							.replace(/[\r\n]+/g, "");
				} catch (e) {
				}
				InventoryChecker.handleCallBack(result, currSuccessCallBack,
						currFailedCallBack);

			}, "json");
		}
	}

	function realTimeCheck(inputJSONStr, currSuccessCallBack,
			currFailedCallBack) {

		if (byPass) {
			InventoryChecker.handleCallBack([], currSuccessCallBack,
					currFailedCallBack);
		} else {
			$.post(basePath + "/checkout/include/realTimeInventoryCheck.jsp", {
				inputJSON : inputJSONStr
			}, function(result) {
				// alert("result: " + result);
				try {
					result = result.replace(/^\s\s*/, '').replace(/\s\s*$/, '')
							.replace(/[\r\n]+/g, "");
				} catch (e) {
				}
				InventoryChecker.handleCallBack(result, currSuccessCallBack,
						currFailedCallBack);

			}, "json");
		}
	}

	function fillErrorForCart(result) {
		if (result) {
			$
					.each(
							result,
							function(thisCount) {
								var thisInventoryInfo = result[thisCount];
								if (!thisInventoryInfo.isAvailable) {
									$(
											"#cart-item-error-msg-"
													+ thisInventoryInfo.skuId)
											.html(
													InventoryChecker
															.getOutOfStockMsg(thisInventoryInfo.skuId));
								}
							});
		}
	}
	function handleCallBack(result, currSuccessCallBack, currFailedCallBack) {

		var isValid = true;
		if (result) {
			$.each(result, function(thisCount) {
				var thisInventoryInfo = result[thisCount];
				if (!thisInventoryInfo.isAvailable) {
					isValid = false;
				}
			});
		} else {
			isValid = false;
		}

		if (byPass || isValid) {
			if (currSuccessCallBack) {
				currSuccessCallBack(result);
			} else {
				successCallBack(result);
			}
		} else {
			if (currFailedCallBack) {
				currFailedCallBack(result);
			} else {
				failedCallBack(result);
			}
		}
	}

	return {
		init : function(_byPass, _catalogId, _successCallBack, _failedCallBack) {
			//initialization, must be called to use functions in this class
			byPass = _byPass;
			catalogId = _catalogId;
			
			//default callbacks
			successCallBack = _successCallBack;
			failedCallBack = _failedCallBack;
		},
		convertCartToJSON : function() {
			// traverse the cartShow html structure and convert to a JSON string to submit real time query
			convertCartToJSON();
		},
		convertCartToAtgCheckJSON : function() {
			// traverse the cartShow html structure and convert to a JSON string to submit atg checking query
			convertCartToAtgCheckJSON();
		},
		atgCheckForCart : function(currSuccessCallBack, currFailedCallBack) {
			// calling inventory check at atg inventory for the whole cart with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			atgCheck(convertCartToAtgCheckJSON(), currSuccessCallBack,
					currFailedCallBack);
		},
		atgCheckForCartWithTargetUrl : function(targetUrl) {
			// customized atg inventory check where success will redirect user to the tagetUrl and
			// failed will call the fillErrorForCart function
			atgCheck(convertCartToAtgCheckJSON(),
					function() {
						window.location= targetUrl;
					},
					function(result) {
						fillErrorForCart(result);
					});
		},
		atgCheck : function(s, currSuccessCallBack, currFailedCallBack) {
			// calling inventory check at atg inventory for any properly formatted json String 
			// with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			atgCheck(s, currSuccessCallBack, currFailedCallBack);
		},
		atgCheckForSingleItem : function(skuId, askingQty, currSuccessCallBack,
				currFailedCallBack) {
			// calling inventory check at atg inventory for any an item (skuID and qty) 
			// with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			atgCheck(singleItemToAtgCheckJSON(skuId, askingQty),
					currSuccessCallBack, currFailedCallBack);
		},
		realTimeCheckForCart : function(currSuccessCallBack, currFailedCallBack) {
			// calling inventory check against innotrac real time inventory for the whole cart with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			realTimeCheck(convertCartToRealTimeCheckJSON(),
					currSuccessCallBack, currFailedCallBack);
		},
		realTimeCheckForCartWithTargetUrl : function(targetUrl) {
			// customized innotrac real time inventory check where success will redirect user to the tagetUrl and
			// failed will call the fillErrorForCart function
			realTimeCheck(convertCartToRealTimeCheckJSON(),
					function() {
						window.location= targetUrl;
					},
					function(result) {
						fillErrorForCart(result);
					});
		},
		realTimeCheck : function(s, currSuccessCallBack, currFailedCallBack) {
			// calling inventory check against innotrac real time inventory for any properly formatted json String 
			// with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			realTimeCheck(s, currSuccessCallBack, currFailedCallBack);
		},
		realTimeCheckForSingleItem : function(innotracId, askingQty,
				currSuccessCallBack, currFailedCallBack) {
			// calling inventory check against innotrac real time inventory for any an item (innotracId and qty) 
			// with a success and failed callbacks for action
			// result in json will be submitted to the callbacks
			realTimeCheck(singleItemToRealTimeCheckJSON(innotracId, askingQty),
					currSuccessCallBack, currFailedCallBack);
		},
		handleCallBack : function(isValid, currSuccessCallBack,
				currFailedCallBack) {
			// generic call back handling and determines whether a custom call is provided or we need to use the default
			// For internal use mostly
			handleCallBack(isValid, currSuccessCallBack, currFailedCallBack);
		},
		getOutOfStockMsg : function(sid, qty) {
			// generic handling of out of stock msg
			return "Item out of stock";
		},
		fillErrorForCart : function(resultJSON) {
			// generic function to populate cart structure with error messages
			fillErrorForCart(resultJSON);
		},
		setByPass : function(_byPass) {
			// set bypass to bypass checking and return true for all checks
			byPass = _byPass;
		}
	}
}();

// initializing the class 
InventoryChecker.init(false, "catalog10001", function() {
	// default success response
}, function() {
	// default failed response
	alert("Item out of stock");
});
