var THUMBNAILS_OPACITY = 0.4;
var EXPANDED_COL_WIDTH = '62%';
var COLLAPSED_COL_WIDTH = '19%';
var DEFAULT_COL_WIDTH = '33%';
var MINIMUM_DESCRIPTION_HEIGHT = 40;
var PRODUCT_INFO_HEIGHT = 140; // 140 - height of the preview, minus paddings
var ANIMATION_SPEED = 2; // Bigger is slower and smoother :)
var ANIMATION_DELAY = 25; // Again: bigger is slower and smoother :)

var isAnythingMoving = false;
var default_product_width;
var previousRow;
var products = [];

String.prototype.reverse = function() {
	// gnirts eht esrever noitcnuf sihT
	var s = "";
	var i = this.length;
	while (i>0) {
			s += this.substring(i-1,i);
			i--;
	}
	return s;
}

String.prototype.str_replace = function(search, replace) {
	return this.split(search).join(replace);
}

String.prototype.reverseIndexOf = function(needle, offset) {
	// Same as indexOf (aka strpos) but in the reverse dirrection (starting from offset)
	var index = this.reverse().indexOf(needle, this.length - offset);
	return this.length - index;
}

String.prototype.trim = function(chars) {
	// Trims whitespace (plus additional chars if set) from string 
	re = new RegExp("(^[\\s"+chars+"]+)|([\\s"+chars+"]+$)", "g");
	return this.replace(re, "");
}

jQuery.fn.equalizeCols = function() {

	jQuery(this).filter(function() {return jQuery(this).find(".auto_fill").length == 0;}).each(function() {
		jQuery(this).prepend(jQuery("<div class='auto_fill'></div>").height(0));
	}).css("height", "auto");
	
	var max_height= 0;

	jQuery(this).each(function() {
		var self= jQuery(this);
		var height= self.height() - self.find(".auto_fill").height();
		max_height=height > max_height ? height : max_height;
	});

	jQuery(this).each(function() {
		var self= jQuery(this);
		var height= self.height() - self.find(".auto_fill").height();
		self.find(".auto_fill").height(max_height - height).css('font-size', 0);
	});
}

function getExponentialStep(value, desiredValue) {
	var difference = Math.max(value, desiredValue) - Math.min(value, desiredValue);
	step = 0;
	if (difference >= 2) {
		step = (desiredValue - value) / ANIMATION_SPEED;
	}
	return step;	
}

function startMoving() {

	if (!isAnythingMoving) {
		// Just started, need to close variant's select (if any opened)
		$("select").blur();
	}

	isAnythingMoving = true;

	if (window.products.length == 0) {
		var container = document.getElementById('products');
		var products1 = container.getElementsByTagName('DIV');
		for (i in products1) {
			element = products1[i];
			if (!element || !element.className || element.className.indexOf('product') == -1) {
				continue;
			}
			window.products[window.products.length] = element;
		}
	}
	
	var busyElements = 0;
	
	for (i in window.products) {
		element = window.products[i];

		desiredLeft = element.getAttribute('desiredLeft');
		if (desiredLeft == '') {
			continue;
		}
		
		fDesiredLeft = parseFloat(desiredLeft);

		var left = element.style.left;
		fLeft = parseFloat(left);
		
		if (!fLeft) {
			fLeft = element.getAttribute("defaultLeft");
		}
		
		var step = getExponentialStep(fLeft, fDesiredLeft);
		
		if (step != 0) {
			busyElements++;
			element.style.left = Number(fLeft) + Number(step) + "px";
		} else {
			
			element.style.left = desiredLeft;
			element.setAttribute("desiredLeft", "");
			
			if (element.className.indexOf('collapsing') > 0) {
				element.className = element.className.replace(" collapsing", "") + " collapsed";
			} else if (element.className.indexOf('expanding') > 0) {
				element.className = element.className.replace(" expanding", "") + " expanded";
			}
			
			// If unsupported variant was chosen - switch to default (attractive) variant
			if ($(".noprice:visible", element).length) {
				$("form", element).get(0).reset();
				$("form .variant_switcher", element).change();
			}
			
		}
		
	}

	if (busyElements > 0) {
		setTimeout(startMoving, ANIMATION_DELAY);
	} else {
		isAnythingMoving = false;
	}
	
}

function restoreOriginalState(product) {
	if (!product) {
		product = $("#products .product");
	}
	$(product).removeClass("collapsed").removeClass("expanded").each(function(){
		$(this).attr('desiredLeft', $(this).attr('defaultLeft'));
		$(".thumbnails", this).shadow();
		$(".info", this).animate({marginLeft: "160px"}, ANIMATION_SPEED*100);
		$(".preview", this).animate({width: "140px"}, ANIMATION_SPEED*200);
	});
	previousRow = null;
	startMoving();
}

$.fn.shadow = function() {
	return $(this)
		.animate({opacity: THUMBNAILS_OPACITY}, ANIMATION_SPEED*100)
		.data("shadowed", 1);
}

