var nlm = new nlmScripter;

var SITE_ROOT = '';

var CART_URL = SITE_ROOT + '/cart.http.php';



var ERRORS = new Array();

var CURRENT_ADDRESS_TYPE = '';



var ADDRESS_SHIPPING = 'shipping';

var ADDRESS_BILLING = 'billing';





var SHIPPING_FOUND = false;



/**

 * ***

 * Front end functions for adding a new product to the cart.

*/



/**

 * Add a product to cart. The quantity and atttributes will automatically be added

 * by grabbing the values from the DOM.

*/

function addToCart(product_id) {

	// First, get any attributes

	var attr = $('attributes_' + product_id);



	var quantity = $('quantity_' + product_id).value();

	quantity = parseInt(quantity);

	

	if ( isNaN(quantity) || quantity < 1) {

		alert('The quantity must be a number greater than 0.');

		return false;

	}

	

	params = new Object();

	params.action = 'addproduct';

	params.product_id = product_id;

	params.quantity = quantity;

	

	_sendRequest(params, function(json) { _httpAddToCart(json, product_id); } );

}



/**

 * Handle the response after a product has been added to a cart.

*/

function _httpAddToCart(json, pid) {

	//var response = nlm.json(json);



	//var pid = response.product_id;



	//var message_class = ( 1 == response.error ? 'error' : 'success' );

	// class - FireFox/good browsers

	//$('request_message_' + pid).attr('class', message_class);

	

	// className - IE

	//$('request_message_' + pid).attr('className', message_class);

	

	//$('request_message_' + pid).replace( T('span', { content: response.text } ) );



	$('request_message_' + pid).addHtml(json);

	setTimeout( function() { $('request_message_' + pid).addHtml('') }, 5000);

}





/**

 * ***

 * Shopping Cart Front End Functions

 * ***

*/





/**

 * Determines which step of the cart to show depending on the validation

 * of previous form inputs.

*/

function showStep(step_num) {

	ERRORS = new Array();

	

	switch ( step_num ) {

		// Just a placeholder

		case STEP_BEGIN: {
			_gaq.push(['_trackPageview', '/cart/begin']);
			break;

		}

		

		// They are going to the shipping section, so the name and email

		// address need to be validated.

		case STEP_SHIPPING: {

			var validate_begin = _validateBegin();

			if ( true == validate_begin ) {

				showQuantityText('update_quantities_shipping', 'update_quantities_finalize');

				_saveCustomer();
				_gaq.push(['_trackPageview', '/cart/shipping']);

			} else {

				_message(ERRORS, 1);

			}

			

			break;

		}

	

		// The customer is going to the billing section, so the shipping address

		// and shipping method must be selected.

		case STEP_BILLING: {

			var validate_address = _validateForm('shipping_address', true);

			var validate_sm = _validateShippingMethod();



			if ( true == validate_address && true == validate_sm ) {

				$('update_quantities_shipping').style('display', 'none');

				$('update_quantities_finalize').style('display', 'none');

				

				_saveAddress('shipping_address', ADDRESS_SHIPPING, _httpSaveAddress);

				_setDisableQuantity(true);
				_gaq.push(['_trackPageview', '/cart/billing']);

			} else {

				_message(ERRORS, 1);

			}



			break;

		}

		

		// They are going to the confirmation section. The Billing Address and

		// Billing Information need to be validated before that can happen.

		case STEP_CONFIRM: {

			var validate_address = _validateForm('billing_address', false);

			var validate_billing = _validateForm('billing_information', false);

			

			if ( false == validate_billing || false == validate_address ) {

				_message(ERRORS, 1);

			} else {

				if ( true == validate_billing ) {

					_saveBilling('billing_information');

				}

				

				if ( true == validate_address ) {

					_saveAddress('billing_address', ADDRESS_BILLING, _httpSaveAddress);

				}

				

				showQuantityText('update_quantities_finalize', 'update_quantities_shipping');

				

				calculateTotal();

				_setDisableQuantity(true);
				_gaq.push(['_trackPageview', '/cart/confirm']);

			}

			

			break;

		}

		

		case STEP_FINAL: {

			hideAll();

			showQuantityText('update_quantities_finalize', 'update_quantities_shipping');

			$('shopping_cart_final').style('display', 'block');

			$('shopping_cart_product_list').style('display', 'none');

			
			_gaq.push(['_trackPageview', '/cart/final']);
			break;

		}

	}

}





