var checkout_loaded = false;

var waitFor = function(params)
{
	var condition  = params.condition;
	var callback   = params.callback;
	var interval   = params.interval || 300;
	var maxTries   = params.maxTries || 30;
	var currentTry = params._currentTry || 0; // private
	
	// If condition passes, run the code
	if(condition() === true)
		return callback();
	
	// Limit the # of attempts
	if(currentTry < maxTries)
	{
		// Increment the attempt #
		params._currentTry = currentTry+1;
		
		// Create the recursive call
		var f = function(){return waitFor(params);}
		
		// Wait for one interval and execute
		setTimeout(f, interval);
	}
	else
	{
		//alert('Maximum tries used for waitFor()...quitting');
	}
};

function initCheckout()
{
	checkout_loaded = false;
	showAjaxLoader(1);
		
	// Create tabbed checkout wizard where tab 2 and 3 are disabled
	jQuery('#shop_checkout').empty().unbind();
	jQuery('#shop_checkout').append
	(
			'<div id="checkout_wrapper">'
		+		'<div id="checkout_steps">'
		+			'<div id="steps_holder">'
		+				'<span id="stepLink1" class="stepLink">Stap 1<br/><span class="stepLinksmall">Winkelmandje</span></span>'
		+				'<span id="stepLink2" class="stepLink">Stap 2<br/><span class="stepLinksmall">Uw gegevens</span></span>'
		+				'<span id="stepLink3" class="stepLink">Stap 3<br/><span class="stepLinksmall">Betalen</span></span>'
		+				'<span id="stepLink4" class="stepLink">Stap 4<br/><span class="stepLinksmall">Bevestiging</span></span>'
		+			'</div>'
		+			'<div id="steps_image_holder">'
		+				'<span id="step_image1" class="step_image"></span>'
		+				'<span id="step_image2" class="step_image"></span>'
		+				'<span id="step_image3" class="step_image"></span>'
		+				'<span id="step_image4" class="step_image"></span>'
		+			'</div>'
		+		'</div>'
		+		'<div id="checkout_content">'
		+			'<div id="step1"></div>'
		+			'<div id="step2" style="display:none;"></div>'
		+			'<div id="step3" style="display:none;"></div>'
		+			'<div id="step4" style="display:none;"></div>'
		+		'</div>'
		+	'</div>'
	);
	
	// Handles the hiding and the showing of all the loose elements
	jQuery('#shop_general').hide();
	jQuery('#product_content').hide();
	jQuery('#normal_content').hide();
	jQuery('#shop_search').hide();
	if(jQuery('#page_content_tbl').exists())jQuery('#page_content_tbl').hide();
	if(jQuery('#shop_checkout').is(':hidden'))jQuery('#shop_checkout').fadeIn();
	
	jQuery('#container').css('background-position','-2724px 0px');
	jQuery('#content_top').css('background-position','-908px 0px');

	jQuery('#permanent_assets').hide();
		
	// Hide filter table and active filters
	if(jQuery('#filtertable').exists())jQuery('#filtertable').hide();
	if(jQuery('#active_filters').exists())jQuery('#active_filters').hide();
	
	if(footer_out)
	{
		// The footer is maximized
		if(tempAssetsHeight == 0)
		{
			jQuery('#permanent_assets').css('height', jQuery('#permanent_assets').height()-100+'px');
		}
		else
		{			
			jQuery('#permanent_assets').css('height', tempAssetsHeight+'px');	
		}
	}
	
	if(active_filters)
	{
		// Active filters is visible
		if(tempAssetsHeight == 0)
		{
			jQuery('#permanent_assets').css('height', jQuery('#permanent_assets').height()-25+'px');
		}
	}
	
	
	// Loads the first step of the checkout wizard
	loadStep1();
}

function exitCheckout()
{
	jQuery('#shop_checkout').hide();
	jQuery('#product_content').hide();
	jQuery('#cart_content').hide();
	if(jQuery('#shop_general').is(':hidden'))jQuery('#shop_general').fadeIn();
	if(jQuery('#page_content_tbl').exists())
	{
		jQuery('#page_content_tbl').show();
	}
	else
	{
		jQuery('#normal_content').show();
	}
	jQuery('#container').css('background-position','-1817px 0px');
	jQuery('#content_top').css('background-position','0px 0px');
		
	if(jQuery('#filtertable').exists())jQuery('#filtertable').fadeIn();
	
	if(footer_out)
	{
		// The footer should be maximized
		if(tempAssetsHeight == 0)
		{
			jQuery('#permanent_assets').css('height', jQuery('#permanent_assets').height()+100+'px');
		}
		else
		{
			jQuery('#permanent_assets').css('height', jQuery('#holder').height()+100+'px');	
		}
	}
	
	if(active_filters)
	{
		// Active filters is visible
		if(jQuery('#active_filters').exists())jQuery('#active_filters').fadeIn();
		
		jQuery('#permanent_assets').css('height', jQuery('#permanent_assets').height()+25+'px');
	}
	
	jQuery('#permanent_assets').show();
}

