//------------------------------------------------------------------
//	Title				Shopping Cart Script
//  Date 				21 November 2007
//  Author	 			Alexey Generalov [webradical]
//  Copyright	 		Ulter West
//	Update				20100131
//------------------------------------------------------------------
//  Goods attributes
//------------------------------------------------------------------
	
	/*	
	 * Defaults
	 * {
	 * 		name	: '',
	 *  	cart	: true,
	 * 		order	: true,
	 * 		proc	: false,	// false/hidden/quantity/price/sumprice/btnremove/btnview
	 * 		convert	: 'all'	[all/link/text] 
	 * }
	*/
	
	Cart.prototype.attArr = [
		{
			name	: 'Артикул',
			cart	: false,
			order	: true,
			proc	: 'hidden'
		},
		{
			name	: 'Название',
			convert	: 'text'
		},
		{
			name	: 'Изображение',
			order	: false
		},
		{
			/* описание - пропускаем */
			proc	: 'skip'
		},
		'Двигатель',
		'Доп. оборудование',
		{
			name	: 'Цена',
			proc	: 'price'
		},
		{
			name	: 'Кол-во',
			proc	: 'quantity'
		},
		{
			name	: 'Сумма',
			proc	: 'sumprice'
		},
		{
			name	: 'Удалить',
			proc	: 'btnremove'
		},
		{
			name	: 'Просмотр',
			proc	: 'btnview'
		}
	];
//------------------------------------------------------------------
//  Script preferences
//------------------------------------------------------------------	
	Cart.prototype.pref ={
			cookie : {
				days 	: 4,
				name 	: 'cartdata',
				refname : 'cartdatahref'
			},
			DOM : {
				cart: {
					cartId : 'cart',
					dataOnlyId : 'cartdataonly',
					orderPriceId : 'orderprice',
					dataContainer : 'td',
					dataHeader : 'th',
					goodsContainer : 'tr',
					goodsWrapper : 'tbody',
					cartWrapper : 'table',
					cartClass: 'tablelist' 
				},
				order		: {
					container : 'hiddenfield',
					fieldName : 'orderdetails'
				},
				informer	: {
					quantityId : 'infquantity',
					sumpriceId : 'infsumprice'
				}
			},
			text : {
				cartEmpty : 'Корзина пуста',
				btnRemove : 'Удалить товар из корзины',
				btnView : 'Вернуться на страницу с товаром',
				dataSeparator : '|',
				columnSeparator : '\t\t',
				rowSeparator : '\n',
				orderSumprice : 'Общая сумма заказа',
				currency : 'руб.',
				addGoods : 'Товар добавлен в корзину!'
			},
			quantityMin : 1,
			quantityMax : 10000,
			btnRemove : '/images/delete.gif',
			btnView : '/images/view.gif',
			toFixed: 0
	};
//------------------------------------------------------------------	
	function Goods(cid, href){
		this.cid = cid;
		this.href = (href == undefined) ? null : href;
	}

	Goods.prototype.quantity = null;
	Goods.prototype.price = null;
	
	(function(){
		var attDef = {
				name	: '',
				cart	: true,
				order	: true,
				proc	: false,  // false/hidden/quantity/price/sumprice/btnremove/btnview
				convert	: 'all'   // all/link/text
			};
		var F = function(o){
			if (typeof o == 'string') o = {name : o};
			for (var j in o)
				this[j] =o[j];
		};
		F.prototype = attDef;
		for (var i = 0; i < Cart.prototype.attArr.length; i++)
			Cart.prototype.attArr[i] = new F(Cart.prototype.attArr[i]);
		
		for (var i = 0; i < Cart.prototype.attArr.length; i++)
			switch(Cart.prototype.attArr[i].proc){
				case 'quantity':
					Goods.prototype.quantity = Cart.prototype.attArr[i].name;
					break;
				case 'price':
					Goods.prototype.price = Cart.prototype.attArr[i].name;
					break;
				case 'sumprice':
					Goods.prototype.sumprice = Goods.prototype[Cart.prototype.attArr[i].name] = function(){
						if (this.price == null || this.quantity == null) return null;
						var t = this[this.price];
						var t2 = this[this.quantity];
						return (this[this.price] * this[this.quantity]);
					}; 
					break;
			}
	})();
	


