/*
 *  \author 		@ide-info <contact@ai-dev.fr>
 *  \copyright  	2011 @ide-info
 *  \license		Read the multi-language license file (license.txt)
 *
 *  \file 			includes/functions.js
 *  \brief			Javascript functions file for ai_multi-dimensions module
 * 
 *  \package		aimultidimensions
 *  \version		0.87
 */

var product_price = 0;
var base_product_price = 0;
var quantity_reduction = 1;
var surface_reduction = 1;
var attributes_price = 0;
var product_taxe_type = 0; 

$(document).ready(function(){
	//	Display default combination
	if (  typeof(default_combination_id) != 'undefined' )
		displayDefaultCombination();
	
	//	Add input for linked products
	for (var cpt = 0; cpt < default_dimensions.length; cpt ++)
	{
		if ( $('select#group_' + default_dimensions[cpt][0]).size() )
		{
			$('select#group_' + default_dimensions[cpt][0]).hide();
			$('select#group_' + default_dimensions[cpt][0]).before('<input type="text" id="value_' + default_dimensions[cpt][0] + '" value="" size="3" maxlength="4" class="text ai_multi_dimensions" />');
			
			//	Set the legend for the limit
			for (var cpt_limits = 0; cpt_limits < limits.length; cpt_limits ++)
			{
				if ( limits[cpt_limits][0] == default_dimensions[cpt][0] )
				{
					if ( limit_placement )
						$('select#group_' + default_dimensions[cpt][0]).parent().append('<span class="center ai_multi_dimensions_legend">(' + limits[cpt_limits][3] + ')</span>');
					else
						$('select#group_' + default_dimensions[cpt][0]).parent().after('<p><span class="center ai_multi_dimensions_legend">(' + limits[cpt_limits][3] + ')</span></p>');
				}
			}

			$('select#group_' + default_dimensions[cpt][0]).addClass('ai_multi_dimensions');
			$('select#group_' + default_dimensions[cpt][0]).removeAttr('onchange');	
			$('select#group_' + default_dimensions[cpt][0] + ' OPTION').each(function() {
				$(this).remove();
			});
			$('select#group_' + default_dimensions[cpt][0]).html('<option value="" selected="selected">Choice</option>');
		}
	}
	
	//	Set the taxe rate (if ever the customer is in a group doesn't display taxes)
	if ( typeof(taxRate) != 'undefined' )
		product_taxes_rate = taxRate * product_taxes_type;
	
	//	If no taxes for this product, set it to 0
	if ( typeof(noTaxForThisProduct) != 'undefined' && noTaxForThisProduct )
		product_taxes_rate = 0;
	
	//	Changes if multidimensions parameters exist
	if ( $('#attributes select.ai_multi_dimensions').size() )
	{		
		//	Add the availability informations
		$('span#availability_label').after('<input type="hidden" id="base_dir_url" value="' + baseDir + '" /><span id="availability_text" class="warning_inline">' + availability_informations_message + '</span>');
		
		//	Remove onchange on other selects
		$('div#attributes SELECT:not(.ai_multi_dimensions)').each(function() {
			$(this).removeAttr('onchange');	
		});
		
		
/****************************************************************************************************************************************/		
				$('#quantity_wanted_p').children('label').show();
				$('#quantity_wanted_p').children('input').show();
/****************************************************************************************************************************************/		

		//	Update cart button creation
		$('#attributes').append('<input type="button" id="ai_calculate" class="exclusive" value="' + calculate_button_label + '" style="margin: 10px auto;" />');
		
		
		
		//	Availability
		$('#availability_value').hide();
		$('#availability_statut').append($('#availability_text'));
		$('#availability_text').show();
		
		//	Click on selects for other parameters
		$('#attributes select:not(.ai_multi_dimensions)').change(function() {
			updateTarget(0, 0, 1);
		});
		
		//	Attributes changes
		$('#attributes input.ai_multi_dimensions').each(function() {
			$(this).keydown(function(){
				majButton();
			});
			$(this).change(function(){
				
				//	If dimension is not ok exit with alert
				if ( !testQuantity($(this).attr('id'), $(this).val()) )
				{
					alert(limit_error_message);
					$(this).val('');
				}
				else
				{
					//	Show quantity if needed
					showQuantity();

					//	update the target
					updateTarget($(this).attr('id'), $(this).val());
				}
			});
		});
		
		//	If quantity is changed, get the new price and display it
		$('input#quantity_wanted').change(function() {
			updatePrice();
		});

		//	Unit price display changes of id to be changed only when we want
		if ( $('#unit_price_display').size() )
			$('#unit_price_display').attr('id', 'ai_unit_price_display');

		//	Save the initial product price
		base_product_price = product_price = productPriceTaxExcluded * (1 + (product_taxes_rate / 100));  
		
		//	Show minimum charged surface message if needed
		if ( minimum_surface != 0 )
			$('input#ai_calculate').before('<p class="ai_minimum_surface_message">' + minimum_surface_message + ' ' + minimum_surface  + ' ' + minimum_surface_scale + '</p>');

		//	Calculate must be done on the first display
		setTimeout('calculateShow()', 600);
	}
	
	//	Combinations sort
	sortCombination();
});