function loadStep1()
{
	showAjaxLoader(1);
	
	jQuery('#step2').hide();
	jQuery('#step1').fadeIn();
	
	jQuery('#stepLink2 .stepLinksmall').css('font-size','9px').css('text-decoration','none');
	jQuery('#stepLink3 .stepLinksmall').css('font-size','9px').css('text-decoration','none');
	
	jQuery('#step_image1').css('background-position','0px -466px');
	jQuery('#step_image2').css('background-position','-150px -486px');
	
	jQuery('#step1').html
	(
			'<table>'
		+		'<thead>'
		+			'<tr>'
		+				'<th>&#32;</th>'
		+				'<th>Product</th>'
		+				'<th>Aantal</th>'
		+				'<th>Optie</th>'
		+				'<th>Prijs</th>'
		+				'<th>Totaal</th>'
		+				'<th></th>'
		+			'</tr>'
		+		'</thead>'
		+		'<tbody></tbody>'
		+		'<tfoot></tfoot>'
		+	'</table>'
	);
	
	// Loads the shopping cart data
	jQuery.getJSON('/modules/shop/load.php?item=cart&action=load',function(data)
	{
		jQuery('#stepLink1 .stepLinksmall').css('font-size','11px').css('text-decoration','underline');
		
		// Empty the step1 body	
		jQuery('#step1 tbody').html('');
		
		// For each shopping cart item (product) loaded
		jQuery.each(data, function(i,item)
		{
			var quantity_input = '';
			var quantity_order = 0;
			
			// Create a unique id based on the selected configs
			var unique_id = '';
			jQuery.each(item.selected_config, function(key, value)
			{
				if(value != '')
				{
					unique_id += '-'+value;
				}	
			});
			
			quantity_input = '<td><input id="cart_quantity'+item.id+unique_id+'" type="text" class="cart_quantity" name="'+item.in_stock+'~'+item.id+'~'+unique_id+'" value="'+item.quantity+'"/></td>'

			quantity_order = parseInt(item.quantity);
			
			// Slits up img1 into the name and extension
			var split = item.img1.split('~')[0].split('.');
			var name = split[0];
			var extension = '.'+split[1];

			// Extracts the real vat rate (vat_id~vat_rate)
			var temp_vat_rate = item.vat_rate.split('~');
			
			// Creates a new row for each product with the product information
			jQuery('#step1 tbody').append
			(
					'<tr id="cart'+item.id+'" class="cart_row">'
				+		'<td style="display: none;">'
				+			'<input type="hidden" id="order_vat_rate'+item.id+unique_id+'" value="'+temp_vat_rate[1]+'"/>'
				+			'<input type="hidden" id="cart_prod_vat'+item.id+unique_id+'" value="'+priceInclusive(temp_vat_rate[1], item.price)+'"/>'
				+			'<input type="hidden" class="cart_prod_total cart_prod_sub_total cart_vat'+parseFloat(temp_vat_rate[1])+'" id="cart_prod_vat_total'+item.id+unique_id+'" value="'+(priceInclusive(parseFloat(temp_vat_rate[1]), parseFloat(item.price)) * quantity_order)+'"/>'
				
				+			'<input type="hidden" id="cart_prod_price'+item.id+unique_id+'" value="'+item.price+'"/>'
				+			'<input type="hidden" id="cart_prod_total'+item.id+unique_id+'" value="'+(item.price * quantity_order)+'" class="cart_prod_price'+i+'"/>'
				+		'</td>'
				
				+		'<td><img class="head_img" src="/upload/products/'+name+'_tiny'+extension+'" alt="'+URLDecode(item.name)+'"/></td>'
				+		'<td>'+URLDecode(item.name)+'</td>'
				+		quantity_input
				+		'<td id="configs_holder'+item.id+unique_id+'"></td>'
				+		'<td>&#8364; '+number_format(priceInclusive(parseFloat(temp_vat_rate[1]),parseFloat(item.price)), 2, ',', '')+'</span></td>'
				+		'<td>&#8364; <span id="cart_prod_visible_total'+item.id+unique_id+'">'+number_format(priceInclusive(parseFloat(temp_vat_rate[1]), parseFloat(item.price) * quantity_order), 2, ',', '')+'</span></td>'
				+		'<td>'
				+			'<img src="img/site/remove.png" alt="" onclick="removeFromCart(\''+item.id+'^'+unique_id.replace(/-/g, '~')+'\',\'cart\')" style="cursor:pointer;"/>'
				+		'</td>'
				+	'</tr>'
			);
			
			jQuery.each(item.configs, function(c,config)
			{
				//'<select class="cart_config '+item.id+' '+item.config_id+'" id="cart_prod_config'+item.id+item.config_id+'"></select>'				
				
				// For each parent config create a new select box
				jQuery('#configs_holder'+item.id+unique_id).append
				(
					'<select class="cart_config '+item.id+' '+unique_id+'" id="cart_prod_config'+item.id+config.id+unique_id+'"></select>'
				);
				
				jQuery.each(config.children, function(cc, child)
				{
					// For each child append the options to the parent select box
					jQuery('#cart_prod_config'+item.id+child.parent_id+unique_id).append
					(
						'<option value="'+child.id+'" '+(in_array(child.id, item.selected_config) ? 'SELECTED' : '')+'>'+child.name+'</option>'
					);
				 	
				 	if(in_array(child.id, item.selected_config))
				 	{
						jQuery('#cart_prod_config'+item.id+child.parent_id+unique_id).addClass('ex'+child.id);
					}
				});
			});			
		});
		
		// Creates the cart footer (subtotal, shipping costs, small order, vat rates and the total amount)
		jQuery('#step1 tfoot').append
		(
				'<tr style="display:none;">'
			+		'<td colspan="4"></td>'
			+		'<td style="border-bottom: 1px solid #ccc;">Subtotaal:</td>'
			+		'<td colspan="2" style="border-bottom: 1px solid #ccc;">&#8364; <span id="cart_sub_total"></span></td>'
			+	'</tr>'
			/*
			+	'<tr>'
			+		'<td colspan="4"></td>'
			+		'<td>Verzend kosten:</td>'
			+		'<td colspan="2">&#8364; <span id="cart_shipping_costs" class="cart_prod_total"></span></td>'
			+	'</tr>'
			*/
			+	'<tr id="cart_small_order">'
			+		'<td colspan="4"><input type="hidden" value="'+small_order_limit+'"></td>'
			+		'<td>Kleine order <small>(< &#8364; '+parseInt(small_order_limit)+')</small>:</td>'
			+		'<td colspan="2">&#8364; <span class="cart_prod_total">'+number_format(small_order_charge, 2, ',', '')+'</span></td>'
			+	'</tr>'
			+	'<tr id="cart_tr_vat1">'
			+		'<td colspan="4"></td>'
			+		'<td>btw (6%):</td>'
			+		'<td colspan="2">&#8364; <span id="cart_vat1"></span></td>'
			+	'</tr>'
			+	'<tr id="cart_tr_vat2">'
			+		'<td colspan="4"></td>'
			+		'<td style="border-bottom: 1px solid #999;">btw (19%):</td>'
			+		'<td colspan="2" style="border-bottom: 1px solid #999;">&#8364; <span id="cart_vat2"></span></td>'
			+	'</tr>'
			+	'<tr style="font-weight: bold;">'
			+		'<td colspan="4"></td>'
			+		'<td>Te betalen:</td>'
			+		'<td colspan="2">&#8364; <span id="cart_total"></span></td>'
			+	'</tr>'
		);		
		
		// Loads the shipping methods
		/*
		jQuery.getJSON('/modules/shop/load.php?item=methods',function(data)
		{
			var last = data.length - 1;
			// Create and fill shipping method select		
			jQuery.each(data, function(i,item)
			{
				if(item.type == 'shipping_method' && i == 0)
				{
					jQuery('#cart_shipping_costs').html(number_format(item.price, 2, ',', ''));
				}
				if(i == last)
				{
					jQuery('#step1').append
					(
							'<input class="cart_button" type="button" value="Volgende" onclick="loadStep2()"/>'
						+	'<input class="cart_button" type="button" value="Annuleren" onclick="exitCheckout()"/>'
					);
			
					// Set the total for the whole cart
					calculateTotal('cart');
					
					jQuery('#ajax_loader').hide('fast');
				}
			});
		});
		*/
		
		jQuery('#step1').append
		(
				'<input class="cart_button" type="button" value="Volgende" onclick="loadStep2()"/>'
			+	'<input class="cart_button" type="button" value="Annuleren" onclick="exitCheckout()"/>'
		);

		// Set the total for the whole cart
		calculateTotal('cart');
		jQuery('#ajax_loader').hide('fast');
		
		
		
		// Handles the onchange event of the config select boxes
		jQuery('.cart_config').change(function()
		{
			var id = jQuery(this).attr('class').split(' ');
			
			var conf_ids = id[2].replace(/-/g, '~');
			
			// Remove the item from the cart
			jQuery.post('/modules/shop/load.php?item=cart&action=remove&product_id='+id[1]+'^'+conf_ids,'');
			
			conf_ids = conf_ids.replace(id[3].replace('ex',''), jQuery(this).val());
			
			// Set the item to the cart again (with different config id)
			addToCart(id[1]+'^'+conf_ids, jQuery('#cart_quantity'+id[1]+id[2]).val());
			
			loadTinyCart();
			initCheckout();
		});		
		
		// Handles the onchange event on the quantity fields
		jQuery('.cart_quantity').change(function()
		{
			var split = jQuery(this).attr('name').split('~');
			var in_stock = parseInt(split[0]);
			var product_id = split[1];
			var config_id = split[2].replace(/-/g, '~');
			var quantity = parseInt(jQuery(this).val());
			
			// When the quantity of a product is changed check if the value is 0
			if(quantity == 0)
			{
				// If the value is 0, remove the product from the shopping cart
				customAlert('Als u het product wilt bestellen, moet het te bestellen aantal minimaal 1 bedragen.');
				jQuery(this).val(1);
			}
			else
			{
				// Checks if the stock for the product is sufficient, if not a message will be shown about delivery
				if(quantity > in_stock)
				{
					if(in_stock < 0)
					{
						customAlert('Er zijn momenteel 0 stuks voorradig. Het restant wordt zo snel mogelijk nageleverd of pas uw bestelling aan.','button');
					}
					else
					{
						customAlert('Er zijn momenteel '+in_stock+' stuks voorradig. Het restant wordt zo snel mogelijk nageleverd of pas uw bestelling aan.','button');
					}
				}
				
				// If the value is not 0, save the new quantity
				addToCart(product_id+'^'+config_id, 'absolute'+quantity);
				
				var tempstring = jQuery('#cart_prod_price'+product_id+split[2]).val();
				// Set a new total price for the product
				jQuery('#cart_prod_total'+product_id+split[2]).val
				(
					quantity * tempstring.replace(',','.')
				);
				
				jQuery('#cart_prod_visible_total'+product_id+split[2]).html
				(
					number_format(quantity * jQuery('#cart_prod_vat'+product_id+split[2]).val(), 2, ',', '')
				);
				
				// Calculate and set the new total price for the product including the vat rate
				jQuery('#cart_prod_vat_total'+product_id+split[2]).val
				(
					quantity * jQuery('#cart_prod_vat'+product_id+split[2]).val()
				);
				
				// Set a new total amount for the whole cart as well
				calculateTotal('cart');
			}
		});
		
		checkout_loaded = true;
	});
}

