function ShoppingCart(options) {
	var that = this;

	/* ////////////////////////////////////////////////////  settings */
	var settings     = options              || {};
	var debug        = settings.debug       || false;
	var itemsN       = settings.itemN       || "items";
	var optionsN     = settings.optionsN    || "options";
	var cartDN       = settings.cartDN      || "cartDN";
	var $cartItems   = settings.cartItems   || $(".cartItem");
	var $BTNcheckout = settings.BTNcheckout || $(".BTNcheckout");
	var $BTNshowCart = settings.BTNshowCart || $(".BTNshowCart");
	var $BTNhideCart = settings.BTNhideCart || $(".BTNhideCart");
	var $cartdisplay = settings.cartdisplay || $("#cartdisplay");
	var removeText   = settings.removeText  || "remove";
	var cartState    = settings.cartState   || false;

	/* ////////////////////////////////////////////////////  variables */
	var WM_cart_ids     = new Array();
	var WM_cart_options = new Array();

	/* ////////////////////////////////////////////////////  private functions */

	function createCookie(name,value,days) { 
		if (days) { 
			var date = new Date(); 
			date.setTime(date.getTime() + (days*24*60*60*1000)); 
			var expires = "; expires=" + date.toGMTString(); 
		} else { 
			var expires = ""; 
		} 
		document.cookie = name + "=" + value+expires + "; path=/"; 
	}

	function readCookie(name) { 
		var nameEQ = name + "="; 
		var ca = document.cookie.split(';'); 
		for(var i=0;i < ca.length;i++) { 
			var c = ca[i]; 
			while (c.charAt(0)==' ') c = c.substring(1,c.length); 
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); 
		}
		return null; 
	}

	function eraseCookie(name) { createCookie(name,"",-1); }

	function storeShowCart(state) { 
		if(state) {
			createCookie(cartDN, "true"); 
		} else {
			createCookie(cartDN, "false"); 
		}
	}

	function showCartState() { return readCookie(cartDN); }

	function setCartState() {
		var state = showCartState();
		if (state === "true") {
			cartState = true;
		} else {
			cartState = false;
		}
	}

	function dbg() {
		for(var x=0; x< arguments.length; x++) {
			arguments[x] && console.log(arguments[x]);
		}
	};

	function createHidden(name, value) {
		return "<input type=\"hidden\" name=\"" + name + "\" value=\"" + value + "\" />";
	}

	function buildCartForm(cart) {
		var html = "";

		html += '<form action="https://www.paypal.com/cgi-bin/webscr" method="post">';

		var metaFields = {
			cmd           : "_cart",
			upload        : 1,
			business      : "justin@kempton.com",
			currency_code : "USD",
			"return"      : "http://www.writersmugs.com/thankyou.php",
			"cancel"      : "http://www.writersmugs.com/cancel.php"
		};

		for(a in metaFields) {
			html += createHidden(a, metaFields[a]);
		}

		var cartData = cart.cart;

		$.each(cartData, function(i, item) {
			i++;

			var fields = {
				amount      : item.price,
				item_name   : item.name + " : #" + item.available,
				item_number : item.id,
				quantity    : item.incart,
				// shipping    : item.shipping
			};

			for(a in fields) {
				html += createHidden(a + "_" + i, fields[a]);
			}
		});

		/* shipping */
		html += createHidden("handling_cart", cart.total_shipping);

		html += '<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">';

		html += '</form>';

		return html;
	}

	function showEmptyCart() {
		$cartdisplay.html("");
	}

	function buildCartItem(item) {
		var html = "";
		if(item) {
			html += "<div id='wm_" + item.id + "' class='unit option-" + item.option + "'>";
			html += (item.thumb) ? "<div class='image'><img src='" + item.thumb + "' /></div>" : "";
			html += (item.name && item.incart) ? "<div class='sub name'><b>" + item.name + " x " + item.incart + "</b></div>" : "";
			html += (item.arttype) ? "<div class='sub type'><b>" + item.arttype + "</b></div>" : "";
			html += (item.id) ? "<div class='sub id'><i>id:</i><b>" + item.id + "</b></div>" : "";
			html += (item.available) ? "<div class='sub edition'><i>edition:</i><b>" + (item.available) + "</b></div>" : "";
			html += (item.price) ? "<div class='sub price'><i>price:</i><b>" + (item.price) + "</b></div>" : "";
			html += (item.shipping) ? "<div class='sub shipping'><i>shipping:</i><b>" + (item.shipping) + "</b></div>" : "";
			html += "<div class='remove'>"+ removeText +"</div>";
			html += "</div>";
		}
		return html;
	}

	function buildCartType(cartType, cartTypeNameRaw) {
		var html       = "";

		if(cartType) {
			var typeName   = cartTypeNameRaw.substring(2) ||  "";
			var totalUnits = cartType.numberpurchased     ||  0;
			var options    = cartType.option              ||  "";
			var price      = parseInt(cartType.price)     ||  0;
			var total      = cartType.total               ||  "";

			html += '<div class="cartType">';
			html += '<span class="numbers">';
			html += totalUnits + " X " + "$" + price;
			html += '</span>';
			html += '<span class="typeName">';
		  html +=	" - " + typeName; 
			html += '</span>';
			html += '<div class="optionsAndTotal">';
			html += '<span class="options">';
			html += options; 
			html += '</span>';
			html += '<span class="total">';
			html += '$' + total; 
			html += '</span>';
			html += '</div>';
			html += '</div>'; 
		}

		return html;
	}

	function buildCartTypeItems(data) {
		var html = "";

		if(data && data.item_types) {
			for(i in data.item_types) {
				html += buildCartType(data.item_types[i], i);
			}
		}

		return html;
	}

	function createCart(data) {
		console.log(data);
		var itemsHTML = "", cartOuter = "";

		/* create the body guts */
		$.each(data.cart, function(i, item) {
			i++;
			itemsHTML += buildCartItem(item);
		});

		cartOuter += '<div class="cartTray">';
		cartOuter += '	<div class="pad shadow round">';
		cartOuter += '		<div class="header">';
		cartOuter += '			<span class="CT-close">&#10006</span>';
		cartOuter += '			<h1>WritersMugs <i>-</i> <em>serving mugs since 2003</em></h1>';
		cartOuter += '		</div>';
		cartOuter += '		<div class="body">';
		cartOuter += '			<div class="fr">';
		cartOuter += '				<div class="cartTotals" class="pad">';
		cartOuter += '					<h2>Total <span "total-cost">$' + data.total_price + '</span></h2>';

		cartOuter += buildCartTypeItems(data);

		cartOuter += '					<h3 class="subtotal">Sub Total: <span "total-cost">$ ' + data.sub_total_price + '</span></h3>';
		cartOuter += '					<h4 class="shippingAndHandling">Shipping & Handling: <span "total-cost">$' + data.total_shipping + '</span></h4>';
		cartOuter += '					<div class="purchaseDiv">';

		/* buy button */
		cartOuter += buildCartForm(data);

		cartOuter += '					</div>';
		cartOuter += '				</div>';
		cartOuter += '			</div>';
		cartOuter += '			<div class="fl">';
		cartOuter += '				<div class="cartItems">';
		cartOuter += '					<h2>Cart Items</h2>';
		cartOuter += '					<div class="pad">';
		cartOuter += '						<div class="cartList">';

		/* cart items */
		cartOuter += itemsHTML;

		cartOuter += '						</div>';
		cartOuter += '					</div>';
		cartOuter += '				</div>';
		cartOuter += '			</div>';
		cartOuter += '			<div style="clear:both;"></div>';
		cartOuter += '		</div>';
		cartOuter += '	</div>';
		cartOuter += '</div>';

		cartState = true;
		storeShowCart("true");


		/* build on page */
		$cartdisplay.html("<div class='WM_Cart'>" + cartOuter + "</div>"); 

		/* re create interative stuff */
		inCartActions();
	}

	/* ////////////////////////////////////////////////////  public functions */

	that._readCookie = function(name) { return readCookie(name); }

	that.clearCookies = function() {
		eraseCookie(itemsN);
		eraseCookie(optionsN);
	};

	that.sendCartToSite = function() {
		/* gather cookie */
		if(readCookie(itemsN) != null) {
			WM_cart_ids = readCookie(itemsN).split("*");
			WM_cart_options = readCookie(optionsN).split("*");

			debug && dbg("sendCartToSite", "WM_cart_ids", WM_cart_ids, "WM_cart_options", WM_cart_options, (readCookie(itemsN) || "items are empty"), (readCookie(optionsN) || "options are empty"));

			var obj = {
				'items' : WM_cart_ids,
				'options' : WM_cart_options
			}

			/* send it as request */
			$.ajax({
				type: "GET",
				url: "http://www.writersmugs.com/income/cart.php",
				data: obj,
				dataType: "jsonp",
				success: function(data) {
					(data.cart!="empty") ? createCart(data) : showEmptyCart(); 
				},
				error: function(e) {
					alert(e);
				}
			});
		}
	};

	that.addToCart = function(obj) {
		var obj = obj || { item:4321, options:"f" };
		var items, options;

		if(items = readCookie(itemsN)) {
			createCookie(itemsN, items + "*" + obj.item);
		} else {
			createCookie(itemsN, obj.item);
		}

		if(options = readCookie(optionsN)) {
			createCookie(optionsN, options + "*" + obj.options);
		} else {
			createCookie(optionsN, obj.options);
		}

		cartState && that.sendCartToSite();
	};

	that.removeFromCart = function(id) {
		console.log(id);
		/* find the id in the cookie, get it's index, remove it and the option */
		debug && dbg("remove from cart", id, WM_cart_ids);

		var index = $.inArray(id, WM_cart_ids);

		if(WM_cart_ids.length == 1) {
			WM_cart_ids[0] = "";
			WM_cart_options[0] = "";
		} else {
			WM_cart_ids.splice(index,1);
			WM_cart_options.splice(index,1);
		}

		/* check to see if there is still an array */
		if(WM_cart_ids.length>0) {
			var temp_ids = "", temp_options = "";
			for(var x=0; x<WM_cart_ids.length; x++) {
				temp_ids += WM_cart_ids[x];
				temp_options += WM_cart_options[x];
				if(x!=WM_cart_ids.length-1) {
					temp_ids += "*";
					temp_options += "*";
				}
			}
			createCookie(itemsN, temp_ids);
			createCookie(optionsN, temp_options);
		} else {
			eraseCookie(itemsN);
			eraseCookie(optionsN);
		}	

		/* then rebuild the cart */
		that.sendCartToSite();
	};

	that.dBug = function() {
		debug && dbg("init", "WM_cart_ids", WM_cart_ids, "WM_cart_options", WM_cart_options, (readCookie(itemsN) || "items are empty"), (readCookie(optionsN) || "options are empty"));
	};

	function inCartActions() {

		$BTNhideCart.add(".CT-close").click(function() {
			$cartdisplay.slideUp();
			cartState = false;
			storeShowCart(false);
		});

		$BTNshowCart.click(function() {
			$cartdisplay.slideDown();
			cartState = false;
			storeShowCart(true);
		});

		$cartdisplay.find(".remove").click( function() {
			var $par = $(this).parents(".unit");
			var id = $par.attr("id").substring(3);
			that.removeFromCart(id);
			$par.fadeOut();
		});
	}

	that.addEvents = function() {
		debug && dbg("addInteraction");

		$cartItems.click( function() {
			cartState = true;
			$cartdisplay.slideDown();
			debug && dbg("cart items");
			that.addToCart({ 
				item    : $(this).attr("item"),
				options : $(this).attr("options")
			});
		});

		$BTNcheckout.click( function() {
			debug && dbg("checkout");
			that.sendCartToSite();
		});

	};

	that.init = function init() {
		setCartState();
		debug && that.dBug();
		cartState && that.sendCartToSite();
		that.addEvents();
	};

}

