	
	function random_string(l) {
		
		// chars
		var ch = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
		
		// string length
		var sl = l;
		
		// random string
		var rs = '';
		
		for (var i=0; i<sl; i++) {
			
			// random number
			var rn = Math.floor(Math.random() * ch.length);
			
			rs += ch.substring(rn, rn + 1);
			
		}
		
		return rs;
		
	}
	
	function HTMLHttpCart() {
		
		// if DOM 2 supports
		if (window.addEventListener) {
			
			window.addEventListener('load', this.onloadListener, false);
		
		// if IE
		} else if (window.attachEvent) {
			
			window.attachEvent('onload', this.onloadListener);
			
		// DOM 0 support
		} else if (window.onload) {
			
			window.onload = this.onloadListener;
			
		}
		
	}
	
	HTMLHttpCart.prototype.onloadListener = function() {
		
		e = document.getElementsByName('cart_submit');
		
		for (var i = 0; i < e.length; i++) {
			
			e[i].onclick = function () {
				
				var btn = this;
				
				// shopping cart transact (place/remove from cart)
				var transact = new HTMLHttpRequest('transact', transactCallback);
				
				// cart information block updater
				var cartInfo = new HTMLHttpRequest('cartInfo', cartInfoCallback);
				
				// submit button id prefix
				var bIdPref = 'cart_submit_';
				
				// item form id prefix
				var fIdPref = 'cart_item_';
				
				// item message container id prefix
				var iMsgPref = 'cart_item_msg_';
				
				// cart info container id
				var ciContId = 'cart_info';
				
				// item node
				var iNode = 0;
				
				// item id
				var iId = 0;
				
				if (this.id.lastIndexOf(bIdPref) != -1) {
					iId = this.id.substr(bIdPref.length).split('_')[1] ? parseInt(this.id.substr(bIdPref.length).split('_')[1]) : 0;
					iNode = parseInt(this.id.substr(bIdPref.length).split('_')[0]);
				}
				
				// msg container
				var cont = document.getElementById(iMsgPref + iNode + '_' + iId);
				
				// cart info container
				var infoCont = document.getElementById(ciContId);
				
				// params form 
				var form = document.getElementById(fIdPref + iNode + '_' + iId);
				
				if (!form) {
					alert('Fatal error: can`t find item form');
					return false;
				}
				
				if (!form.cart_url) {
					alert('Fatal error: cart url param is not defined');
					return false;
				}
				
				if (!form.action) {
					alert('Fatal error: action param is not defined');
					return false;
				}
				
				var URL = '';
				URL += form.cart_url.value;
				URL += '/~action=' + form.action.value + '~id=' + iId;
				
				if (sels = form.getElementsByTagName('select')) {
					for (var j = 0; j < sels.length; j++) {
						if (sels[j].name && sels[j].name.match(/^cp_(\d+?)$/)) {
							URL += '~' + sels[j].name + '=' + sels[j].value;
						}
					}
						
				}
				
				URL += '~' + random_string(32) + '.ajax';
				
				transact.load(URL);
				
				btn.disabled = true;
				cont.innerHTML = 'Пожалуйста, подождите...';
				cont.className = 'success db';

				function transactCallback(DOM) {
					
					var xmldata = this.getXML();
					
					var statusCode = xmldata.getElementsByTagName('code')[0].childNodes[0] ? xmldata.getElementsByTagName('code')[0].childNodes[0].nodeValue : '';
					var statusMsg = xmldata.getElementsByTagName('msg')[0].childNodes[0] ? xmldata.getElementsByTagName('msg')[0].childNodes[0].nodeValue : '';
					var data = xmldata.getElementsByTagName('data')[0].childNodes[0] ? xmldata.getElementsByTagName('data')[0].childNodes[0].nodeValue : '';
					
					cont.innerHTML = statusMsg;
					cont.className = 'success db';
					
					if (statusCode == 1) {
						
						switch (form.action.value) {
							case 'place':
								
								btn.src = '/images/izcart.gif';
								form.action.value = 'remove';
								
								cartItemsNodes(iId, iNode, '/images/izcart.gif', 'remove');
								
							break;
							case 'remove':
								
								btn.src = '/images/incart.gif';
								form.action.value = 'place';
								
								cartItemsNodes(iId, iNode, '/images/incart.gif', 'place');
								
							break;
						}
						
						if (infoCont) {
							
							// cart info url
							var ciURL = URL.replace(/place|remove/i, 'info');
							cartInfo.load(ciURL);
							
						}
						
					}
					
					btn.disabled = false;
					
				}
				
				function cartInfoCallback(DOM) {
					
					var xmldata = this.getXML();
					
					var statusCode = xmldata.getElementsByTagName('code')[0].childNodes[0] ? xmldata.getElementsByTagName('code')[0].childNodes[0].nodeValue : '';
					var statusMsg = xmldata.getElementsByTagName('msg')[0].childNodes[0] ? xmldata.getElementsByTagName('msg')[0].childNodes[0].nodeValue : '';
					var data = xmldata.getElementsByTagName('data')[0].childNodes[0] ? xmldata.getElementsByTagName('data')[0].childNodes[0].nodeValue : '';
					
					if (statusCode == 1) {
						infoCont.innerHTML = data;
					}
					
				}
				
				return false;
				
			}
			
		}
		
		s = document.getElementsByTagName('select');
		
		for (var i = 0; i < s.length; i++) {
			
			if (s[i].name.indexOf('cp') > -1) {
				
				function checkCartItem() {
					
					var request = new HTMLHttpRequest('request', requestCallback);
					
					this.id.match(/^cp_(\d+?)_(\d+?)_(\d+?)$/);
					
					var iNode = RegExp.$1;
					
					var iId = RegExp.$2;
					
					var pId = RegExp.$3;
					
					// submit button id prefix
					var bIdPref = 'cart_submit_';
					
					// item form id prefix
					var fIdPref = 'cart_item_';
					
					// item message container id prefix
					var iMsgPref = 'cart_item_msg_';
					
					// params form 
					var form = document.getElementById(fIdPref + iNode + '_' + iId);
					
					// msg container
					var cont = document.getElementById(iMsgPref + iNode + '_' + iId);
					
					// params form 
					var btn = document.getElementById(bIdPref + iNode + '_' + iId);
					
					if (!form) {
						alert('Fatal error: can`t find item form');
						return false;
					}
					
					if (!form.cart_url) {
						alert('Fatal error: cart url param is not defined');
						return false;
					}
					
					if (!form.action) {
						alert('Fatal error: action param is not defined');
						return false;
					}
					
					var URL = '';
					URL += form.cart_url.value;
					URL += '/~action=check~id=' + iId;
					
					if (sels = form.getElementsByTagName('select')) {
						for (var j = 0; j < sels.length; j++) {
							if (sels[j].name && sels[j].name.match(/^cp_(\d+?)$/)) {
								URL += '~' + sels[j].name + '=' + sels[j].value;
							}
						}
					}
					
					URL += '~' + random_string(32) + '.ajax';
					
					request.load(URL);
					
					btn.disabled = true;
					cont.innerHTML = 'Пожалуйста, подождите...';
					cont.className = 'success db';
					
					function requestCallback(DOM) {
						
						var xmldata = this.getXML();
						
						var statusCode = xmldata.getElementsByTagName('code')[0].childNodes[0] ? xmldata.getElementsByTagName('code')[0].childNodes[0].nodeValue : '';
						var statusMsg = xmldata.getElementsByTagName('msg')[0].childNodes[0] ? xmldata.getElementsByTagName('msg')[0].childNodes[0].nodeValue : '';
						var data = xmldata.getElementsByTagName('data')[0].childNodes[0] ? xmldata.getElementsByTagName('data')[0].childNodes[0].nodeValue : '';
						
						cont.innerHTML = statusMsg;
						cont.className = 'success db';
						
						switch (statusCode) {
							
							case '22':
								
								btn.value= 'Удалить из корзины';
								form.action.value = 'remove';
								
							break;
							
							case '23':
								
								btn.value= 'Положить в корзину';
								form.action.value = 'place';
								
							break;
							
						}
						
						cartParamsInit(iId, iNode, pId);
						cartParamsNodes(iId, iNode, pId)
						
						btn.disabled = false;
						
					}
					
				}
				
				s[i].onchange = checkCartItem;
				
			}
			
		} // select loop
		
	}
	
	GCart = new HTMLHttpCart();
	
	function cartParamsInit(iId, iNode, pId) {
		var d = document;
		if (cart_mp[iId][pId]) {
			if (cart_mp[iId][pId].length) {
				for (spId in cart_mp[iId][pId]) {
					if (d.getElementById('cp_' + iNode + '_' + iId + '_' + spId) && d.getElementById('cp_' + iNode + '_' + iId + '_' + pId)) {
						var m = d.getElementById('cp_' + iNode + '_' + iId + '_' + pId);
						var s = d.getElementById('cp_' + iNode + '_' + iId + '_' + spId);
						while (s.options.length>1) {
							s.removeChild(s.options[1]);
						}
						if (cart_msi[iId]) {
							if (cart_msi[iId][pId]) {
								if (cart_msi[iId][pId][m.value]) {
									if (cart_msi[iId][pId][m.value][spId]) {
										for (spiId in cart_msi[iId][pId][m.value][spId]) {
											var sOpt = document.createElement('option');
											s.appendChild(sOpt);
											sOpt.innerHTML = cart_msi[iId][pId][m.value][spId][spiId] + '';
											sOpt.value = spiId;
										}
									}
								}
							}
						}
						cartParamsInit(iId, iNode, spId);
					}
				}
			}
		}
	}
	
	function cartItemsNodes(iId, iNode, btnTitle, action) {
		var items = document.getElementsByName('cart_item_node_' + iId);
		for (i=0; items[i]; i++) {
			if (items[i].value != iNode) {
				document.getElementById('cart_submit_' + items[i].value + '_' + iId).src= btnTitle;
				document.getElementById('cart_item_' + items[i].value + '_' + iId).action.value = action;
				document.getElementById('cart_item_msg_' + items[i].value + '_' + iId).innerHTML = '<' + '!-- --' + '>';
			}
		}
	}
	
	function cartParamsNodes(iId, iNode, pId) {
		var items = document.getElementsByName('cart_item_node_' + iId);
		for (i=0; items[i]; i++) {
			if (items[i].value != iNode) {
				document.getElementById('cp_' + items[i].value + '_' + iId + '_' + pId).value= document.getElementById('cp_' + iNode + '_' + iId + '_' + pId).value;
				document.getElementById('cart_item_msg_' + items[i].value + '_' + iId).innerHTML = '<' + '!-- --' + '>';
				cartParamsInit(iId, items[i].value, pId);
			}
		}
	}
	
	