function loadStep2()
{
	showAjaxLoader(1);
	var continue_function = true;
	
	// Create an array item for each product in checkout_cart prod[product_id]=quantity
	jQuery('.cart_quantity').each(function()
	{
		var split = jQuery(this).attr('name').split('~');
		if(split[2] == 'none')
		{
			continue_function = false;
			return false;
		}
	});
	
	if(continue_function)
	{
		jQuery('#step1').hide();
		jQuery('#step3').hide();
		jQuery('#step2').fadeIn();
		
		jQuery('#step_image3').css('background-position','-300px -486px');
		jQuery('#step_image2').css('background-position','-150px -466px');
		
		jQuery('#stepLink1 .stepLinksmall').css('font-size','9px').css('text-decoration','none');
		jQuery('#stepLink2 .stepLinksmall').css('font-size','11px').css('text-decoration','underline');
		
		if(!jQuery('#order_logged_in').exists())
		{
			jQuery('#step2').load('modules/shop/order/customer.php',function()
			{
				jQuery('#ajax_loader').hide('fast');
			});
		}
		else
		{
			jQuery('#ajax_loader').hide('fast');
		}
	}
	else
	{
		jQuery('#ajax_loader').hide('fast');
		customAlert("Er is een product dat nog geconfigureerd moet worden.");
		loadStep1();
	}
}