function calculateShow()
{
	$('p#add_to_cart').hide('slow');
	$('p#availability_statut').show('slow');
	$('p#quantity_wanted_p').hide('slow');
}

/**
 * \brief	Find or create an attribute and if needed send the combination
 * \param	string Id of the target to update
 * \param	integer Value inputs by user
 * \param	boolean If 1, others parameters have called the methode
 * \retval 	void
 */
function updateTarget(target, value, others)
{
	//	If no linked attributs, exit 
	if ( !$('#attributes select.ai_multi_dimensions').size() )
		return true;

	//	Get the parameters
	var index = 0;
	var attr_2 = '-1';
	var attr_3 = '-1';
	$('#attributes select.ai_multi_dimensions').each(function() {

		//	if no parameters, create them
		if ( !target && !value )
		{
			if ( $(this).attr('id') )
				target = $(this).attr('id');
			value = $('#' + target.replace('group', 'value')).val();
		}

		//	Other attributes
		target = target.replace('value', 'group');
		if ( $(this).attr('id') != target && attr_2 == '-1' )
			attr_2 = $(this).val();
		else if ( $(this).attr('id') != target && attr_3 == '-1' )
			attr_3 = $(this).val();
	});

	//	Get the non-aimultidimensions parameters to create de combination
	var more = new Array();
	$('#attributes select:not(.ai_multi_dimensions)').each(function() {
		more.push($(this).val());
	});
	more = more.join('_');

	//	Send the request
	if ( location.href.indexOf($('#base_dir_url').val()) === 0 )  
	{
		if ( !others )
			others = 0;
		var token = encode('group=' + target + '&value=' + value + '&product=' + $('#product_page_product_id').val() + '&attr_2=' + attr_2 + '&attr_3=' + attr_3 + '&more=' + more + '&others=' + others);
		$.get($('#base_dir_url').val() + 'modules/aimultidimensions/includes/ajax.php?token=' + token, function(data) {
			var tabData = data.split('|');
			
			//	New combination
			if ( tabData.length > 1 )
			{
				//	Update the target with the attribute id
				$('select#' + target + ' option').val(tabData[0]);
				
				//	Make the array with all the parameters (without 
				var params = new Array(tabData[0]);
				for ($index = 9; $index < (tabData.length - 2) ; $index ++)
				{
					params.push(tabData[$index]);
				}
				
				//	Add the combination to javascript array
				addCombination(	parseInt(tabData[1]), params, parseInt(tabData[2]), parseFloat(tabData[3]).toFixed(6), tabData[4], tabData[5], tabData[6], parseFloat(tabData[7]), parseInt(tabData[8]));
				
				//	Combinations sort
				sortCombination();
			}
			else
			{
				if ( data.substr(0, 7) == 'Error->' )
					alert(data.substr(7));
				else if ( data.substr(0, 7) == 'Price->' )
				{
					attributes_price = parseFloat(data.substr(7));
					product_price = base_product_price + attributes_price;
				}
				else
				{
					var tabSub = data.split('@');
					$('select#' + target + ' option').val(tabSub[0]);
					attributes_price = parseFloat(tabSub[1]);
					product_price = base_product_price + attributes_price;
				}
			}
			
			//	Update squared or cubed price display
			if ( tabData.length > 1 )
			{
				surface_reduction = parseFloat(tabData[tabData.length - 1]);
				attributes_price = parseFloat(tabData[tabData.length - 2]);
				product_price = base_product_price + attributes_price;
			}

			//	Show the right combination if exists only if all dimensions are set
			var all_dimensions = true;
			$('#attributes input.ai_multi_dimensions').each(function() {
				if ( $(this).val() == '' )
					all_dimensions = false;
			});

			//	If at least one dimension is not set, don't show the combination
			if ( all_dimensions )
				setTimeout('showCombination()', 500);		
		});
	}
}