function showQuantityText(show_field, hide_field) {

	$(hide_field).style('display', 'none');

	$(show_field).style('display', 'inline');

}



/**

 * Shows the shipping section.

*/

function showShipping() {

	hideAll();

	_setDisableQuantity(false);

	

	showQuantityText('update_quantities_shipping', 'update_quantities_finalize');

	$('shopping_cart_shipping').style('display', 'block');

}



/**

 * Shows the billing section.

*/

function showBilling() {

	hideAll();



	$('update_quantities_shipping').style('display', 'none');

	$('update_quantities_finalize').style('display', 'none');

	$('shopping_cart_billing').style('display', 'block');

}



/**

 * Shows the billing section.

*/

function showOverview() {

	hideAll();

	$('shopping_cart_overview').style('display', 'block');

}



/**

 * Hides all sections.

*/

function hideAll() {

	$('shopping_cart_start').style('display', 'none');

	$('shopping_cart_shipping').style('display', 'none');

	$('shopping_cart_billing').style('display', 'none');

	$('shopping_cart_overview').style('display', 'none');

}



function _setDisableQuantity(set) {

	var inputs = $('shopping_cart_product_list').childrenRaw('select');

	

	var i=0;

	for ( i=0; i<inputs.length; i++ ) {

		//if ( inputs[i].type == 'text' ) {

			inputs[i].disabled = set;

		//}

	}

}





/**

 * ***

 * Validation Functions

 * ***

*/



/**

 * Function to validate the Name and Email Address entered before the customer

 * can continue the checkout.

*/

function _validateBegin() {

	var inputs = $('customer_data').children('input');

	

	if ( inputs.name.length < 1 ) {

		ERRORS.push('Please enter a name.');

	}

	

	if ( inputs.email_address.length < 1 || false == _validateEmail(inputs.email_address) ) {

		ERRORS.push('The email address entered is invalid.');

	}

	
	if ( inputs.company.length < 1 ) {
		ERRORS.push('Please enter a company name.');
	}

	if ( inputs.phone_number.length < 1 ) {
		ERRORS.push('Please add a phone number.');
	}

	

	return ( ( ERRORS.length > 0 ) ? false : true );

}



function _validateForm(form_name, reset) {

	// If reset is true, the ERRORS array should be reset. If there

	// are multiple forms on the same page, reset should be set to false

	// so that the customer sees the errors of all forms.

	if ( true == reset ) { ERRORS = new Array(); }



	var form = $(form_name).childrenRaw('input');

	

	var i=0;

	for ( i=0; i<form.length; i++ ) {

		// Elements must be required to pass.

		// TODO: Make required a regex that they must pass.

		if ( 1 == form[i].getAttribute('required') ) {

			if ( form[i].value.length < 1 ) {

				var input_name = form[i].name.split('_').join(' ');

				ERRORS.push('Please enter a value into the "' + input_name + '" field.');

			}

		}

	}

	

	return ( ( ERRORS.length > 0 ) ? false : true );

}



/**

 * Validates whether or not a shipping method was selected.

*/

function _validateShippingMethod() {

	var form = $('shipping_method_list').childrenRaw('input');



	var i=0;

	var passed = false;

	for ( i=0; i<form.length; i++ ) {

		if ( true == form[i].checked ) { passed = true; }

	}



	if ( false == passed ) {

		ERRORS.push('Please select a Shipping Method before you continue.');

	} else {

		saveShippingMethod();

	}



	return passed;

}





function validateZipCode(zip_code) {

	//zip_code = zip_code;

	

	if ( zip_code.length == 5 ) {

		getShipping();

	}

}



/**

 * ***

 * Customer Information Management Functions

 * ***

*/





/**

 * Saves the Customer's Name and Email address to the session

*/