function loadStep3(user_id,callback)
{
	showAjaxLoader(1);
	
	// Clear the style of step 2 and switch the backgrounds
	jQuery('#step2').hide();
	jQuery('#step4').hide();
	jQuery('#step3').fadeIn();
	
	jQuery('#stepLink2 .stepLinksmall').css('font-size','9px').css('text-decoration','none');
	jQuery('#stepLink4 .stepLinksmall').css('font-size','9px').css('text-decoration','none');	
	jQuery('#stepLink3 .stepLinksmall').css('font-size','11px').css('text-decoration','underline');
	
	jQuery('#step_image4').css('background-position','-448px -486px');
	jQuery('#step_image3').css('background-position','-300px -466px');
	
	jQuery.getJSON('/modules/shop/load.php?item=methods',function(data)
	{
		// Load the customer data for the customer info block
		jQuery.getJSON('/modules/shop/load.php?item=customer&id='+user_id,function(item)
		{
			if(typeof callback == 'undefined')
			{
				jQuery('#step3').html
				(
						'<input id="step3_user_id" type="hidden" value="'+user_id+'"/>'
					+	'<form id="step3_left" class="uniForm" style="width: 49% !important; float: left;">'
					+		'<fieldset class="inlineLabels" style="border-color: #70AFEF;">'
					+			'<div class="ctrlHolder" style="border-color: #70AFEF;">'
					+			'Opmerkingen of alternatief verzendadres:<br/>'
					+			'<textarea id="order_comments" style="color:#0053A6; font-size: 12px; font-family: Arial,Verdena,Helvetica,sans-serif; width: 100%;"></textarea>'
					+		'</div>'
					+		'<div class="ctrlHolder" style="border: none;">'
					+			'<b>Betaal methode:</b> <select id="payment_method_step3" style="color:#0053A6; font-size: 12px;"></select><br/><br/>'
					+			'Voor rembourszendigen wordt &euro; 20,- extra in rekening gebracht. De overige betaalmethoden zijn gratis, u betaalt alleen uw order.'
					+		'</div>'
					+		'</fieldset>'
					+	'</form>'
					+	'<form id="step3_right" class="uniForm" style="width: 49% !important; float: right;">'
					+		'<fieldset class="inlineLabels" style="border-color: #70AFEF;">'
					+			'<div class="ctrlHolder" style="border-color: #70AFEF;">'
					+				'<b>Uw gegevens (<a href="javascript:void(0);" onclick="enableCustomerField();loadStep2();" style="color:#0079F2; text-decoration:none; font-weight:normal;">aanpassen</a>):</b><br/>'
					+				'<div style="padding-left: 10px;">'
					+					URLDecode(item.name)+'<br/>'
					+					ucwords(URLDecode(item.data[0][1]))+'<br/>'
					+					URLDecode(item.data[0][2])+' '+ucwords(URLDecode(item.data[0][3]))+'<br/>'
					+					URLDecode(item.data[0][4])+'<br/>'
					+					item.data[0][5]
					+				'</div>'
					+			'</div>'
					+			'<div class="ctrlHolder" style="border-color: #70AFEF;">'
					+				'<b>Te betalen:</b> &#8364; <span id="pay_meth_total">'+jQuery('#cart_total').html()+'</span>'
					+			'</div>'
					+		'</fieldset>'
					+	'</form>'
					+	'<form class="uniForm" style="width: 100% !important; clear: both;">'
					+		'<fieldset class="inlineLabels" style="border-color: #70AFEF;">'
					+			'<input id="place_order_button" class="cart_button" type="button" value="Plaats Bestelling" onclick="placeOrder('+user_id+');"/>'
					+			'<input class="cart_button" type="button" value="Vorige" onclick="loadStep2()"/>'
					+		'</fieldset>'
					+	'</form>'
				);
			}
			else
			{
				callback();
			}
			
			// Create and fill shipping method select
			/*
			jQuery('#shipping_step3').html('Verzend methode: <select id="shipping_method_step3"></select>');		
			jQuery.each(data, function(i,item)
			{
				if(item.type == 'shipping_method')
				{
					jQuery('#shipping_method_step3').append('<option value="'+item.id+'~'+item.price+'">'+ucwords(item.name)+'</option>');
				}
			});
			*/
							
			// Bind change event to shipping method select, and set the checkout_shipping price
			/*
			var shipping_value = jQuery('#shipping_method').val().split('~');
			jQuery('#checkout_shipping').html(shipping_value[1]);
			
			jQuery('#shipping_method').change(function()
			{
				shipping_value = jQuery(this).val().split('~');
				jQuery('#checkout_shipping').html(shipping_value[1]);
				calculateTotal('checkout');
			});
			*/		
			
			// Fill payment method select
			jQuery.each(data, function(i,item)
			{
				if(item.type == 'payment_method')
				{
					jQuery('#payment_method_step3').append('<option value="'+item.id+'">'+item.name+'</option>');
				}
			});
		
			var selected_pay_method = 'ideal';
			
			jQuery('#payment_method_step3').change(function()
			{
				if((jQuery('#payment_method_step3 option:selected').text()).toLowerCase() == 'onder rembours')
				{
					jQuery('#pay_meth_total').html
					(
						number_format(parseFloat((jQuery('#pay_meth_total').html()).replace(',','.')) + 20, 2, ',', '')
					);
				}
				else if(selected_pay_method == 'onder rembours')
				{
					jQuery('#pay_meth_total').html
					(
						number_format(parseFloat((jQuery('#pay_meth_total').html()).replace(',','.')) - 20, 2, ',', '')
					);
				}
				
				selected_pay_method = (jQuery('#payment_method_step3 option:selected').text()).toLowerCase();
			});
			
			jQuery('#ajax_loader').hide('fast');
		});
	});
}