//------------------------------------------------------------------

	function Cart(){this.goodsArr = new Array(); }

	
	
	Cart.prototype.addGoodsMsg = function(btnObj, text){
		alert(text);
	}
	
	Cart.prototype.getSumPrice = function(){
		if (!Goods.prototype.sumprice || Goods.prototype.sumprice() == null) return null;
		var sum = 0;
		for (var i = 0; i < this.goodsArr.length; i++)
			sum += this.goodsArr[i].sumprice();
		return sum.toFixed(this.pref.toFixed);
	}


	Cart.prototype.showInformer = function(){
		var q = document.getElementById(this.pref.DOM.informer.quantityId);
		var s = document.getElementById(this.pref.DOM.informer.sumpriceId);
		
		
		if (q != undefined) q.firstChild.nodeValue = this.goodsArr.length;
		if (s != undefined && this.getSumPrice() != null) s.firstChild.nodeValue = (this.getSumPrice()).toFixed(this.pref.toFixed);
	}
	

	
	
	Cart.prototype.getHREFCID = function(matchcid)
	{
	
		var data = document.cookie.split(';');		
		var reg = /(\s*cartdatahref\d{1,2}=\s*)/;
		var cid_reg = /\d{1,2}/;
		
		for (var i = 0; i < data.length; i++){
			if (data[i].match(reg) != null) { 
				var cid = parseInt(unescape(data[i]).match(cid_reg));
				
				if (cid == matchcid)
				{
					var href = unescape(data[i]).replace(reg, '');
					return href;
				}
			}
		}
		
		return '';
		
	}

	Cart.prototype.restoreCart = function(){
		this.goodsArr = [];

		if (document.cookie == '')
		{
			this.showCart(); 
			this.showInformer();
			return;
		}
	
		
		var data = document.cookie.split(';');
		var reg = /(\s*cartdata\d{1,2}=\s*)/;
		var cid_reg = /\d{1,2}/;
		
		for (var i = 0; i < data.length; i++){
			
			if (data[i].match(reg) != null) {
			
				var cid = parseInt(unescape(data[i]).match(cid_reg));
				var href= this.getHREFCID(cid);
				
				var str = unescape(data[i]).replace(reg, '');
				var str = str.split(this.pref.text.dataSeparator);
				
				var g = new Goods(cid, href);
				var d = 0;
				for (var j = 0; j < this.attArr.length, d < str.length; j++)
				{
					switch (this.attArr[j].proc)
					{
						case 'price':
						case 'hidden':
						case false:
							g[this.attArr[j].name] = str[d];
							d++;
							break;
						case 'quantity':
							g[this.attArr[j].name] = parseInt(str[d].match(/\d+/));
							d++;
							break;
						case 'sumprice':
						case 'skip':
						case 'btnremove':
						case 'btnview':
							break;
						default:
							throw new Error('Proccesing value not correct');
					}
				}
				this.goodsArr.push(g);
				
				/* !! */
				
				//var price = unescape(str[str.length - 2]).replace(/\s/g, '');	  
				//price = parseFloat(price);
				//var q = str.pop(); 
				//var tmp = new Goods(cid, str.join(this.DATA_SEPARATOR), q, price, href);
				//this.goodsArr.push(tmp);
			}
		}

	
		this.showInformer();
		if (document.getElementById(this.pref.DOM.cart.cartId))
			this.showCart();		
		
		if (document.getElementById(this.pref.DOM.cart.dataOnlyId))
			this.showCart(true);
	
	}
	
	Cart.prototype.removeGoodsCID = function(cid){
		this.createCookie(this.pref.cookie.name + cid, '', -1);
		this.createCookie(this.pref.cookie.refname + cid, '', -1);
	}
	
	Cart.prototype.clearCart = function(){
		for (var i= 0; i < this.goodsArr.length; i++)
			this.removeGoodsCID(this.goodsArr[i].cid);
		this.restoreCart();
	}
	
	
	//	Set quantity of goods with @data and 
	Cart.prototype.setGoodsQuantity = function(cid, quantity){
		if ((quantity < this.pref.quantityMin) || (quantity > this.pref.quantityMax)) {alert("The quantity is out of range [" + this.QUANTITY_MIN_VALUE + "-" + this.QUANTITY_MAX_VALUE + "]"); return null;}
		var c = unescape(document.cookie);
		c = c.split(';');
		var data = null;
		for (var i = 0; i < c.length; i++)
			if (c[i].indexOf(this.pref.cookie.name + cid) != -1)
			{
				
				data = c[i].replace(/cartdata\d+=/,'').split('~');
				break;
			}
	
		data = data[0] + '~' + quantity + '~' + data[2]; 
		this.createCookie(this.pref.cookie.name + cid, data, this.pref.cookie.days);				
	}
	
	Cart.prototype.setUserQuantity = function(cid, input){
		var test = input.value.match(/\D+/);
		
		if (test != null || input.value==''){
			alert("The quantity does not contain any non-digit characters. " + test);
			this.restoreCart();
			return;
		}
		
		this.setGoodsQuantity(cid, parseInt(input.value));
		this.restoreCart();
	}
	
	//	Cart interfeice with 
	//	goods table, remove button, quantity field 
	Cart.prototype.showCart = function(){		
		var obj = arguments[0] ? document.getElementById(this.pref.DOM.cart.dataOnlyId) : document.getElementById(this.pref.DOM.cart.cartId);
		if (obj == undefined) return;
		
		if (this.goodsArr.length == 0){
			var text = document.createTextNode(this.pref.text.cartEmpty);
			try{
				obj.replaceChild(text, obj.firstChild);
			}catch(e){
				obj.appendChild(text);
			}
			this.updateSumPrice();
			return; 
		}
		
		//!! Заменить td на this.pref.DOM.cart.dataContainer;
		var parseData = function(some, tag)
		{
			var node = document.createElement(tag);
			var _tmp = some.substring(some.length-4);
			if ((_tmp == '.jpg') || (_tmp == '.gif') || (_tmp == '.png')){
				var r = document.createElement('img');
				r.src=some;
				node.appendChild(r);
			}else if(some.substring(0,4) == 'http' || some.charAt(0) == '/'){
				var r = document.createElement('a');
				var someArr = some.split(',');
				r.href=someArr[0];
				r.appendChild(document.createTextNode(someArr[1]));
				node.appendChild(r);
			}else{
				node.appendChild(document.createTextNode(some));
			}
			return node;
		}
		
		var wrapper = document.createElement(this.pref.DOM.cart.cartWrapper);
		wrapper.className=this.pref.DOM.cart.cartClass;
		var container = document.createElement(this.pref.DOM.cart.goodsWrapper);
		wrapper.appendChild(container);
		var goods = document.createElement(this.pref.DOM.cart.goodsContainer);
		//table headers
		
		for (var i = 0; i < this.attArr.length; i++)
		{
			if (this.attArr[i].cart != false && this.attArr[i].proc != 'skip' && !(arguments[0] && (this.attArr[i].proc == 'btnremove' || this.attArr[i].proc == 'btnview'))){
				var th = document.createElement(this.pref.DOM.cart.dataHeader);
				th.appendChild(document.createTextNode(this.attArr[i].name));
				goods.appendChild(th); 	
			}
		}

		container.appendChild(goods);
		
		for (var i = 0; i < this.goodsArr.length; i++){
			goods = document.createElement(this.pref.DOM.cart.goodsContainer);
			container.appendChild(goods);
			
			for (var j = 0; j < this.attArr.length; j++)
			{
				if (this.attArr[j].cart)
				{
					switch (this.attArr[j].proc)
					{
						case 'price':
						case false:
						case 'hidden':
							goods.appendChild(parseData(this.goodsArr[i][this.attArr[j].name], this.pref.DOM.cart.dataContainer));
							break;
						case 'quantity':
							if (arguments[0]) {
								var node = document.createTextNode(this.goodsArr[i].quantity); 
							}else{
								var node = document.createElement('input');
								node.setAttribute('type', 'text');
								node.className='quantity';
								node.value = this.goodsArr[i][this.attArr[j].name];
				
								function constr2(p1, p2){
									return function(){
										cart.setUserQuantity(p1, p2);
									}
								}
								
								node.onkeyup = constr2(this.goodsArr[i].cid, node);
							}
							var td = document.createElement(this.pref.DOM.cart.dataContainer);
							td.className = 'quantity'
							td.appendChild(node);
							goods.appendChild(td);
							break;
						case 'skip':
							break;
						case 'btnremove':
							if (!arguments[0]) {
								var node = document.createElement('img');
								node.setAttribute('src', this.pref.btnRemove);
								node.setAttribute('alt', this.pref.text.btnRemove);
								node.setAttribute('title', this.pref.text.btnRemove);
								node.className='btnRemove';
								node.style.cursor = 'pointer';
								
								function constr(p){	 
									return function(){
										cart.removeGoodsCID(p);
										cart.restoreCart();
									}
								}

								node.onclick = constr(this.goodsArr[i].cid);
								var td = document.createElement(this.pref.DOM.cart.dataContainer);
								td.className = 'remove'
								td.appendChild(node);
								goods.appendChild(td);
							}
							break;
						case 'btnview':
							if (!arguments[0]) {
								var node = document.createElement('img');
								node.setAttribute('src', this.pref.btnView);
								node.setAttribute('alt', this.pref.text.btnView);
								node.setAttribute('title', this.pref.text.btnView);
								node.className='btnview';
								node.style.cursor = 'pointer';
								function constr23(p){
									return function(){location.href=p;}
								}
								node.onclick = constr23(this.goodsArr[i].href);
								var td = document.createElement('td');
								td.className = 'view'
								td.appendChild(node);
								goods.appendChild(td);
							}
							break;
						case 'sumprice':
							var node = document.createElement(this.pref.DOM.cart.dataContainer);
							node.appendChild(document.createTextNode(this.goodsArr[i][this.attArr[j].name]()));
							goods.appendChild(node);
							break;
						default:
							throw new Error('Proccesing value not correct');
					}
				}
			}
		
		}
		
		
		if (!obj.firstChild)
			obj.appendChild(wrapper)
		else
			obj.replaceChild(wrapper, obj.firstChild);
		
		this.updateSumPrice();
	}
	Cart.prototype.updateSumPrice = function()
	{
		if (!Goods.prototype.sumprice || Goods.prototype.sumprice() == null) return;
		var order = document.getElementById(this.pref.DOM.cart.orderPriceId);
		if (!order) return;
		var text = document.createTextNode(this.getSumPrice());
		
		if (!order.firstChild)
			order.appendChild(text)
		else
			order.replaceChild(text, order.firstChild);
	}
	
	// Записать данные в куки, сложив значения атрубута количество если нужно ~DDD~
	Cart.prototype.storeData = function(data){
		var c = unescape(document.cookie).split(';');
		data = unescape(data);
		var rxp = /\d+/;
		var isq = false;
		var cid = null;

		var __getq = function(str){
			str.match(/(?:~)(\d+)(?:~)/g);
			return parseInt(RegExp.$1);
		}
		
		for (var i = 0; i < this.attArr.length; i++)
			if (this.attArr[i].proc == 'quantity') isq = i;
		
		if (isq){
			data = data.split('~');
		}
		
		if (data instanceof Array){
			for (var i = 0; i < c.length; i++)
				if (c[i].indexOf(data[0]) != -1 && c[i].indexOf(data[2]) != -1){
					cid = parseInt(c[i].match(rxp));
					data = data[0] + '~' + (parseInt(data[1]) + __getq(c[i])) +'~' + data[2];
				}
		}else{
			for (var i = 0; i < c.length; i++)
				if (c[i].indexOf(data) != -1) return;
		}
		if (cid == null) cid = this.genCookieID();
		if (data instanceof Array) data = data.join('~');
		
		// Create cookie with goods data
		this.createCookie(this.pref.cookie.name + cid, data, this.pref.cookie.days);
		// Create cookie with goods URL
		this.createCookie(this.pref.cookie.refname + cid, location.href, this.pref.cookie.days); 		 
	}
	
	//	Generate cookie id
	Cart.prototype.genCookieID = function(){
		var c = unescape(document.cookie).split(';');
		if (c.length == 0) return 0;
		for (var i = c.length - 1; i > -1; i--){
			if (c[i].indexOf(this.pref.cookie.name) != -1) return parseInt(c[i].match(/\d+/)) + 1;
		}
		return 0;
	}
	
	Cart.prototype.getDataDOM = function(obj, hidden){
		var h = 0;
		var parseToData = function(nodes){
			var str = '';
			for (var i = 0; i < nodes.length; i++){
				if (nodes[i].nodeType == 3)
				{ 
					
					if (nodes[i].parentNode.className.indexOf('price') != -1)
						str += nodes[i].nodeValue.replace(/(\s+|\xA0)/g,'').replace(/\D*$/g,'').replace(/,/,'.');
					else
						str += nodes[i].nodeValue;
				}
				else
				{
					switch(nodes[i].tagName){
						case 'IMG':
							str += nodes[i].src;
							break;
						case 'A':
							str += nodes[i].href + ',' + nodes[i].firstChild.nodeValue;
							break;
						case 'INPUT':
							str += '~' + nodes[i].value + '~';
							break;
					}
				}
			}
			return str;
		}


		var data = '';
		var d = 0;
		for (var i = 0; i < this.attArr.length; i++)
		{

				switch (this.attArr[i].proc)
				{
					case 'price':
					case 'quantity':
					case false:
						if (d == obj.length) break;
						data += parseToData(obj[d].childNodes) + this.pref.text.dataSeparator;
						d++;
						break;
					case 'skip':
					case 'btnremove':
					case 'btnview':
					case 'sumprice':
						d++;
						break;
					case 'hidden':
						if (!hidden) throw new Error('Hidden attributes array not passed');
						data += hidden[h] + this.pref.text.dataSeparator;
						h++;
						break;
					default:
						throw new Error('Proccesing value not correct');
				}

		}

		data = data.substring(0, data.length - 1);
		return data;
	};
		  
	Cart.prototype.catalogSubmit = function(obj)
	{	
		var btnObj = obj;
		var addCheck = function(a){
			a = [a[0],a[a.length-1]];
			for (var i = 0; i < a.length; i++)
				if (a[i].nodeType != 3 && a[i].firstChild.tagName == 'INPUT' && a[i].firstChild.checked) return true;
			return false;
		}
		
		var hidden = (arguments[1] instanceof Array) ? arguments[1] : null;
		// Если два аргумента то добавляется один товар
		// кнопка рядом среди атрибутов, чекбокса нет
		obj = arguments[1] ? [obj.parentNode.parentNode] : obj.parentNode.parentNode.parentNode.childNodes;

		for (var i = 0; i < obj.length ; i++){
			//Если один товар или товар номер i из пакета прошел чек
			if (obj.length == 1 || (obj.length == 3 && i==1) || addCheck(obj[i].childNodes))
			{
				var data = this.getDataDOM(obj[i].childNodes, hidden);
				this.storeData(data);
				this.restoreCart();					
				
			}			
		}
		if (this.pref.text.addGoods.length != 0)
			this.addGoodsMsg(btnObj, this.pref.text.addGoods);
	};
	
	Cart.prototype.paramSubmit = function(obj, data){
		var btnObj = obj;	
		
		if (typeof data == 'string') data = data.split(this.pref.text.dataSeparator);
		var d = 0;
		for (var i = 0; i < this.attArr.length, d < data.length; i++)
		{
			switch (this.attArr[i].proc)
			{
				case 'price':
					data[d] = data[d].replace(/(\s+|\xA0)/g,'').replace(/\D*$/g,'').replace(/,/,'.');
					d++;
					break;
				case 'quantity':
					data[d] = '~' + parseInt(data[d]) + '~'; 
					d++;
					break;
				case 'hidden':
				case false:
					d++;
					break;
			}

		}
		data = data.join(this.pref.text.dataSeparator);
		this.storeData(data);
		this.restoreCart();	
		if (this.pref.text.addGoods.length != 0)
			this.addGoodsMsg(btnObj, this.pref.text.addGoods);
	}


	
	//	Create cookie @name with @value (cookie expire days = @days).
	//	You can also give the @days of -1 and it will be erased immediately. 
	Cart.prototype.createCookie = function(name, value, days){
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
		document.cookie = name + "=" + escape(value) + expires + "; path=/";
	}
	
	Cart.prototype.orderForm = function(){
		//this.restoreCart();
		var hidden = document.getElementById(this.pref.DOM.order.container);
		if (hidden == undefined) return;

			var __convert = function(value, convert){
		
				switch(convert){
					case 'link':
						return value.split(',')[0];
					case 'text':
						return value.split(',')[1];
					case 'all':
					default:
						return value;
				}
			}
		
			var field = document.createElement("input");
			field.setAttribute('type', 'hidden'); 
			field.setAttribute('name', this.pref.DOM.order.fieldName);
			
			var str = '';
			for (var i = 0; i < this.attArr.length; i++){
				if (this.attArr[i].order && this.attArr[i].proc != 'btnremove' && this.attArr[i].proc != 'btnview' && this.attArr[i].proc != 'skip')
				str += this.attArr[i].name + this.pref.text.columnSeparator;
			}
			
			str += this.pref.text.rowSeparator;
			for (var i = 0; i < this.goodsArr.length; i++){
				for (var j = 0; j < this.attArr.length; j++)
				{
					if (this.attArr[j].order && this.attArr[j].proc != 'btnremove' && this.attArr[j].proc != 'btnview' && this.attArr[j].proc != 'skip')
					{
						if (this.attArr[j].proc == 'sumprice')
								str += __convert(this.goodsArr[i][this.attArr[j].name](), this.attArr[j].convert) + this.pref.text.columnSeparator;
						else
								str += __convert(this.goodsArr[i][this.attArr[j].name], this.attArr[j].convert) + this.pref.text.columnSeparator;
					}
				}
				str += this.pref.text.rowSeparator;
			}
		
			if (this.getSumPrice() != null)
			str += this.pref.text.rowSeparator + this.pref.text.orderSumprice + ' ' + this.getSumPrice() + ' ' + this.pref.text.currency;

		field.setAttribute('value', str);
		hidden.appendChild(field);
		
	}
	

	/*
	function addLoadEvent(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		}else{
			window.onload = function() {
				if (oldonload){
				oldonload();
				}
      			func();
    		}
  		}
	}



	addLoadEvent(function() {
  		cart.restoreCart();
 		cart.orderForm();
	});

	*/
	
	// Dean Edwards/Matthias Miller/John Resig

	function init() {
	    // выходим, если функция уже выполнялась
	    if (arguments.callee.done) return;

	    // устанавливаем флаг, чтобы функция не исполнялась дважды
	    arguments.callee.done = true;

  		cart.restoreCart();
 		cart.orderForm();
	};

	/* для Mozilla/Firefox/Opera 9 */
	if (document.addEventListener) {
	    document.addEventListener("DOMContentLoaded", init, false);
	}

	/* для Internet Explorer */
	/*@cc_on @*/
	/*@if (@_win32)
	document.write("<script id=\"__ie_onload\" defer=\"defer\" src=\"javascript:void(0)\"><\/script>");
	var script = document.getElementById("__ie_onload");
	script.onreadystatechange = function() {
	    if (this.readyState == "complete") {
		init(); // вызываем обработчик для onload
	    }
	};
	/*@end @*/

	/* для Safari */
	if (/WebKit/i.test(navigator.userAgent)) { // условие для Safari
	    var _timer = setInterval(function() {
		if (/loaded|complete/.test(document.readyState)) {
		    clearInterval(_timer);
		    init(); // вызываем обработчик для onload
		}
	    }, 10);
	}

	/* для остальных браузеров */
	window.onload = init;

	
	var cart = new Cart();
	