/**
 * \brief	Show the right combination after an ajax call
 * \retval 	void
 */
function showCombination()
{
	findCombination();

	//	If ok, hide the message
	if (!selectedCombination['unavailable'] && quantityAvailable > 0 && productAvailableForOrder == 1)
		$('#availability_statut').hide();

	//	Update price reduction
	updatePrice();
}

/**
 * \brief	Display or hide the add button
 * \retval 	void
 */
function majButton()
{
	$('#add_to_cart').hide();
	$('#availability_statut').show();
	$('#pQuantityAvailable').hide();
	$('#product_reference').hide();
}

/**
 * \brief	Find or create an attribute and if needed send the combination
 * \param	object Level limit (optional)
 * \retval 	string Text representation of the array
 * 
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
 */
function dump(arr,level)
{
	var dumped_text = '';
	if( !level )
		level = 0;
	
	//	The padding given at the beginning of the line.
	var level_padding = '';
	for( var j = 0; j < level + 1; j ++) 
		level_padding += '    ';
	
	if(typeof(arr) == 'object')	//	Array/Hashes/Objects
	{  
		for(var item in arr)
		{
			var value = arr[item];
			
			if(typeof(value) == 'object')	//	If it is an array
			{ 
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} 
			else
				dumped_text += level_padding + '"' + item + '" => "' + value + '"' + "\n";
		}
	} 
	else	//	Stings/Chars/Numbers etc.
		dumped_text = '===>' + arr + '<===(' + typeof(arr) + ')';

	return dumped_text;
}

//private property
var strings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

// public method for encoding
function encode(input)
{
	var returnString = '';
	var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
	var i = 0;

	input = utf8Encode(input);
	while (i < input.length)
	{
		chr1 = input.charCodeAt(i++);
		chr2 = input.charCodeAt(i++);
		chr3 = input.charCodeAt(i++);

		enc1 = chr1 >> 2;
		enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
		enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
		enc4 = chr3 & 63;

		if (isNaN(chr2))
			enc3 = enc4 = 64;
		else if (isNaN(chr3))
			enc4 = 64;

		returnString = returnString + strings.charAt(enc1) + strings.charAt(enc2) + strings.charAt(enc3) + strings.charAt(enc4);
	}

	return returnString;
}

// private method for UTF-8 encoding
function utf8Encode(string) 
{
	string = string.replace(/\r\n/g,"\n");
	var returnString = '';

	for (var n = 0; n < string.length; n++)
	{
		var c = string.charCodeAt(n);

		if (c < 128)
			returnString += String.fromCharCode(c);
		else if((c > 127) && (c < 2048))
		{
			returnString += String.fromCharCode((c >> 6) | 192);
			returnString += String.fromCharCode((c & 63) | 128);
		}
		else 
		{
			returnString += String.fromCharCode((c >> 12) | 224);
			returnString += String.fromCharCode(((c >> 6) & 63) | 128);
			returnString += String.fromCharCode((c & 63) | 128);
		}
	}

	return returnString;
}