// Save the order to the database
function placeOrder(user_id, proceed, passed_order_id)
{
	showAjaxLoader(1);
	if(typeof proceed == "undefined")proceed = false;
	if(typeof passed_order_id == "undefined")passed_order_id = "";
	
	// If the customer wants to pay with iDeal, the payment must be fulfilled first.
	if((jQuery('#payment_method_step3 option:selected').text()).toLowerCase() == 'ideal' && !proceed)
	{
		// Create an array item for each product in checkout_cart prod[product_id]=quantity	
		var array = '';
		jQuery('.cart_quantity').each(function()
		{
			var split = jQuery(this).attr('name').split('~');
			// Fetches the vat_rate of the product
			var order_vat_rate = jQuery('#order_vat_rate'+split[1]+split[2]).val();
			
			array += '&prod['+split[1]+'~'+split[2].replace(/-/g, '~')+'~'+order_vat_rate+']='+jQuery(this).val();
		});
		
		// Id of the payment option
		var payment_meth = URLDecode(jQuery('#payment_method_step3').val());
		// Id of the shipping option
		//var shipping_meth = jQuery('#shipping_method_step3').val().split('~');
	 	
		// Get the order and get the order_id
		jQuery.post('/modules/shop/order/save.php?'+array,
		{
			order_id: '',
			customer_id: user_id,
			payment: payment_meth,
			//shipping: shipping_meth[0],
			extra: (jQuery('.small_order_hidden').exists() ? (0) : (small_order_charge)),
			order_comment: jQuery('#order_comments').val()},
			function(order_id)
			{		
				jQuery('#step3').prepend
				(
						'<form id="ideal_form" method="post">'
					+		'<div>'
					+			'<input type="hidden" id="merchantID" name="merchantID"/>'
					+			'<input type="hidden" id="subID" name="subID"/>'
					+			'<input type="hidden" id="amount" name="amount"/>'
					+			'<input type="hidden" id="purchaseID" name="purchaseID"/>'
					+			'<input type="hidden" id="language" name="language"/>'
					+			'<input type="hidden" id="currency" name="currency"/>'
					+			'<input type="hidden" id="description" name="description"/>'
					+			'<input type="hidden" id="hash" name="hash"/>'
					+			'<input type="hidden" id="paymentType" name="paymentType"/>'
					+			'<input type="hidden" id="validUntil" name="validUntil"/>'
					+			'<input type="hidden" id="urlSuccess" name="urlSuccess"/>'
					+			'<input type="hidden" id="urlCancel" name="urlCancel"/>'
					+			'<input type="hidden" id="urlError" name="urlError"/>'
					+			'<input type="hidden" id="itemNumber1" name="itemNumber1" value="1"/>'
					+			'<input type="hidden" id="itemDescription1" name="itemDescription1"/>'
					+			'<input type="hidden" id="itemQuantity1" name="itemQuantity1" value="1"/>'
					+			'<input type="hidden" id="itemPrice1" name="itemPrice1"/>'
					+		'</div>'
					+	'</form>'
				);		
				
				var merchantID = '005014636';									// AcceptantID
				var subID = '0';												// Vrijwel altijd 0 (nul)
				var purchaseID = order_id;										// Vrij veld - te gebruiken voor uw backoffice
				var paymentType = 'ideal'										// Altijd ideal
				var amount = (jQuery('#cart_total').html()).replace(',','');	// Totaal bedrag van de bestelling
				var validUntil = 0;												// Geldig tot ... waarde (geinitialiseerd op 0)
				var language = 'nl';											// Taal setting
				var currency = 'EUR';											// Valuta setting
				var description = 'bestelling van de Groef audio';				// Beschrijving		
				var urlBase = 'http://webshop.degroefaudio.nl';					// Basis site url
				var urlSuccess = urlBase + '?result=success&oid='+order_id+'&uid='+user_id;	// Success url
				var urlCancel = urlBase + '?result=cancel&oid='+order_id+'&uid='+user_id;	// Cancel url
				var urlError = urlBase + '?result=error&oid='+order_id+'&uid='+user_id;		// Error url
				var urlPost = 'https://ideal.secure-ing.com/ideal/mpiPayInitIng.do';	// Url to post the form to (action)
				
				// Create the valid until date-time
				var time = (new Date().getTime()/1000)+3600;	
				validUntil = date('Y-m-d',time)+'T'+date('G:i:s',time)+'Z';
				
				// Set the product price to the total order amount
				jQuery('#itemPrice1').val(amount);
				
				// Create the hash string out of all necessary assets
				var hashString =	merchantID
								+	subID
								+	amount
								+	purchaseID
								+	paymentType
								+	validUntil
								+	jQuery('#itemNumber1').val()
								+	purchaseID									// As itemDescription1
								+	jQuery('#itemQuantity1').val()
								+	jQuery('#itemPrice1').val();
			
				jQuery.get('/modules/shop/order/ideal.php',{hash_string: hashString},function(hash)
				{
					jQuery('#ideal_form').attr('action', urlPost);				// Set the form action
					
					// Set all the post values
					jQuery('#merchantID').val(merchantID);
					jQuery('#subID').val(subID);
					jQuery('#amount').val(amount);
					jQuery('#purchaseID').val(purchaseID);		
					jQuery('#itemDescription1').val(purchaseID);		
					jQuery('#language').val(language);
					jQuery('#currency').val(currency);
					jQuery('#description').val(description);
					jQuery('#hash').val(hash);
					jQuery('#paymentType').val(paymentType);
					jQuery('#validUntil').val(validUntil);
					jQuery('#urlSuccess').val(urlSuccess);
					jQuery('#urlCancel').val(urlCancel);
					jQuery('#urlError').val(urlError);
					
					// Trigger the form submit
					jQuery('#ideal_form').submit();
					
					jQuery('#ajax_loader').hide('fast');
				});
			}
		);
	}
	else
	{
		// Create an array item for each product in checkout_cart prod[product_id]=quantity	
		var array = '';
		jQuery('.cart_quantity').each(function()
		{
			var split = jQuery(this).attr('name').split('~');
			// Fetches the vat_rate of the product
			var order_vat_rate = jQuery('#order_vat_rate'+split[1]+split[2]).val();
			
			array += '&prod['+split[1]+'~'+split[2].replace(/-/g, '~')+'~'+order_vat_rate+']='+jQuery(this).val();
		});
		
		// Id of the payment option
		var payment_meth = URLDecode(jQuery('#payment_method_step3').val());
		// Id of the shipping option
		//var shipping_meth = jQuery('#shipping_method_step3').val().split('~');
	 	
		// Post the order
		jQuery.post('/modules/shop/order/save.php?'+array,
		{
			order: 'place',
			customer_id: user_id,
			payment: payment_meth,
			//shipping: shipping_meth[0],
			extra: (jQuery('.small_order_hidden').exists() ? (0) : (small_order_charge)),
			order_comment: jQuery('#order_comments').val(),
			id: passed_order_id},
			function()
			{
				jQuery('#ajax_loader').hide('fast');
				loadStep4(user_id);
			}
		);
	}
}

