function Bag(){
	var
		totalCost= 0,
		totalQuantiy= 0,
		events= new Array(),
		instance= false,
		self= this,
		queue= new Array(),
		attributes= {},
		items= {};
	
	if(!instance){
		/* Инициализация корзины: запрос данных */
		$.get('/bag/items', {}, function(request){
			if(request /*&& request.error==false*/){
                                //if (console && console.log) { console.log(request); }
				instance= self;
				
				/* Если в очереди есть события на добавление товаров в корзину - выполняем их */
				$.each(queue, function(i, f){
					f.apply(self);
				});

				if(request.items){
					items= request.items;
				}

				totalCost= request.cost;

				totalQuantiy= request.quantiy;
				
				calculateBag();
				
				/* Вызов обработчиков по окончании инициализации корзины */
				trigger('data.load.ready');
			}else{
				/* Вызов обработчиков при неудачной инициализации корзины */
				trigger('data.load.error');
			}
		}, "json");
	}
	
	function trigger(event, params){
		if(events[event]){
			$.each(events[event], function(i, e){
                            e.call(self, params);
			});
		}
	}
	
	function getAttributes(){
		
		var
			isEmpty= true,
			data= attributes;
		
	    for(var prop in attributes) {
	        if(attributes.hasOwnProperty(prop)){
	        	
	        	isEmpty= false;
	            break;
	        }
	    }

		if(isEmpty){
			return false;
		}
		
		attributes= {};
		
		return data;
	}
	
	function calculateBag(){
		
		totalCost= 0,
		totalQuantiy= 0;
		
		$.each(items, function(i, o){
			totalQuantiy+= (o.quantity*1);
			totalCost+= o.cost*o.quantity;
		});
		
		trigger('calculate');
	};

	return {
		
		on: function(event, callback){
			if(!events[event]){
				events[event]= new Array();
			}
			
			events[event].push(callback);
		},
		
		withAttr: function(attr,value){
			attributes[attr]=value;
			
			return this;
		},

		/* Установить поле key для товара item_id */
		set: function (item_id, quantity, callback){
			
			if(typeof(items[item_id])=='object'){
				
				var 
					attr= getAttributes(),
					postData={
						id: item_id, 
						quantity: quantity
					};
				
				if(attr!=false){
					$.extend(postData, attr);
				}
                                $.ajax({
                                    type: "POST",
                                    url: '/bag/update',
                                    data: postData,
                                    success: function(request){
						if(request && request.error==false){
							items[item_id].quantity= quantity;

							calculateBag();

							trigger('update', Array(items[item_id]));

							if(typeof(callback)!='undefined'){
								callback(request);
							}
						}
                                    },
                                    dataType: 'json'
                                });
			}
		},
		
		/* Добавить товар в корзину */
		add: function(id, quantity, callback){
			if (console && console.log) { console.log('add'); }
			var f= function(){
				
				var 
					attr= getAttributes(),
					postData={
						quantity: parseInt(quantity) || 1,
						id: id
					};
				
				if(attr!=false){
					$.extend(postData, attr);
				}
                                $.ajax({
                                    type: "POST",
                                    url: '/bag/add',
                                    data: postData,
                                    success: function(request){
						
						items[id]= request;

						calculateBag();
						
						trigger('add');
						
						if(typeof(callback)!='undefined'){
							callback(request);
						}
                                    },
                                    dataType: 'json'
                                });
			};
			
			if(!instance){
				/* Если корзина ещё не инициализированна, то события на добавление товаров ставим в очередь */
				queue.remove.push(f);
			}else{
				f();
			}
		},
		
		/* Удаление товара из корзины */
		remove: function(id, callback){
			
			var f= function(){
				
				var 
					attr= getAttributes(),
					postData={
						id: id
					};
				
				if(attr!=false){
					$.extend(postData, attr);
				}
                                $.ajax({
                                    type: "POST",
                                    url: '/bag/remove',
                                    data: postData,
                                    success: function(request){
						delete items[id];

						calculateBag();

						trigger('remove');

						if(typeof(callback)!='undefined'){
							callback(request);
						}
                                    },
                                    dataType: 'json'
                                });
			};

			if(!instance){
				/* Если корзина ещё не инициализированна, то события на удаление товаров ставим в очередь */
				queue.remove.push(f);
			}else{
				f();
			}
		},
		
		/* Получить товар по его id в козине */
		get: function(item_id){
			return items[item_id];
		},
		
		/* Вернуть список товаров в корзине */
		list: function (){
			return items;
		},
		
		/* Получить итоговую сумму товаров в корзине */
		getTotalCost: function(){
			return totalCost;
		},
		
		/* Кол-во товаров в корзине */
		getTotalQuantity: function(){
			return totalQuantiy;
		}
	};
};