/**
 * \brief	Display or hide the reference
 * \retval 	void
 */
function updateReference()
{
	var reference = '';
	
	//	If reference is empty, hide it
	if ( $('#product_reference span').size() )
		reference = $('#product_reference span').html().replace('\'\'', '');
	if ( reference == '' )
	{
		$('#product_reference span').html(reference);
		$('#product_reference').hide();
	}
}

/**
 * \brief	Change the price in squared or cubed meter
 * \retval 	void
 */
function updatePrice()
{
	//	Quantity reduction
	var quantity = parseInt($('input#quantity_wanted').val());
	var token = encode('product=' + $('#product_page_product_id').val() + '&quantity=' + quantity);
	$.get($('#base_dir_url').val() + 'modules/aimultidimensions/includes/ajax.php?token=' + token, function(data) {
		if ( data == '' )
			data = 0;
		quantity_reduction = 1 - parseFloat(data);

		//	Get the minimum charged surface
		var token = encode('action=mcs');
		$.get($('#base_dir_url').val() + 'modules/aimultidimensions/includes/ajax.php?token=' + token, function(data) {
			if ( parseFloat(data) != parseFloat(minimum_surface) )
				minimum_surface = parseFloat(data);
		});
		
		//	Surface reduction
		var dimension = 1;
		var dimension_tmp = 1;
		$('#attributes input.ai_multi_dimensions').each(function() {
			for (var cpt = 0; cpt < default_dimensions.length; cpt ++)
			{
				if ( default_dimensions[cpt][0] == $(this).attr('id').replace('value_', '') )
					dimension_tmp = dimension_tmp * ( parseFloat($(this).val()) / default_dimensions[cpt][1] );
			}
		});
		if ( !isNaN(dimension_tmp) )
		{
			//	Recalculate the surface with the quantity against the limit, the price will be changed only if the surface is even under the minimum charged surface
			if ( minimum_surface_on_quantity == 1 )
				surface_recalculated = quantity * dimension_tmp;
			else
				surface_recalculated = dimension_tmp;
			if ( surface_recalculated >= minimum_surface )
				dimension = dimension_tmp;
			else
				dimension = minimum_surface;
		}
		
		var reduction = 0;
		if ( !isNaN(dimension_tmp) )
		{
			var global_dimension = dimension;
			
			//	If global surface reduction, get the surface * quantity to calculate
			if ( parseInt(global_surface_reduction) == 1 )
				global_dimension *= quantity;	
			for (var cpt = 0; cpt < dimensions_reductions.length; cpt ++)
			{
				if ( dimensions_reductions[cpt][0] <= global_dimension )
					reduction = dimensions_reductions[cpt][1];
				else
					break;
			}
		}
		surface_reduction = 1 + (reduction / 100);

		//	If quantity > 1 and surface_recalculated < minimum_surface the dimension must by divided par quantity
		if ( minimum_surface_on_quantity == 1 && surface_recalculated < minimum_surface )
			dimension /= quantity;
		
		//	If selection is not set
		if ( selectedCombination['price'] !== undefined )
		{
			//	New price
			var new_price = product_price * surface_reduction * dimension;
			selectedCombination['price'] = new_price;
			
			//	We round the unit price with the Prestashop rules
			var display_price_tmp = new_price * quantity_reduction;
			$('#our_price_display').text(formatCurrency(parseFloat(display_price_tmp * quantity), currencyFormat, currencySign, currencyBlank));
			
			//	Update price in database
			var ajax_price = ((new_price - base_product_price) / (1 + (product_taxes_rate / 100))) / group_reduction;
			var token = encode('action=upp&product=' + $('#product_page_product_id').val() + '&quantity=' + quantity + '&attribute=' + $('#idCombination').val() + '&price=' + ajax_price);
			$.get($('#base_dir_url').val() + 'modules/aimultidimensions/includes/ajax.php?token=' + token, function(data) {
				//alert(data);
			});
		}

		//	If squared or cubed meter can be changed, let's do it
		if ( $('#ai_unit_price_display').size() )
			$('#ai_unit_price_display').text(formatCurrency(parseFloat(product_price * quantity_reduction * surface_reduction), currencyFormat, currencySign, currencyBlank));
	});

	//	Update display
	updateDisplay();

	//	Update reference display
	updateReference();
}