// Called from login of checkout
function loadStep4(user_id, ideal, order_id)
{
	if(typeof ideal == 'undefined')
	{
		ideal = false;
		order_id = false;
	}
	showAjaxLoader(1);
	
	jQuery('#step3').hide();
	jQuery('#step4').fadeIn();	
	
	jQuery('#stepLink3 .stepLinksmall').css('font-size','9px').css('text-decoration','none');
	jQuery('#stepLink4 .stepLinksmall').css('font-size','11px').css('text-decoration','underline');
	
	jQuery('#step_image4').css('background-position','-448px -466px');
	
	jQuery('#step4').html
	(
			'<div style="width: 100%; border: 1px solid #ccc; border-bottom: 0px; padding-top: 5px; padding-bottom: 5px;">'
		+		'<font style="font-size: 13px; font-weight: bold;">Uw bestelling is succesvol verzonden!</font><br/>'
		+		'Hieronder vindt u een overzicht van uw bestelling, ook hebben we u een bevestigings e-mail toegestuurd.'
		+	'</div>'
		+	'<div id="products_block" class="block">'
		+		'<table>'
		+			'<thead>'
		+				'<tr>'
		+					'<th>&#32;</th>'
		+					'<th>Product</th>'
		+					'<th>Aantal</th>'
		+					'<th>Optie</th>'
		+					'<th>Prijs</th>'
		+					'<th>Totaal</th>'
		+				'</tr>'
		+			'</thead>'
		+			'<tbody></tbody>'
		+			'<tfoot></tfoot>'
		+		'</table>'
		+	'</div>'
		+	'<div id="address_block" class="block"><table><tbody></tbody></table></div>'
		+	'<div id="shipping_method_block" class="block" style="display:none;"></div>'
		+	'<div id="payment_method_block" class="block"></div>'
	);
	
	jQuery.getJSON('/modules/shop/load.php?item=cart&action=load',function(data)
	{
		jQuery('#products_block tbody').html('');
		jQuery.each(data, function(i,item)
		{
			var split = item.img1.split('~')[0].split('.');
			var name = split[0];
			var extension = '.'+split[1];
			
			// Create a unique id based on the selected configs
			var unique_id = '';
			jQuery.each(item.selected_config, function(key, value)
			{
				if(value != '')
				{
					unique_id += value;
				}	
			});
			
			// Extracts the real vat rate (vat_id~vat_rate)
			var temp_vat_rate = item.vat_rate.split('~');
			
			jQuery('#products_block tbody').append
			(
					'<tr id="cart'+item.id+'" class="cart_row">'
				+		'<td><img class="head_img" src="/upload/products/'+name+'_tiny'+extension+'" alt="'+URLDecode(item.name)+'"/></td>'
				+		'<td>'+URLDecode(item.name)+'</td>'
				+		'<td>'+item.quantity+'</td>'
				+		'<td id="chk_configs_holder'+item.id+unique_id+'"></td>'
				+		'<td>&#8364; '+number_format(priceInclusive(parseFloat(temp_vat_rate[1]), parseFloat(item.price)), 2, ',', '')+'</td>'
				+		'<td>&#8364; '+number_format((priceInclusive(parseFloat(temp_vat_rate[1]), parseFloat(item.price)) * parseInt(item.quantity)), 2, ',', '')+'</td>'
				+	'</tr>'
			);
			
			jQuery.each(item.configs, function(c,config)
			{
				// For each parent config create a new select box
				jQuery('#chk_configs_holder'+item.id+unique_id).append
				(
					'<span id="checkout_prod_config'+item.id+config.id+unique_id+'"></span>'
				);
				
				jQuery.each(config.children, function(cc, child)
				{
					// Append the selected config option
					if(in_array(child.id, item.selected_config))
					{
						jQuery('#checkout_prod_config'+item.id+child.parent_id+unique_id).append(child.name);
					}
				});
			});			
		});
		
		jQuery('#products_block tfoot').append
		(
				'<tr style="display:none;">'
			+		'<td colspan="4"></td>'
			+		'<td style="border-bottom: 1px solid #ccc;">Subtotaal:</td>'
			+		'<td colspan="2" style="border-bottom: 1px solid #ccc;">&#8364; <span id="checkout_sub_total"></span></td>'
			+	'</tr>'
			/*
			+	'<tr>'
			+		'<td colspan="4"></td>'
			+		'<td>Verzend kosten:</td>'
			+		'<td colspan="2">&#8364; <span class="checkout_prod_total">'+jQuery('#cart_shipping_costs').html()+'</span></td>'
			+	'</tr>'
			*/
			+	'<tr id="checkout_small_order">'
			+		'<td colspan="4"><input type="hidden" value="'+small_order_limit+'"></td>'
			+		'<td>Kleine order <small>(< &#8364; '+parseInt(small_order_limit)+')</small>:</td>'
			+		'<td colspan="2">&#8364; <span class="checkout_prod_total">'+number_format(small_order_charge, 2, ',', '')+'</span></td>'
			+	'</tr>'
			+	'<tr id="payment_special" '+((jQuery('#payment_method_step3 option:selected').text()).toLowerCase() == 'onder rembours' ? '' : 'style="display:none;"')+'>'
			+		'<td colspan="4"><input type="hidden" value="20"></td>'
			+		'<td>Rembourskosten</td>'
			+		'<td colspan="2">&#8364; <span class="checkout_prod_total">'+number_format(20, 2, ',', '')+'</span></td>'
			+	'</tr>'
			+	'<tr id="checkout_tr_vat1">'
			+		'<td colspan="4"></td>'
			+		'<td>btw (6%):</td>'
			+		'<td colspan="2">&#8364; <span id="checkout_vat1" class="checkout_prod_total"></span></td>'
			+	'</tr>'
			+	'<tr id="checkout_tr_vat2">'
			+		'<td colspan="4"></td>'
			+		'<td style="border-bottom: 1px solid #999;">btw (19%):</td>'
			+		'<td colspan="2" style="border-bottom: 1px solid #999;">&#8364; <span id="checkout_vat2" class="checkout_prod_total"></span></td>'
			+	'</tr>'
			+	'<tr style="font-weight: bold;">'
			+		'<td colspan="4"></td>'
			+		'<td>Te betalen:</td>'
			+		'<td colspan="2">&#8364; <span id="checkout_total"></span></td>'
			+	'</tr>'
		);
		
		// Set the total for the whole cart
		calculateTotal('checkout');
	});
	
	if(jQuery('#order_comments').val() != '')
	{
		jQuery('#products_block').append
		(
				'<div id="comment_step4">'
			+		'<br/><br/><span style="font-weight:bold; color:#0E3F54;">Opmerkingen:</span><br/>'
			+		'<div id="order_comment_step4" style="width: 460px; border: 1px solid #ccc; margin-top: 3px; padding: 5px; overflow: hidden;">'
			+			jQuery('#order_comments').val()
			+		'</div>'
			+	'</div>'
		);
	}
	
	// Load the customer data into the address block
	jQuery.getJSON('/modules/shop/load.php?item=customer&id='+user_id,function(item)
	{
		jQuery('#address_block').prepend('<span style="font-weight:bold; color:#0E3F54;">Verzend Gegevens:</span>');
		jQuery('#address_block tbody').html('');		
		jQuery('#address_block tbody').append
		(
				'<tr><td>'+URLDecode(item.name)+'</td></tr>'
			+	'<tr><td>'+ucwords(URLDecode(item.data[0][1]))+'</td></tr>'
			+	'<tr><td>'+URLDecode(item.data[0][2])+'</td></tr>'
			+	'<tr><td>'+ucwords(URLDecode(item.data[0][3]))+'</td></tr>'
			+	'<tr><td>'+URLDecode(item.data[0][4])+'</td></tr>'
			+	'<tr><td>'+item.data[0][5]+'</td></tr>'
		);
		
		// After loading step 4, empty the shopping cart
		emptyCart('empty');
		jQuery('#ajax_loader').hide('fast');
	});
	
	// Set Payment option
	jQuery('#payment_method_block').html('Betaal methode: <span id="payment_method_step4" style="font-weight:normal;">'+jQuery('#payment_method_step3 :selected').text()+'</span>');
	
	// Add 'exit' button
	jQuery('#step4').append
	(
			'<div class="buttonHolder" style="border-color: #70AFEF; clear:both;">'
		+		'<a href="/"><input class="cart_button" type="button" value="Afsluiten"/></a>'
		+	'</div>'
	);
	
	if(ideal)
	{
		jQuery('#payment_method_step4').html('iDeal');
		jQuery.get('/modules/shop/load.php?item=order_comment&id='+order_id+'&customer_id='+user_id,function(order_comment)
		{
			if(order_comment != '')
			{
				jQuery('#order_comment_step4').html(URLDecode(order_comment));
			}
			else
			{
				jQuery('#comment_step4').hide();
			}
		});
	}
}

// Recieved an ideal error. Hide content of the steps (incl buttons), show error message and show a exit button.
function idealError()
{
	jQuery('#step3').html
	(
			'<div style="width:100%; text-align:center; font-size:15px; padding:10px;">'
		+		'Er is een fout opgetreden tijdens het afhandelen van uw iDeal betaling.<br/>'
		+		'<a href="/"><input style="float:none;" class="cart_button" type="button" value="Afsluiten"/></a>'
		+	'</div>'
	);
}

