	function dispatchGeoState( res ){		
				
		switch( res.data.sCity ){		
			case null:      break;
			case undefined: break;
			case -1: $("select#sCity").append('<option value="-1">&mdash;</option>'); break;
			default:			
				cities = res.data.sCity;			
				$("select#sCity").append('<option value="-1">' + reqSelectCity + '</option>');			
				$.each( cities , function(cityId , cityParams){				
					$("select#sCity").append('<option value="' + cityId + '">' + cityParams.name + '</option>');				
					if( cityParams.is_active == 0 ) { $("select#sCity option[value=" + cityId + "]").attr('disabled' , 'disabled').attr('class' , 'inactive'); }				
				});			
			break;
		}
		
		switch( res.data.sMStation ){		
			case null:        break;
			case undefined:   break;
			case -1: $("select#sMStation").append('<option value="-1">&mdash;</option>');  break;
			default:			
				mStations = res.data.sMStation;			
				$("select#sMStation").append('<option value="-1">' + reqSelectMStation + '</option>');			
				$.each( mStations , function(stationId , stationParams){				
					$("select#sMStation").append('<option value="' + stationId + '">' + stationParams.name + '</option>');				
					if( stationParams.is_active == 0 ) { $("select#sMStation option[value=" + stationId + "]").attr('disabled' , 'disabled').attr('class' , 'inactive');	}
				});			
			break;		
		}
		
		switch( res.data.sPOS ){		
			case null:        break;
			case undefined:   break;
			case -1: $("select#sPOS").append('<option value="-1">&mdash;</option>');  break;
			default:			
				POS = res.data.sPOS;			
				/*$("select#sPOS").append('<option value="-1">' + reqSelectPOS + '</option>');*/
				$.each( POS , function(posId , posParams){					
					$("select#sPOS").append('<option value="' + posId + '">' + posParams.name + '</option>');	
					$("div#posAddress").empty().append(posParams.address);					
					if( posParams.is_active == 0 ) { /*$("select#sPOS option[value=" + posId + "]").attr('class' , 'inactive');*/ }
				});			
			break;		
		}
		
		if( res.data.sPos == 1 ) { 
			shipPOSEnable = 1; 
			shipPOSCost = res.data.sPosCost; 
		}
		if( res.data.sPost == 1 ) { 
			shipPostEnable = 1; 
			shipPostCost = res.data.sPostCost; 
		}
		if( res.data.sCourier == 1 ) { 
			shipCourierEnable = 1; 
			shipCourierCost = res.data.sCourierCost; 
		}
		
		return;
		
	}
	//------------------------------------------------------------------------
	function WLYRound( num , ord , show ) {
		
		mlt = Math.pow(10,ord);		
		num = num * mlt;			
		if( Math.round( num ) > num ) {
		
			absSuffix = Math.abs( num - Math.round( num ) );
			
			if( ( absSuffix > 0.4 && absSuffix <= 0.5 ) ) {				
				
				criterium = num - 1 + absSuffix;
				
				if( criterium % 2 != 0 ) { 
					num = num + 0.1;
				} else {
					num = num - 0.1;
				}
				
			}
		
		}		
		num = Math.round( num );		
		num = num / mlt;
		num = num.toFixed( ord );
		
		return num ;
		
	}
	//------------------------------------------------------------------------
	function dispatchCartState( res ){		
		
		if( res.data.items == undefined ){
		
			location.href = '/cart.contents'; 
			return false;
		
		}else{			
		
			curOverallItemsCost = res.data.overallItemsCost;
			items = res.data.items;
			
			var price  = 0.0;
			var amount = 0;
			var cost   = 0.0;
			var totalSum = 0.0;
			var totalSumRounded = 0.0;
			var costRounded = 0.0;
			
			$.each(items , function(index , value){
				
				price  = parseFloat(value.price);
				amount = value.amount;
				cost   = parseFloat(value.cost);
				
				if( overallServicesCost != -1 ) {
					
					diff = overallServicesCost / curOverallItemsCost;
					
					//alert( diff  + " - "+ WLYRound( diff + 0.000001 * ( diff % 2 - 1 ) , 5 ) );
					
					//cost  = cost + cost * WLYRound( diff + 0.000001 * ( diff % 2 - 1 ) , 5 );
					cost  = cost * ( 1 + diff );
					costRounded = WLYRound( cost , 2 );
					price = WLYRound( cost , 2 ) / amount;
					//price = cost / amount;
					
				}

				parsedCost = parseFloat( cost );
				parsedSum = parseFloat(totalSum);
				totalSum = parsedCost + parsedSum;
				curTotalSumRounded = totalSumRounded;
				parsedCostRounded = costRounded;
				parsedCurTotalSumRounded = parseFloat(curTotalSumRounded);
				totalSumRounded = parsedCostRounded + parsedCurTotalSumRounded;
				
				$("tr#row-" + index  + " .price").empty().append( WLYRound( price , 3 ) );
				$("tr#row-" + index  + " input.q").val( amount );
				$("tr#row-" + index  + " .cost").empty().append( WLYRound( cost , 2 ) );
				
				lastRowIndex = index;
		
			});
			
			if( totalSum ) { 				
				finalDiff = totalSum - totalSumRounded;	
				finalDiff = WLYRound( finalDiff , 2 );
				//alert( totalSumRounded + " - " + totalSum + " - " + finalDiff );				
				$("tr#row-" + lastRowIndex  + " .cost").empty().append( WLYRound( parseFloat(WLYRound( cost , 2 )) + parseFloat(finalDiff) , 2 ) );
				overallItemsCost = totalSum; 				
			}
			
		}		
		
		if( overallCost != -1 ) { 
			overallCost = overallItemsCost/* + overallServicesCost*/;			
			/*overallServicesCost = 0;*/ 
			/*overallItemsCost = overallCost;*/			
		}		
		
		updateOverallSaldos();

		return;
		
	}
	//------------------------------------------------------------------------
	function updateOverallSaldos(){
		
		if( overallItemsCost != -1 ) { 			
			overallItemsCostValue = ( overallCost != -1 ) ? overallCost : overallItemsCost;
			overallItemsCostValue = overallItemsCostValue.toFixed(2);
			$("tr#overallItems .cost").empty().append( overallItemsCostValue ); 		
		}else{		
			$("tr#overallItems .cost").empty().append( "&mdash;" ); 		
		}
		
		if( overallServicesCost != -1 ) {			
			$("tr#overallServices .cost").empty().append( overallServicesCost.toFixed(2) ); 
			overallCost = overallItemsCost/* + overallServicesCost*/;			
		}else{					
			overallCost = -1;			
			$("tr#overallServices .cost").empty().append( "&mdash;" ); 	
		}
		
		if( overallCost != -1 ) { 			
			$("tr#overallSaldo #cost").empty().append( overallCost.toFixed(2) ); 		
		}else{		
			$("tr#overallSaldo #cost").empty().append( "&mdash;" );	
		}
		
	}
	//------------------------------------------------------------------------
	function resetShippingOptions(){		
		
		shipPOSEnable = 0;
		shipPOSCost = -1;
		shipPostEnable = 0;
		shipPostCost = -1;
		shipCourierEnable = 0;
		shipCourierCost = -1;
			
		shippingCost = -1;
		
		shippingOptionsSetUp();
		recalcOverallServicesCost();
		updateOverallSaldos();
		
	}
	//------------------------------------------------------------------------
	function recalcOverallServicesCost(){
		
		overallServicesCost = 0;
		
		if( shippingCost >= 0 ) { 
		
			overallServicesCost = overallServicesCost + shippingCost; 
			overallServicesCost = Number(overallServicesCost);
			
				rowsCount = $("tr[id^='row'] .price").length;
				
				/*
				$("tr[id^='row'] .price").each(function(){
					
					curPrice    = parseInt( $(this).text() );
					curCost     = parseInt( $(this).parent("tr").find(".cost").text() );
					curQuantity = parseInt( $(this).parent("tr").find(".q").val() );
					
					updCost  = curCost + ( overallServicesCost / rowsCount );
					updPrice = updCost / curQuantity;

					$(this).empty().append( updPrice );
					$(this).parent("tr").find(".cost").empty().append( updCost );
 					
				});
				*/
			
		}else{ overallServicesCost = -1; }
		
	}
	//------------------------------------------------------------------------
	function blockGeoSwitchers( nodeId ){
		
		$("select#sRegion").attr('disabled','disabled');
		$("select#sCity").attr('disabled','disabled');
		$("select#sMStation").attr('disabled','disabled').hide();
		$("select#sPOS").attr('disabled','disabled').hide();
		$("select#sMixed").attr('disabled','disabled').show();			
		
		switch( nodeId ){
		
			case "sRegion":  
				$("select#sCity").empty();
				$("select#sMStation").empty();
				$("select#sPOS").empty();				
			break;
			case "sCity":  
				$("select#sMStation").empty();
				$("select#sPOS").empty();				
			break;
		
		}
		
	}
	//------------------------------------------------------------------------
	function geoSwitchersSetUp(){
		
		$("select#sRegion").removeAttr('disabled').show();
		$("select#sCity").attr('disabled' , 'disabled').show();
		$("select#sMStation").attr('disabled' , 'disabled').hide();
		$("select#sPOS").attr('disabled' , 'disabled').hide();
		$("select#sMixed").attr('disabled' , 'disabled').show();
		
	}
	//------------------------------------------------------------------------
	function updateShippingOptions( curPoint ){
		
		switch( curPoint ){
					 	
			case "deliv_courier": 
				shippingCost = shipCourierCost; 
				if( $("select#sMStation option").size() > 1 ){					
					$("select#sMixed").attr('disabled','disabled').hide();
					$("select#sPOS").attr('disabled','disabled').hide();
					$("div#posAddress").hide();					
					$("select#sMStation").removeAttr('disabled').show();					
				}else{					
					$("select#sPOS").attr('disabled','disabled').hide();
					$("div#posAddress").hide();	
					$("select#sMStation").attr('disabled','disabled').hide();
					$("select#sMixed").attr('disabled','disabled').show();
				}
			break;
			case "deliv_post":    
				shippingCost = shipPostCost; 
			break;
			case "deliv_pos": 
				shippingCost = shipPOSCost;
				if( $("select#sPOS option").size() > 0 ){					
					$("select#sMixed").attr('disabled','disabled').hide();									
					$("select#sMStation").attr('disabled','disabled').hide();
					$("select#sPOS").removeAttr('disabled').show();	
					$("div#posAddress").show();	
				}else{														
					$("select#sMStation").attr('disabled','disabled').hide();
					$("select#sPOS").attr('disabled','disabled').hide();
					$("div#posAddress").hide();	
					$("select#sMixed").attr('disabled','disabled').show();					
				}				 
			break;
						
		}
		
		shippingOptionsSetUp();
		/*recalcOverallServicesCost();*/
		updateOverallSaldos();
		updatePInfoStack( curPoint );
		
	}
	//------------------------------------------------------------------------
	function shippingOptionsSetUp(){
		
		if( shipPOSEnable == 1 ) { 		
			$(".points input#deliv_pos").removeAttr('disabled');
			$(".points label[for=deliv_pos]").removeAttr('class'); 			
		} else { 		
			$(".points input#deliv_pos").removeAttr('checked').attr('disabled','disabled');
			$(".points label[for=deliv_pos]").attr('class','inactive');			
		}
		
		if( shipPostEnable == 1 ) { 
			$(".points input#deliv_post").removeAttr('disabled');
			$(".points label[for=deliv_post]").removeAttr('class'); 			
		} else { 
			$(".points input#deliv_post").removeAttr('checked').attr('disabled','disabled'); 
			$(".points label[for=deliv_post]").attr('class','inactive');
		}
		
		if( shipCourierEnable == 1 ) { 
			$(".points input#deliv_courier").removeAttr('disabled'); 
			$(".points label[for=deliv_courier]").removeAttr('class'); 
		} else { 
			$(".points input#deliv_courier").removeAttr('checked').attr('disabled','disabled'); 
			$(".points label[for=deliv_courier]").attr('class','inactive');
		}	
		
		if( shipPOSEnable == 1 && shipPostEnable == 0 && shipCourierEnable == 0 ) { if( $("input#deliv_pos").attr('checked') == false ) { $("input#deliv_pos").attr('checked' , 'checked');$("input#deliv_pos").trigger("click"); } }
		if( shipPOSEnable == 0 && shipPostEnable == 1 && shipCourierEnable == 0 ) { if( $("input#deliv_post").attr('checked') == false ) { $("input#deliv_post").attr('checked' , 'checked');$("input#deliv_post").trigger("click"); } }
		if( shipPOSEnable == 0 && shipPostEnable == 0 && shipCourierEnable == 1 ) { if( $("input#deliv_courier").attr('checked') == false ) { $("input#deliv_courier").attr('checked' , 'checked');$("input#deliv_courier").trigger("click"); } }
		
		if( shippingCost == -1 ){			
			$("td#shippingCost").empty().append("&mdash;");			
		}else{			
			$("td#shippingCost").empty().append( shippingCost );			
		}
		
		recalcOverallServicesCost();
		updateOverallSaldos();
		
	}
	//------------------------------------------------------------------------
	function freeGeoSwitchers(){
		
		$("select#sRegion").removeAttr('disabled');
		
		if( $("select#sCity option").size() > 1 ) { $("select#sCity").removeAttr('disabled'); }		
		if( $("select#sMStation option").size() > 1 ) { $("select#sMStation").removeAttr('disabled'); }	
		if( $("select#sPOS option").size() > 0 ) { $("select#sPOS").removeAttr('disabled'); }
		
	}
	//------------------------------------------------------------------------
	function cartCommunicate(sAction , nodeId , setValue) {
		
		$.ajax({
			url:      'async_req',
			type:     'POST',
			data:     '_SENDID=' + sAction + '&node_id=' + nodeId + '&set_value=' + setValue,
			dataType: 'json',
			timeout:  5000,
			beforeSend: function(){
				
				switch( sAction ){
					case "delete":  $("tr#" + nodeId).fadeTo( 300 , 0.3 ); break;
					case "recount":	$("tr#" + nodeId).fadeTo( 300 , 0.3 ); break;
					case "retrieve_geo": blockGeoSwitchers( nodeId );resetShippingOptions(); break;
				}
				
			},
			complete: function(){				
			},
			success: function( response ){
				
				switch( sAction ){
				
					case "delete": 
					
						if( response.status == 'failure' ){						
							$('form').prepend( msgConnectionError );						
						}else{						
							dispatchCartState( response ); 
							$("tr#" + nodeId).fadeTo( 100 , 0 );
							$("tr#" + nodeId).remove();	
						}
						
					break;
					
					case "recount": 
						
						if( response.status == 'failure' ){						
							alert("!!" + sAction);
							$('form').prepend( msgConnectionError + "(" + response.curError + ")" );						
						}else{								
							dispatchCartState( response );					
							$("tr#" + nodeId).fadeTo( 300 , 1 );
						}
						
					break;
					case "retrieve_geo":
						
						dispatchGeoState( response );											
						freeGeoSwitchers();
						shippingOptionsSetUp();
						
					break;
					
				}
 
				return false;
				
			},
			error: function(){
				$('form').prepend( msgConnectionError );
				
				switch( sAction ){
					case "delete":						
						$("tr#" + nodeId).fadeTo( 300 , 1 );						
					break;
				}
				
				return false;
			}
			
		});
		
	}
	
	// p Info functions ---------------------------------------
	function blockPInfoRows( rowStack ){		
		
		$.each( rowStack , function(index , rowId){
			
			$(".pInfo tr#" + rowId).fadeTo( 300 , 0.3 );
			$(".pInfo tr#" + rowId + " input").attr('disabled' , 'disabled');
			if( '\v'=='v' ) { $(".pInfo tr#" + rowId + " input").attr('class' , 'w250 inactive'); } // IE
			
		});
	
	}
	function freePInfoRows( rowStack ){
	
		$.each( rowStack , function(index , rowId){
			
			$(".pInfo tr#" + rowId + " input").removeAttr('disabled');
			$(".pInfo tr#" + rowId).fadeTo( 300 , 1 );
			if( '\v'=='v' ) { $(".pInfo tr#" + rowId + " input").attr('class' , 'w250'); } // IE
		
		});
	
	}
	function updatePInfoStack( curPoint ){
		
		switch( curPoint ){
		
			case "deliv_courier":  			
				blockFields = '["zipCode" , "passportData"]';
				freeFields  = '["street" , "house" , "entrance" , "passCode" , "level" , "room" , "companyName" , "comment"]';			
			break;	
			case "deliv_post":  			
				blockFields = '["entrance" , "passCode" , "level"]';
				freeFields  = '["zipCode" , "passportData" , "street" , "house" , "room" , "companyName" , "comment"]';			
			break;
			case "deliv_pos":  			
				blockFields = '["zipCode" , "passportData","street" , "house" , "entrance" , "passCode" , "level" , "room" , "companyName"]';
				freeFields  = '["comment"]';			
			break;			
			default:
				blockFields = null;
				freeFields  = null;
			break;
		
		}
		
		pInfoSetUp();
		
	}
	function pInfoSetUp(){		
		
		if( blockFields == null ) { blockPInfoRows( eval(allFields) ); } else { blockPInfoRows( eval(blockFields) ); }
		if( freeFields == null ) { freePInfoRows( eval(initFields) ); } else { freePInfoRows( eval(freeFields) ); }
		
	}
	
	$(document).ready(function(){
		
		//Init form elements and data
		$(".cart-body").show();
		//$(".back-to-catalogue").fadeTo(15000 , 1).fadeOut();
		$(".err").fadeTo(15000 , 1).fadeOut();
		
		geoSwitchersSetUp();
		resetShippingOptions();
		shippingOptionsSetUp();
		
		updatePInfoStack();
		
		//Amount controller
		$("input.q").bind("modAmount" , function(){
					
			curValue = $(this).val();
			row_id = $(this).parent("td").parent("tr").attr("id");
					
			if( curValue === "" || curValue === 0 || curValue === undefined ){
				$(this).val( tempPrevValue );
			}else{
				cartCommunicate("recount" , row_id , sid + "," + curValue );
			}
					
			tempPrevValue = 0;
					
			return false;					
					
		});				
		
		$("input.q").bind("keyup" , function(){	$(this).trigger("modAmount"); return false; });				
		$("input.q").bind("focus" , function(){	tempPrevValue = $(this).val(); return false; });				
		$("input.q").bind("blur"  , function(){ tempPrevValue = 0; return false; });
				
		//Go next controller
		$("input#go_next").bind("click" , function(){
					
			errText = "";
					
			if( !$(".points input:checked").size() ) { errText += errFShipping + "\n"; }
					
			if( $("tr#name_1 input").val() == "" || $("tr#name_1 input").val() == null )   { errText += errFName1 + "\n";  }
			if( $("tr#name_2 input").val() == "" || $("tr#name_2 input").val() == null )   { errText += errFName2 + "\n";  }
			if( $("tr#name_3 input").val() == "" || $("tr#name_3 input").val() == null )   { errText += errFName3 + "\n";  }
			if( $("tr#email input").val() == "" || $("tr#email input").val() == null ) { errText += errFEmail + "\n"; }
			if( $("tr#phone input").val() == "" || $("tr#phone input").val() == null ) { errText += errFPhone + "\n"; }
			if( $("input#terms:checked").size() == 0 ) { errText += errFTerms + "\n"; }
					
			if( !errText ){
				return;
			}else{
				errText = errDetected + "\n" + errText;						
				alert( errText );
				return false;
			}
					
		});
				
		//Delete controller
		$("img.del").parent("a").bind("click" , function(){
		
			row_id = $(this).parent("td").parent("tr").attr("id");					
			cartCommunicate( "delete" , row_id , sid );					
			return false;
					
		});
				
		//Geo controller
		$("select#sRegion").change( function(){ curGeoNodeId = $(this).attr("id");$(".selector").trigger("modGeo");return false; } );
		$("select#sCity").change( function(){ curGeoNodeId = $(this).attr("id");$(".selector").trigger("modGeo");return false; } );
		$(".selector").bind("modGeo" , function(){
					
			regionId   = $("select#sRegion").children("option:selected").val();
			cityId     = $("select#sCity").children("option:selected").val();
			mStationId = $("select#sMStation").children("option:selected").val();
			posId      = $("select#sPOS").children("option:selected").val();
					
			curShippingOption = $(".points input:checked").val();
					
			SQ = regionId + "," + cityId + "," + mStationId + "," + posId + ",," + curShippingOption ;
					
			if( curGeoNodeId != -1 ){ cartCommunicate( "retrieve_geo" , curGeoNodeId , SQ ); }
					
				return false;
					
		});	
		
		$(".points input").bind("click" , function(){ 
			updateShippingOptions( $(".points input:checked").attr("id") ); 
			$("input.q").trigger("modAmount") 
		});
		
		
		
	});