$.fn.reveal = function() {
	return $(this)
		.animate({opacity: 1}, 600)
		.data("shadowed", 0);
}

$.fn.count = function() {
	var result = 0;
	for (var i in this.get(0)) {
		result++;
	}
	return result;
}

function expandProduct(element) {

	$(element).parents(".row").add(previousRow).each(function(){
	
		var left = 0;
		
		$(".product", this).each(function(){
			
			var desiredWidth = parseFloat(DEFAULT_COL_WIDTH);
			
			if (this != element) {
				$(".thumbnails", this).shadow();
				$(".info", this).animate({marginLeft: "160px"}, ANIMATION_SPEED*100);
			}
			
			if (this == element) {
				
				previousRow = this.parentNode;
				
				// To be expanded ~60% width
				$(".thumbnails", this).reveal();
				$(".info", this).animate({marginLeft: 0}, ANIMATION_SPEED*100);
				$(this).removeClass("collapsing").addClass('expanding');
				desiredWidth = parseFloat(EXPANDED_COL_WIDTH);
				
			} else if (this.parentNode == element.parentNode) {
				// To be collapsed to ~20% width
				$(this).removeClass("expanding").addClass('collapsing');
				desiredWidth = parseFloat(COLLAPSED_COL_WIDTH);
			} else {
				// To be collapsed to ~33% width
				$(this).removeClass("expanding").addClass("collapsing");
			}
			
			if (this.parentNode == element.parentNode) {
				$(".preview", this).animate({width: "95px"}, ANIMATION_SPEED*200);
			} else {
				$(".preview", this).animate({width: "140px"}, ANIMATION_SPEED*200);
			}
			
			$(this).removeClass("expanded").removeClass("collapsed");
		
			desiredWidth = row_width * desiredWidth / 100;
			$(this).attr('desiredLeft', left);
			$(this).attr('desiredWidth', desiredWidth);
			left += desiredWidth;
			
		});
		
		
	});
	
	if (!isAnythingMoving) {
		startMoving();
	}
	
}

function getProductFooter(product, variant_id) {
	var price_block = $("#variant_" + variant_id, product);
	var product_variants = allVariants[product.attr("product_id")];
	if (!product_variants) return null;
	var product_variants_count = $(product_variants).count();
	if (price_block.length == 0) {
		var variant_data = product_variants[variant_id];
		if (variant_data) {
			button_tpl_id = "info_button_block";
			if (variant_data.is_purchasable) {
				button_tpl_id = "buy_button_block";
			}
			button_tpl = $("#" + button_tpl_id).html();
			template_id = "#product_footer";
			if (variant_data["price_negotiated"]) {
				template_id = "#product_negotiatable_footer";
			}
			footer = $(template_id).clone();
			//filling with data
			$(".controls", footer).html(button_tpl);
			$(".from", footer).html((product_variants_count > 1 && variant_data["is_attractive"]) ? I18N_TEXT_FROM : "");
			$(".prices", footer).html(variant_data["price"]);
			$(".stock", footer).html(variant_data["stock"]);
			$(".product_url", footer).attr("href", product.attr("href"));
		} else {
			footer = $("#product_unavailable").clone();
		}
		$(".block_id", footer).attr("id", "variant_" + variant_id);
		if ("not sovled http://dev.jquery.com/ticket/4691") {
			button = $(".buy_button", footer);
			$(".buy_button", footer).replaceWith("<input type='image' src='"+button.attr("src")+"' alt='"+button.attr("alt")+"' name=\""+'variants_values['+variant_id+']'+"\">")
			qty = $(".qty_field", footer);
			$(".qty_field", footer).replaceWith("<input type='text' size=3 value=1 name='product_qty["+variant_id+"]'>");
		}
		footer_html = footer.html();
		$(".footer", product).prepend(footer_html);
		price_block = $("#variant_" + variant_id, product);
	}
	return price_block;
}