// Order id cancelled, remove created order_id
function orderCancel(order_id)
{
	jQuery.post('/modules/shop/order/remove.php',{id: order_id},function(){});
}

// Function that calculates the total amount of the cart/checkout_cart
function calculateTotal(location)
{
	// Set a new subtotal amount for the whole cart
	var cart_total = 0;
	var cart_sub_total = 0;
	var vat1 = 0;
	var vat2 = 0;
	
	jQuery('.cart_vat'+vat_rate1).each(function(i)
	{
		var price = jQuery('.cart_prod_price'+i).val();
		price = price.replace(',','.');
		
		var amount = jQuery(this).val().replace(',','.') - parseFloat(price);
		vat1 += amount;
	});
	jQuery('#'+location+'_vat1').html(number_format(vat1, 2, ',', ''));
	if(vat1 == 0)
	{
		jQuery('#'+location+'_tr_vat1').hide();
	}
	
	jQuery('.cart_vat'+vat_rate2).each(function(i)
	{
		var price = jQuery('.cart_prod_price'+i).val();
		price = price.replace(',','.');
		
		var amount = number_format(jQuery(this).val().replace(',','.'), 2, '.', '') - parseFloat(price);
		vat2 += amount;
	});
	jQuery('#'+location+'_vat2').html(number_format(vat2, 2, ',', ''));
	if(vat2 == 0)
	{
		jQuery('#'+location+'_tr_vat2').hide();
	}
	
	// Get the total amount (exl. VAT) for each product and add it to the cart subtotal
	jQuery('.cart_prod_sub_total').each(function()
	{
		var prodSubTotal = jQuery(this).val();
		prodSubTotal = prodSubTotal.replace(',','.');
		
		cart_sub_total += parseFloat(prodSubTotal);
	});
	
	// Get the total amount (exl. VAT) for each product and add it to the cart subtotal
	jQuery('.cart_prod_total').each(function()
	{
		var prodTotal = 0;
		
		if(jQuery(this).is(':input')) prodTotal = jQuery(this).val();
		else prodTotal = jQuery(this).html();
		
		prodTotal = prodTotal.replace(',','.');
		cart_total += parseFloat(prodTotal);
	});
	
	/*
	var shipping_costs = jQuery('#cart_shipping_costs').html();	
	shipping_costs = parseFloat(shipping_costs.replace(',','.'));
	*/
	
	// Handles the small order costs
	small_order_value = parseFloat(jQuery('#cart_small_order').find('input').val());
		
	if(cart_sub_total > small_order_value)
	{
		jQuery('#'+location+'_small_order').hide().addClass('small_order_hidden');
		cart_total -= small_order_charge;
	}
	else
	{
		jQuery('#'+location+'_small_order').show().removeClass('small_order_hidden');
	}
	
	// If payment method is 'onder rembours' it costs 20,- extra 
	if(location == 'checkout' && (jQuery('#payment_method_step3 option:selected').text()).toLowerCase() == 'onder rembours')
	{
		cart_total += 20;
	}
	
	// Set the total amount
	jQuery('#'+location+'_total').html(number_format(cart_total, 2, ',', ''));
	jQuery('#'+location+'_sub_total').html(number_format(cart_sub_total, 2, ',', ''));
}

// Load the small shopping cart
function loadTinyCart()
{
	var cart_quantity = 0;
	var cart_total = 0;
	var shipping = 0;
	
	cart_total_excl = 0;
	jQuery.getJSON('/modules/shop/load.php?item=cart&action=load',function(data)
	{
		jQuery.getJSON('/modules/shop/load.php?item=methods',function(jdata)
		{
			var last = jdata.length - 1;
				
			jQuery.each(jdata, function(j,jtem)
			{
				if(jtem.type == 'shipping_method' && j == 0)
				{
					//shipping = parseFloat(jtem.price);
				}
				if(j == last)
				{
					jQuery.each(data, function(i,item)
					{
						var temp_vat_rate = item.vat_rate.split('~');
						
						cart_quantity += parseInt(item.quantity);
						cart_total_excl += parseFloat(item.price) * parseInt(item.quantity);
						cart_total += (priceInclusive(temp_vat_rate[1], item.price) * parseInt(item.quantity));
					});
					
					if(round_float(cart_total,2) == false)
					{
						// No product set
						jQuery('#tiny_total').hide();
						jQuery('#tiny_total_title').hide();
						
						jQuery('#cart_quantity').hide().removeClass().addClass('hidden_q');
						jQuery('#cart_footer').hide();
						jQuery('#cart_hidden').show();
					}
					else
					{
						if(cart_total_excl < small_order_limit)
						{
							cart_total += small_order_charge;
						}
						cart_total += shipping;
						
						// There is a product
						jQuery('#cart_hidden').hide();			
						jQuery('#cart_quantity td:last').html(cart_quantity);
						jQuery('#tiny_total').html('&#8364; '+number_format(cart_total, 2, ',', ''));
						
						if(jQuery('.hidden_q').exists())
						{
							jQuery('#tiny_total').show();
							jQuery('#tiny_total_title').show();
							
							jQuery('#cart_quantity').show().removeClass();				
							jQuery('#cart_footer').show();
						}
					}					
				}
			});
		});
	});
}

// Add a product to the shopping cart
function addToCart(product_id, quantity, array, callback, proceed)
{
	if(typeof callback == "undefined")callback = function(){};
	if(typeof proceed == "undefined")proceed = false;
	
	if(proceed)
	{
		if(typeof array == "undefined" || array == '')
		{
			// Add a single product with it's quantity to the shopping cart. If the product allready is in the
			// shoppingcart increase the quantity.
			jQuery.post('/modules/shop/load.php?item=cart&action=add&product_id='+product_id+'&quantity='+quantity,'',function()
			{
				callback();
				loadTinyCart();
			});
		}
		else
		{
			// Add a array of products and an absolute quantity to the shopping cart. If the product allready is in
			// the shoppingcart it will get the new absolute quantity
			var url_array = '';
			for(key in array)
			{
				url_array += '&prod['+key+']='+array[key];
			}
			jQuery.post('/modules/shop/load.php?item=cart&action=add_array'+url_array,'',function()
			{
				callback();
				loadTinyCart();
			});
		}
	}
	else
	{
		if(product_id.indexOf('~') == -1)
		{
			jQuery.getJSON('/modules/shop/load.php?item=configs&id='+product_id.split('^')[0],function(data)
			{
				jQuery.each(data, function(c,config)
				{
					var child_config = config.children[0];
					product_id += '~'+child_config.id;
				});
				addToCart(product_id, quantity, array, callback, true);
			});
		}
		else
		{
			addToCart(product_id, quantity, array, callback, true);
		}
	}
}