/**
 * \brief	Show / hide quantity input
 * \retval 	void
 */
function showQuantity()
{
	var all_dimensions = true;
	$('#attributes input.ai_multi_dimensions').each(function() {
		if ( $(this).val() == '' )
			all_dimensions = false;
	});
	
	if ( all_dimensions )
		$('p#quantity_wanted_p').show();
	else
		$('p#quantity_wanted_p').hide('slow');
}

/**
 * \brief	Check if a value is in the limits range
 * \param 	string Id of the control
 * \param 	integer Value for the dimension
 * \retval 	boolean Result of the check
 */
function testQuantity(id, value)
{
	id = parseFloat(id.replace('value_', ''));
	
	for(var cpt = 0; cpt < limits.length; cpt ++)
	{
		if ( parseFloat(limits[cpt][0]) == id )
		{
			if ( parseFloat(value) < parseFloat(limits[cpt][1]) || ( parseFloat(value) > parseFloat(limits[cpt][2]) && parseFloat(limits[cpt][2]) != 0) )
				return false;
		}
	}
	
	return true;
}

/**
 * \brief	Sort the combination list
 * \retval 	void
 */
function sortCombination()
{
	if ( typeof(combinations) != 'undefined' )
		combinations.sort(function(a,b){return b.idCombination - a.idCombination});
}

//	Tools function redeclaration (add the first line)
function formatCurrency(price, currencyFormat, currencySign, currencyBlank)
{
	price = parseFloat(price);
	
	// if you modified this function, don't forget to modify the PHP function displayPrice (in the Tools.php class)
	blank = '';
	price = parseFloat(price.toFixed(6));
	price = ps_round(price, priceDisplayPrecision);
	if (currencyBlank > 0)
		blank = ' ';
	if (currencyFormat == 1)
		return currencySign + blank + formatNumber(price, priceDisplayPrecision, ',', '.');
	if (currencyFormat == 2)
		return (formatNumber(price, priceDisplayPrecision, ' ', ',') + blank + currencySign);
	if (currencyFormat == 3)
		return (currencySign + blank + formatNumber(price, priceDisplayPrecision, '.', ','));
	if (currencyFormat == 4)
		return (formatNumber(price, priceDisplayPrecision, ',', '.') + blank + currencySign);
	return price;
}

/**
 * \brief	Display the default combination on start
 * \retval 	void
 */
function displayDefaultCombination()
{
	//	Searchibng for the default combination
	for (var combination = 0; combination < combinations.length; ++ combination)
	{
		if ( combinations[combination]['idCombination'] == default_combination_id )
		{
			selectedCombination['unavailable'] = false;
			selectedCombination['reference'] = combinations[combination]['reference'];
			$('#idCombination').val(combinations[combination]['idCombination']);

			//get the data of product with these attributes
			quantityAvailable = combinations[combination]['quantity'];
			selectedCombination['price'] = combinations[combination]['price'];
			selectedCombination['unit_price'] = combinations[combination]['unit_price'];
			if (combinations[combination]['ecotax'])
				selectedCombination['ecotax'] = combinations[combination]['ecotax'];
			else
				selectedCombination['ecotax'] = default_eco_tax;
			break;
		}
	}
	
	//	Update the display
	updateDisplay();
}