function _saveCustomer() {

	var inputs = $('customer_data').children('input');

	

	params = new Object();

	params.action = 'savecustomer';

	params.name = inputs.name;

	params.email_address = inputs.email_address;

	params.company = inputs.company;
	params.phone_number = inputs.phone_number;

	

	_sendRequest(params, _httpSaveCustomer);

}



/**

 * Callback from _saveCustomer()

*/

function _httpSaveCustomer(json) {

	var response = nlm.json(json);

	

	_message(response.text, response.error);

	if ( 0 == response.error ) {

		showShipping();

	}

}



/**

 * Saves an address to the session. The type is either shipping or billing.

 * save_function is a callback for what should happen after the address is saved.

*/

function _saveAddress(form_name, type, save_function) {

	var inputs = $(form_name).children('input');

	var state = $(form_name).children('select').state;

	var country = inputs.country; //$(form_name).children('select').country;





	var params = new Object();

	params.action = 'saveaddress';

	params.address_type = type;

	

	params.name = inputs.name;

	params.street_one = inputs.street_address_one;

	params.street_two = inputs.street_address_two;

	params.city = inputs.city;

	params.state = state;

	params.zip_code = inputs.zip_code;

	params.country = country;



	_setAddressType(type);

	_sendRequest(params, save_function);

	_writeAddress(type, params);

}



/**

 * Callback for after an address has been saved.

*/

function _httpSaveAddress(json) {

	var response = nlm.json(json);

	

	_message(response.text, response.error);

	if ( 0 == response.error ) {

		switch ( CURRENT_ADDRESS_TYPE ) {

			case ADDRESS_SHIPPING: {

				showBilling();

				break;

			}

			

			case ADDRESS_BILLING: {

				showOverview();

				break;

			}

		}

	}

}



function saveShippingMethod() {

	var form = $('shipping_method_list').childrenRaw('input');



        var i=0;

	var method;

	var price = 0.0;

	for ( i=0; i<form.length; i++ ) {

		if ( true == form[i].checked ) {

			method = form[i].value;

		}

	}



	price = $('shipping_price_' + method).value();



	params = new Object();

	params.action = 'saveshipping';

	params.method = method;

	params.price = price;



	_sendRequest(params, function(json) { });

}



/**

 * Saves the billing information to the session.

*/

function _saveBilling(form_name) {

	var cc = $(form_name).children('input');

	

	var select = $(form_name).children('select');

	

	var params = new Object();

	params.action = 'savebilling';

	params.credit_card_name = cc.credit_card_name;

	params.credit_card_number = cc.credit_card_number;

	params.credit_card_expiration_month = select.credit_card_expiration_month;

	params.credit_card_expiration_year = select.credit_card_expiration_year;

	params.credit_card_cvv2 = cc.credit_card_cvv2;



	_sendRequest(params, function() {

			var cc_num = params.credit_card_number;

			var len = cc_num.length;

			var half = Math.ceil(len/2);

			var dist = Math.ceil(((len - half) / 2));

			

			var i=0;

			for ( i=dist; i<(dist+half); i++ ) {

				cc_num[i] = 'X';

			}



			$('shopping_cart_credit_card_overview').addHtml(

				params.credit_card_name + '<br />' +

				cc_num + '<br />' +

				params.credit_card_expiration_month + '/' + params.credit_card_expiration_year + '<br />' +

				params.credit_card_cvv2 + '<br /><br />'

			);

		}

	);

}



/**

 * Sets the global address type so it can be used in _httpSaveAddress()

*/

function _setAddressType(addr_type) {

	CURRENT_ADDRESS_TYPE = addr_type;

}



/**

 * Writes the address to the confirmation screen.

 * addr_type is either shipping or billing.

*/

function _writeAddress(addr_type, addr) {

	var addr_two = '';

	if ( '' != addr.street_two ) {

		addr_two = addr.street_two + '<br />';

	}

	

	$('shopping_cart_' + addr_type + '_overview').addHtml(

		addr.name + '<br />' +

		addr.street_one + '<br />' +

		addr_two +

		addr.city + ', ' + addr.state + ' ' + addr.zip_code + '<br />' +

		addr.country

	);

}



/**

 * Copies the address data from the 'from' form to the 'to' form.

*/