// Remove a product from the shopping cart
function removeFromCart(product_id, location, message)
{
	if(typeof message == "undefined")message = 'Weet u zeker dat u dit product wilt verwijderen?';
	//if(confirm(message)){}
	
	jQuery.post('/modules/shop/load.php?item=cart&action=remove&product_id='+product_id,'',function()
	{
		initCheckout();
		loadTinyCart();
	});
}

// Empty the whole shopping cart
function emptyCart(message)
{
	if(typeof message == "undefined")
	{
		if(confirm('Are you sure you want to empty your shopping cart?'))
		{
			jQuery.post('/modules/shop/load.php?item=cart&action=empty','',function()
			{
				initCheckout();
				loadTinyCart();
			});
		}
	}	
	else
	{
		jQuery.post('/modules/shop/load.php?item=cart&action=empty','',function()
		{
			loadTinyCart();
		});
	}
}

// Function that rounds float to n decimals
function round_float(x,n)
{
	if(!parseInt(n))
		var n=0;
	if(!parseFloat(x))
		return false;
	return Math.round(x*Math.pow(10,n))/Math.pow(10,n);
}

function date(format, timestamp)
{
    var that = this,
        jsdate = (        (typeof timestamp === 'undefined') ? new Date() : // Not provided
        (timestamp instanceof Date) ? new Date(timestamp) : // Javascript Date()
        new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
    ), //, tal= [], // Keep this here (works, but for code commented-out below for file size reasons)
        formatChr = /\\?([a-z])/gi,        formatChrCb = function (t, s) {
            return f[t] ? f[t]() : s;
        },
        _pad = function (n, c) {
            if ((n = n + "").length < c) {                return new Array((++c) - n.length).join("0") + n;
            } else {
                return n;
            }
        },        txt_words = ["Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
        "January", "February", "March", "April", "May", "June", "July",
        "August", "September", "October", "November", "December"],
        txt_ordin = {1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st"},
        f = {        // Day
            d: function () {
                return _pad(f.j(), 2);
            },
            D: function () {                return f.l().slice(0, 3);
            },
            j: function () {
                return jsdate.getDate();
            },            l: function () {
                return txt_words[f.w()] + 'day';
            },
            N: function () {
                return f.w() || 7;            },
            S: function () {
                return txt_ordin[f.j()] || 'th';
            },
            w: function () {                return jsdate.getDay();
            },
            z: function () {
                return (jsdate - new Date(f.Y(), 0, 1)) / 864e5 >> 0;
            }, 
        // Week
            W: function () {
                var c = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3);
                return 1 + Math.round((c - (new Date(c.getFullYear(), 0, 4))) / 864e5 / 7);            },
 
        // Month
            F: function () {
                return txt_words[6 + f.n()];            },
            m: function () {
                return _pad(f.n(), 2);
            },
            M: function () {                return f.F().slice(0, 3);
            },
            n: function () {
                return jsdate.getMonth() + 1;
            },            t: function () {
                return (new Date(f.Y(), f.n() + 1, 0)).getDate();
            },
 
        // Year
			L: function () {
                var y = f.Y();
                return (!(y & 3) && (y % 1e2 || !(y % 4e2))) ? 1 : 0;
            },
            o: function () {                return f.Y() + (f.n() === 12 && f.W() < 9 ? -1 : (f.n() === 1 && f.W() > 9 ? 1 : 0));
            },
            Y: function () {
                return jsdate.getFullYear();
            },            y: function () {
                return (jsdate.getFullYear() + "").slice(2);
            },
 
        // Time
			a: function () {
                return jsdate.getHours() > 11 ? "pm" : "am";
            },
            A: function () {
                return f.a().toUpperCase();            },
            B: function () {
                return _pad(Math.floor(((jsdate.getUTCHours() * 36e2) + (jsdate.getUTCMinutes() * 60) +
                                        jsdate.getUTCSeconds() + 36e2) / 86.4) % 1e3, 3);
            },            g: function () {
                return jsdate.getHours() % 12 || 12;
            },
            G: function () {
                return jsdate.getHours();            },
            h: function () {
                return _pad(f.g(), 2);
            },
            H: function () {                return _pad(f.G(), 2);
            },
            i: function () {
                return _pad(jsdate.getMinutes(), 2);
            },            s: function () {
                return _pad(jsdate.getSeconds(), 2);
            },
            u: function () {
                return _pad(jsdate.getMilliseconds() * 1000, 6);            },
 
        // Timezone
            e: function () {
				//The following works, but requires inclusion of the very large timezone_abbreviations_list() function svar abbr='', i=0;
                /*
				if (that.php_js && that.php_js.default_timezone) {
                    return that.php_js.default_timezone;
                }
                if (!tal.length) {                    tal = that.timezone_abbreviations_list();
                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {                            return tal[abbr][i].timezone_id;
                        }
                    }
                }
                */
				return 'UTC';
            },
            I: function () {
                // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
                // If they are not equal, then DST is observed.                return 0 + (((new Date(f.Y(), 0)) - Date.UTC(f.Y(), 0)) !== ((new Date(f.Y(), 6)) - Date.UTC(f.Y(), 6)));
            },
            O: function () {
                var a = jsdate.getTimezoneOffset();
                return (a > 0 ? "-" : "+") + _pad(Math.abs(a / 60 * 100), 4);            },
            P: function () {
                var O = f.O();
                return (O.substr(0, 3) + ":" + O.substr(3, 2));
            },            T: function () {
 
// The following works, but requires inclusion of the very large timezone_abbreviations_list() function
/*                var abbr='', i=0;
                if (!tal.length) {                    tal = that.timezone_abbreviations_list();
                }
                if (that.php_js && that.php_js.default_timezone) {
                    for (abbr in tal) {
                        for (i=0; i < tal[abbr].length; i++) {                            if (tal[abbr][i].timezone_id === that.php_js.default_timezone) {
                                return abbr.toUpperCase();
                            }
                        }
                    }                }
                for (abbr in tal) {
                    for (i=0; i < tal[abbr].length; i++) {
                        if (tal[abbr][i].offset === -jsdate.getTimezoneOffset()*60) {
                            return abbr.toUpperCase();                        }
                    }
                }
*/
                return 'UTC';            },
            Z: function () {
                return -jsdate.getTimezoneOffset() * 60;
            },
         // Full Date/Time
            c: function () {
                return 'Y-m-d\\Th:i:sP'.replace(formatChr, formatChrCb);
            },
            r: function () {                return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
            },
            U: function () {
                return Math.round(jsdate.getTime() / 1000);
            }        };
    return format.replace(formatChr, formatChrCb);
}