$().ready(function(){

	$("td.manufacturer").each(function(){
		// Fixing rare IE6 weird zero width of <td> with dropdown (see #2417 note ~6126)
		if ($(this).width() < 10) {
			$(this).width(200);
		}
	});

	row_width = $("#products").width();
	expanded_product_width = row_width * parseFloat(EXPANDED_COL_WIDTH) / 100;

	$(".row").each(function(){
		$(".title h2", this).equalizeCols();
	});
	
	
	$(".thumbnails").each(function(){
		$("img:first", this).addClass("selected");
	});
	
	$("#products .product").mouseover(function(){
		if (!$(this).hasClass("expanded") && !$(this).hasClass("expanding")) {
			var product = this;
			$(".preview a", product).click(function(){
				$(this).unbind("click"); // 2nd click must open Product Info page
				expandProduct(product);
				return false;
			});
		}
	});
	
	$("#products .product").each(function(){
		var product_id = this.id.str_replace('product_', '');
		$(this).attr("product_id", product_id);
		$(this).attr("href", $(".url", this).attr("href"));
	});

	// Adding footer for each product (stock, price, buy/info button)
	$("#products .product").each(function(){
		var product_id = $(this).attr("product_id");
		var product_variants = allVariants[product_id];
		// First element is the most attractive one
		attractive_variant_id = 0;
		count = 0;
		for (var i in product_variants) { // how correctly to get the first one???
			count++;
			if (!attractive_variant_id)
			if (product_variants[i].is_attractive)
				attractive_variant_id = i;
		}
		// Delete old footer (generated on server)
		$(".footer", this).empty();
		// Create first advanced footer
		getProductFooter($(this), attractive_variant_id);
	});

	// Adding dropdowns for variants.
	// Must be added before optimizing description height (so dropdowns height could be excluded)
	$("#products .product").each(function(){
		var product_id = $(this).attr("product_id");
		var attributes = allAttributes[product_id];
		if (!attributes) {
			// There are no variants
			return;
		}
		html = '\n<table>';
		for (var i in attributes) {
			title = i;
			values = attributes[i];
			if (values.length == 1) {
				// When only one color - just print it, not in dropdown
				html += '<tr><td>'+title+'</td><td width="60%">' + values[0].value + '<input class="variant_switcher" type="hidden" value="'+values[0].vvid+'"></td></tr>';
			} else {
				html += '<tr><td>'+title+'</td><td width="60%">\n<select class="variant_switcher">\n';
				for (var j in values) {
					html += '<option value="'+values[j].vvid+'"' + (values[j].is_attractive ? ' selected="selected" ' : '') + '>'+ values[j].value+'</option>\n';
				}
				html += '</select></td></tr>';
			}
		}
		html += '</table>\n\n';
		$('.variants', this).html(html);
	});
	
	$("#products .product").each(function(){
		// Fixing width of the info box (before it will be cut in height)
		$(".data .info", this).width(expanded_product_width - 165); // TODO: Remove hard-code. 165 is a rest space: width of preview + width of smaller preview + all paddings.
	});
	
	// Making optimum height for description and variants of products.
	// Let description text fill every space which left from variants selectboxes
	$("#products .product").each(function(){
	
		var more_link = $(".info .more", this);
		var more_text = more_link.html();
		more_link.empty();
	
		var current_height, desired_height;
	
		current_height = $(".description", this).height();
		desired_height = Math.max(MINIMUM_DESCRIPTION_HEIGHT, PRODUCT_INFO_HEIGHT - $(".variants", this).height());
		
		element = $(".description", this);
		text = element.text();
		
		if (current_height > desired_height) {
			
			var difference = desired_height / current_height;
			position = text.reverseIndexOf(" ", (text.length * difference)); // trimmming to first space before cut position
			if (position > 0) {
				text = text.substr(0, position);
			}
			element.height("auto");
			
		} else if (desired_height - current_height < 20) {
			// If tnot very big difference (line or two) - let it go :) (besides "more info" link may give this extra line)
			element.height("auto");
		} else {
			// If it's almoust empty - fill the rest space with nothing, so selectboxes will be still alligned to the bottom
			element.height(desired_height);
		}
		
		element.html(text.trim('.') + "&hellip;<br>" + more_text);
		
		$(this).attr("defaultLeft", this.offsetLeft);
	
	});
	
	// Preparing products to be animated when needed
	// Nailing them to the absolute coordinates, freezing heights
	var defaultWidth = row_width * parseFloat(DEFAULT_COL_WIDTH) / 100;
	$("div.row").each(function(){
		var left = 0;
		$(this).css({
			height: $(this).height() + "px"
		});
		$(".product", this).each(function(){
			$(this).attr("defaultLeft", left);
			$(this).attr("defaultWidth", defaultWidth);
			$(this).attr("desiredLeft", "");
			$(this).css({
				left: left + "px",
				position: "absolute",
				width: parseInt(expanded_product_width) + "px"
			});
			left += defaultWidth;
		});
	});
	
	// Switching preview when hovering the thumbnail
	$(".thumbnails img").mouseover(function(){
		$("img", $(this).parent()).not(this).removeClass("selected");
		$(this).addClass("selected");
		$(".preview img:first", $(this).parents('.product')).attr('src', $(this).attr('longdesc')); // only the 1st image is a preview, there's also a "expand me" button
	});
	
	$(".product .close a").click(function(){
		restoreOriginalState();
		return false;
	});
	
	// Changing price when switching another variant
	$(".variant_switcher").change(function(){
		product = $(this).parents('.product');
		var price_block_id = $(this).parents(".product").attr("product_id");
		$(".variant_switcher", product).each(function(){
			price_block_id += '_' + this.value;
		});
		variant_id = revAttributes[price_block_id];
		price_block = getProductFooter(product, variant_id).hide();
		
		// Doing change effect
		$(".footer > *", product).not(price_block).slideUp('slow'); // Hiding old
		price_block.slideDown("slow"); // Showing new
		
	});
	
});