function copyAddress(from, to) {

	var from_addr = $(from).childrenRaw('input');

	var to_addr = $(to).childrenRaw('input');

	

	var from_state = $(from).children('select').state;

	var to_states = $(to).childrenRaw('option');





	var from_country = $(from).children('select').country;

	

	// Copy all of the input values.

	var i=0;

	for ( i=0; i<from_addr.length; i++ ) {

		to_addr[i].value = from_addr[i].value;

	}

	

	// Because the state is a dropdown, it needs to be handled differently.

	for ( i=0; i<to_states.length; i++ ) {

		if ( to_states[i].value == from_state ) {

			to_states[i].selected = true;

		}

		

		if ( to_states[i].value == from_country ) {

			to_states[i].selected = true;

		}

	}

}



/**

 * ***

 * Message Functions

 * ***

*/



/**

 * Writes a message to the shopping cart.

*/

function _message(msg, error) {

	var message_class = ( 1 == error ? 'message_error' : 'message_success' );

	

	if ( 'object' == typeof msg ) {

		msg = msg.join('<br />');

	}

	

	$('sc_message').addHtml(msg);

	$('sc_message').attr('class', message_class);

	$('sc_message').attr('className', message_class);

	$('sc_message').style('display', 'block');

}



/**

 * Hides the current message and resets the contents.

*/

function hideMessage() {

	$('sc_message').addHtml('');

	$('sc_message').style('display', 'none');

}



/**

 * ***

 * Shipping Functions

 * ***

*/



/**

 * Front end function for loading the shipping quotes.

 * _saveAddress() is called here to save the address first so that the

 * NLM_Mini_Cart class can just use the newly saved address rather than

 * having to pass the new data.

*/

function getShipping() {

	var validate_address = _validateForm('shipping_address', true);

	if ( true == validate_address ) {

		_saveAddress('shipping_address', ADDRESS_SHIPPING, _loadShippingQuotes);

	} else {

		_message(ERRORS, 1);

	}

}



/**

 * Callback for after the address has been saved.

*/

function _loadShippingQuotes(json) {

	_message('Loading your shipping quotes. One moment please.', 0);

	

	//$('shipping_method_list').addHtml('<img src="' + SITE_ROOT + '/Themes/Images/ajax_spinner_long.gif" />');

	$('shipping_method_list').replace( T('p', { content: 'Loading Shipping Quotes', 'class': 'success', next: T('img', { src: SITE_ROOT + '/Themes/Images/ajax_spinner_long.gif', style: 'margin: auto; display: block' } ) } ) );

	

	var params = new Object();

	params.action = 'getshipping';

	

	_sendRequest(params, _showShippingQuotes);

}



/**

 * Callback from _loadShippingQuotes that displays them on the screen.

*/

// TODO: handle errors gracefully

function _showShippingQuotes(json) {

	var sml = 'shipping_method_list';

	var sq = 'shipping_quotes';

	

	// Right now, pure HTML is being returned because IE doesn't like 

	// cooperating with dynamic tables.

	$(sml).addHtml(json);

	

	/*

	$(sml).replace( T('table', { 'id': sq } ) );

	for ( var quote in methods ) {

		var q = methods[quote];

		

		$('shipping_quotes').append( T('tr',

			{ next: T('td',

				{ 'class': 'method', 'colspan': "3", 'content': q.title }

				)

			}

			)

		);



		for ( var m in q.quotes ) {

			var x = q.quotes[m];

			var quote_id = 'quote_' + x.method;

			$(sq).append( T('tr', { id: quote_id} ) );



			// mn = Method Name

			var mn = T('td',

				{ 'class': 'method_name', content: x.method_name }

			);

			

			// mp = Method Price

			var mp = T('td',

				{ 'class': 'method_price', content: '$' + x.price }

			);

			

			// ms = Method Select

			var ms = T('td',

				{ 'class': 'method_select', next: T('input',

					{ type: 'radio', onclick: "saveShippingMethod()", name: 'shipping_method', value: x.method }

					)

				}

			);



			var mph = T('input', {type: 'hidden', id: 'shipping_price_' + x.method, value: x.price } );

			$(quote_id).append(mn);

			$(quote_id).append(mp);

			$(quote_id).append(ms);

			$(quote_id).append(mph);

		}

	}

	*/

	_message('Shipping Method quotes successfully loaded!', 0);

	

	// Global variable to determine if shipping has been calculated

	SHIPPING_FOUND = true;

}


/**
 * Shopping Cart and Line Item Management Functions
*/

/**
 * Updates the quantity of a line item by the product ID. 
*/
function updateQuantity(product_id) {
	var quantity = parseInt($('quantity_' + product_id).value());
	var original_quantity = parseInt($('product_quantity_original_' + product_id).value());

	if ( true == isNaN(quantity) ) {
		quantity = 0;
	}
	
	var delete_item = true;
	if ( 0 == quantity ) {
		delete_item = confirm('Are you sure you want to remove this product from your Shopping Cart?');
	}
	
	if ( true == delete_item ) {
		params = new Object();
		params.action = 'updateproduct';
		params.product_id = product_id;
		params.quantity = quantity;
		
		$('product_quantity_original_' + product_id).setValue(quantity);

		_sendRequest(params, function(json) {
				// Recalculate the total for this line item
				calculateLineItemTotal(product_id, quantity);
				
				// Recalculate the totals for the order
				calculateTotal();
				
				// Recalculate the shipping if all of the information
				// has already been filled out.
				if ( true == SHIPPING_FOUND ) {
					getShipping();
				}
			}
		);
	} else {
		$('quantity_' + product_id).setValue(original_quantity);
	}
}

/**

 * Calculates the total of the order.

*/

function calculateTotal() {

	params = new Object();

	params.action = 'calculatetotal';



	_sendRequest(params, _updateTotals);

}



/**

 * Calculates the line item total (total_price) for a line item.

*/

function calculateLineItemTotal(product_id, quantity) {

	var price = parseFloat( $('product_price_' + product_id).value() );

	var quantity = parseInt(quantity);

	

	$('total_price_' + product_id).addHtml( (price * quantity).toFixed(2) );

	

	if ( 0 == quantity ) {

		$('product_listing_item_' + product_id).style('display', 'none');

	}

}





/**

 * Finalizes the order and ensures the card is successfully charged.

*/

function finalizeOrder(button) {

	hideMessage();

	

	params = new Object();

	params.action = 'saveorder';



	button.disabled = 'disabled';

	button.className = 'large_button_disabled';

	

	_sendRequest(params, function(json) { _saveOrder(json, button); } );

}



function _saveOrder(json, button) {

	var order = nlm.json(json);



	if ( 0 == order.error ) {

		$('shopping_cart_title').style('display', 'none');

		$('shopping_cart_product_list').style('display', 'none');

		$('button_edit_shipping').style('display', 'none');

		$('button_edit_billing').style('display', 'none');

		$('button_finalize').style('display', 'none');

		

		_message('Thank you for your order! Your Order ID is ' + order.order_id, 0);
		var cart_page = '/order-complete: ' + order.order_id;
		_gaq.push(['_trackPageview', cart_page]);

	} else {

		button.disabled = null;

		button.className = 'large_button';

	

		_message(order.text, 1);

	}

}





/**

 * Callback to write the totals where necessary.

*/

function _updateTotals(json) {

	var total = nlm.json(json);



	$('total_sub').addHtml(total.sub);

	$('total_tax').addHtml(total.tax);

	$('total_shipping').addHtml(total.shipping);

	$('total_total').addHtml(total.total);

	$('total_tax_rate').addHtml(total.tax_rate);

	$('cart_product_listing_subtotal').addHtml(total.sub);

}



/**

 * Sends an HTTP Request.

*/

function _sendRequest(params, callback_func) {

	nlm.httpRequest( {

		url: CART_URL,

		params: params,

		method: 'POST',

		headers: { 'Content-type': 'application/x-www-form-urlencoded' },

		isasync: true,

		isxml: false,

		callback: callback_func

		}

	);

}



/**

 * Validates an email address, loosely based on RFC2882 (I think).

*/

function _validateEmail(email) {

	var email_regex = /([a-z0-9-_.!#$%^&*~`]+)(@[a-z0-9-]+\.[a-z]+)/i;

	var regex = new RegExp(email_regex);



	return regex.test(email);

}