(function($) {
	$.fn.umibasket = function(settings) {
		var config = {
			selSum : "#order_total_discount",
			selItems : "*[id^='basketrow']",
			selWeight : ""
		};

		if (typeof settings == "string") {
			var wrapper = this.first().data("basket");
			if (wrapper) {
				var otherArgs = Array.prototype.slice.call(arguments, 1);
				return wrapper[settings].apply(wrapper, otherArgs);
			}
		}

		if (typeof settings == "object")
			$.extend(config, settings);

		return this.each(function() {
					$(this).data("basket", new Basket(this, config));
				});

	}

	function Basket(elem, config) {
		this.root = $(elem);
		this.items = this.root.find(config.selItems);
		this.sum = this.root.find(config.selSum);
		this.weight = this.root.find(config.selWeight);
		this.init();
		this.attachEvents();
	}

	Basket.prototype = {
		init : function() {
			this.items.umibasketitem();
		},
		attachEvents : function() {
			var me = this;
			this.items.bind("basketItemChange", function() {
						me.root.trigger("basketChange");
					});
			this.root.bind("updateBasket",function(event, basketInfo){
				me.sum.html(basketInfo.order_total);
				me.root.trigger("basketChange");
			});
		},
		getSum : function() {
			var sum = 0;
			this.items.each(function() {
						sum += $(this).umibasketitem("getSum");
					});
			return sum;
		},
		getWeight : function() {
			var sum = 0;
			this.items.each(function() {
						sum += $(this).umibasketitem("getTotalWeight");
					});
			return sum;
		},
		getOrder : function() {
			return {
				'sum' : this.getSum(),
				'weight' : this.getWeight()
			};
		},
		verify:function(){
			
		},
		onCountChange : function() {

		}
	}

	$.fn.umibasketitem = function(settings) {
		var config = {
			selSum : "span[id$='price_total']",
			selTotalWeight : "span[id$='weight_total']",
			selPrice : "span[id$='price']",
			selWeight : "span[id$='weight']",
			selCountInput : "input[id$='count']"
		};

		if (typeof settings == "string") {
			var wrapper = this.first().data("basketitem");
			var otherArgs = Array.prototype.slice.call(arguments, 1);
			return wrapper[settings].apply(wrapper, otherArgs);
		}

		if (typeof settings == "object")
			$.extend(config, settings);

		return this.each(function() {
					$(this).data("basketitem", new BasketItem(this, config));
				});
	}

	function BasketItem(elem, config) {
		this.root = $(elem);
		this.count = this.root.find(config.selCountInput);
		this.sum = this.root.find(config.selSum);
		this.weight = this.root.find(config.selWeight);
		this.price = this.root.find(config.selPrice);
		this.totalWeight = this.root.find(config.selTotalWeight);
		this.init();
		this.attachEvents();
	}

	BasketItem.prototype = {
		init : function() {

		},
		attachEvents : function() {
			var me = this;
			var f = function() {
				me.onCountChange();
				me.root.trigger("basketItemChange");
			}
			me.count.change(f).keyup(f);
		},
		getSum : function() {
			var me = this;
			return me.getPrice() * me.getCount();
		},
		getTotalWeight : function() {
			return parseFloat(this.totalWeight.html());
		},
		getWeight : function() {
			return parseFloat(this.weight.html());
		},
		getPrice : function() {
			return parseFloat(this.price.html());
		},
		onCountChange : function() {
			this.updateTotalWeight();
			this.updateTotalPrice();
		},
		updateTotalWeight : function() {
			var me = this;
			me.totalWeight.html(me.getWeight() * me.getCount());
		},
		updateTotalPrice : function() {
			var me = this;
			me.sum.html(me.getPrice() * me.getCount());
		},
		getCount : function() {
			return parseInt(this.count.val());
		}
	}

	$.fn.deliverytypes = function(settings) {
		var config = {
			'selDeliveryTypes' : '.delivery_type'
		};

		if (typeof settings == "string") {
			var wrapper = this.first().data("deliverytypes");
			if (wrapper) {
				var otherArgs = Array.prototype.slice.call(arguments, 1);
				return wrapper[settings].apply(wrapper, otherArgs);
			}
		}

		if (typeof settings == "object")
			$.extend(config, settings);

		return this.each(function() {
					$(this).data("deliverytypes",
							new DeliveryTypes(this, config));
				});
	}

	function DeliveryTypes(elem, config) {
		this.root = $(elem);
		this.types = this.root.find(config.selDeliveryTypes);
		this.order = config.order;
		this.init();
		this.attachEvents();
	}

	DeliveryTypes.prototype = {
		init : function() {
			this.types.deliverytype();
		},
		attachEvents : function() {
			var me = this;
			me.types.bind("changeTypes", function() {
						me.types.trigger("changeType");
						me.root.trigger("changeTypes");
					}).bind("changePrice", function(event, price) {
						me.root.trigger("changePrice", price);
					});
			me.root.bind("changeOrder", function(event, order) {
						me.types.trigger("changeOrder1", [order]);
					})
		},
		setOrder : function(order) {
			this.order = order;
			this.types.each(function() {
						$(this).deliverytype("setOrder", order);
					});
		},
		getActiveType : function() {
			var atype = false;
			this.types.each(function() {
						var dtype = $(this);
						if (dtype.deliverytype("isActive")) {
							atype = dtype;
						}
					});
			return atype;
		},
		recalc : function(order) {
			//this.types.trigger("changeOrder",order);  //
		}
	}

	$.fn.deliverytype = function(settings) {
		var config = {
			'selAddressesBlock' : '.addresses',
			'selAddresses' : '.address',
			'selRadio' : '.dname input:radio',
			'selPrice' : '#delivery_price',
			'selPaymentTypes' : '.payment_types'
		};

		if (typeof settings == "string") {
			var wrapper = this.first().data("deliverytype");
			var otherArgs = Array.prototype.slice.call(arguments, 1);
			return wrapper[settings].apply(wrapper, otherArgs);
		}

		if (typeof settings == "object")
			$.extend(config, settings);

		return this.each(function() {
					$(this)
							.data("deliverytype",
									new DeliveryType(this, config));
				});
	}

	function DeliveryType(elem, config) {
		this.root = $(elem);
		this.addressesBlock = $(config.selAddressesBlock);
		this.addresses = $(config.selAddresses);
		this.radio = this.root.find(config.selRadio);
		this.price = $(config.selPrice);
		this.paymentTypes = this.root.find(config.selPaymentTypes);
		
		this.order = null;
		this.address = null;

		this.calculator = CalculatorsFactory(this.root.attr("id"));

		this.init();
		this.attachEvents();
	}

	DeliveryType.prototype = {
		init : function() {
			this.radio.removeAttr("checked");
			//this.addressesBlock.hide();
			this.price.hide();
			this.addresses.deliveryaddress();
		},
		attachEvents : function() {
			var me = this;
			me.radio.change(function() {
						me.root.trigger("changeTypes");
					});
			me.root.bind("changeType", function() {
						if (me.radio.is(":checked") && me.addresses.length) {
							//me.addressesBlock.show();
							me.addresses.first().trigger("selectAddress");
						} else {
							//me.addressesBlock.hide();
							me.price.hide();
						}
					});
			me.addresses.bind("changeAddresses", function() {
						me.setAddress($(this).deliveryaddress("getAddress"));
						me.recalc();
					});
			me.root.bind("changeOrder1", function(event, order) {
						me.setOrder(order);
						me.recalc();
					});
		},
		setOrder : function(order) {
			this.order = order;
		},
		setAddress : function(address) {
			this.address = address;
		},

		setPrice : function(price) {
			this.price.find("b").html(price);
			this.price.show();
		},

		hasCheckedAddress : function() {
			var l = this.addresses.find("input:checked").size();
			return l > 0;
		},

		recalc : function() {
			var me = this;
			
			if (this.radio.is(":checked") && this.hasCheckedAddress()) {
				return this.calculator.calc(me.address, me.order, function(
								price) {
							me.setPrice(price);
							me.root.trigger("changePrice", price);
						});
			}
		},

		isActive : function() {
			return this.radio.is(":checked");
		},

		getPaymentTypes : function() {
			return this.paymentTypes.html();
		}
	}

	$.fn.deliveryaddress = function(settings) {
		var config = {
			'selRadio' : 'input:radio'
		};

		if (typeof settings == "string") {
			var wrapper = this.first().data("deliveryaddress");
			var otherArgs = Array.prototype.slice.call(arguments, 1);
			return wrapper[settings].apply(wrapper, otherArgs);
		}

		if (typeof settings == "object")
			$.extend(config, settings);

		return this.each(function() {
					$(this).data("deliveryaddress",
							new DeliveryAddress(this, config));
				});
	}

	function DeliveryAddress(elem, config) {
		this.root = $(elem);
		this.radio = this.root.find(config.selRadio);
		this.init();
		this.attachEvents();
	}

	DeliveryAddress.prototype = {
		init : function() {

		},
		attachEvents : function() {
			var me = this;
			me.radio.change(function() {
						if ($(this).is(":checked"))
							me.root.trigger("changeAddresses", $(this));
					});
			me.root.bind("selectAddress", function() {
						me.radio.attr("checked", "checked");
						me.root.trigger("changeAddresses");
					});
		},

		getAddress : function() {
			return addresses[this.radio.val()];
		}
	}

	function EMSDelivery() {
		this.url = "http://emspost.ru/api/rest/";
		this.locations = Array();// this.ready = false; this.lastprice = 0;
		this.init();
	}

	EMSDelivery.prototype = {
		init : function() {
			var me = this;
			
			jQuery.ajax({
						type : "GET",
						url : this.url,
						data : "method=ems.get.locations&type=cities&plain=false",
						dataType : "jsonp",
						success : function(response) {
							jQuery.each(response.rsp.locations, function(index, value) {
										me.locations[String.toUpperCase(value.name)] =value.value;
									});
							me.ready = true;
						}
					});
		},
		getCityIdent : function(city) {
			if (!this.ready)
				return
			"Servise not ready";
			var me = this;
			cityIdent = me.locations[city];
			return cityIdent;
		},

		getIdent : function(address) {
			var me = this;
			var ident = me.getCityIdent(address.city)
			if (ident != undefined) {
				return ident;
			}
			return address.region;
		},
		calc : function(address, order, callback) {
			var me = this;
			var to = me.getIdent(address);

			jQuery.ajax({
						type : "GET",
						url : this.url,
						data : {
							"method" : "ems.calculate",
							"from" : "city--kazan",
							"to" : to,
							"weight" : order.weight,
							"plain" : false
						},
						dataType : "jsonp",
						success : function(response) {
							if (response.rsp.stat == "ok") {
								me.lastprice = response.rsp.price;
								callback(response.rsp.price);
							} else {
								jQuery("#order_submit_button").attr("disabled","disabled");
								callback("Обговаривается отдельно с менеджером магазина. ");
								//callback(response.rsp.err.msg);
							}
						}
					});
			return this.lastprice;
		}
	}

	function MRussia() {

	};

	MRussia.prototype = {
		init : function() {

		},
		calc : function(address, order, callback) {
			callback($("#delivery_price").html());
			
		}
	}

	function CalculatorsFactory(type) {
		switch (type) {
			case ('EMS') :
				return new EMSDelivery();
				break;
			case ('IN_RUSSIA') :
				return new MRussia();
				break;
		}
	}

	$(function() {
				var basket = $(".umibasket").umibasket();

				umiBasket.prototype.updateBasket = function() {
					var __self = this;
					var hdl = function(oResponce) {
					
						__self.onUpdate(oResponce);
						basket.trigger("updateBasket",oResponce);
					}
					lLib.getInstance().makeRequest('/eshop/json_get_basket/?',
							hdl);
				}

				var dtypes = $('#delivery_types').deliverytypes();
				var ptBlock = $("#payment_types").hide();
				var adrBlockLength = $(".address").length;
				var ptBlockContent = ptBlock.find(".content");

				var basketSum = $("#order_total_discount");
				var deliverySum = $("#delivery_price");
				var deliverySumInput = $("input[name='delivery_price']");
				var totalSum = $("#totalsumm");

				dtypes.deliverytypes("setOrder", basket.umibasket("getOrder"));
				basket.bind("basketChange", function() {
							var order = $(this).umibasket("getOrder");
							dtypes.trigger("changeOrder", [order]);
						});
				dtypes.bind("changeTypes", function() {
					var atype = dtypes.deliverytypes("getActiveType");
					$("#delivery_payment_block").hide();
					$("#order_submit_button").attr('disabled', true);
					if (atype) {
						var payment_types = atype
								.deliverytype("getPaymentTypes");
						ptBlockContent.html(payment_types);
						if (payment_types && adrBlockLength) {
							ptBlock.show();
						} else {
							ptBlock.hide();

						}
					}
				}).bind("changePrice", function(event, price) {
							//$("#order_submit_button").attr('disabled', true);
							deliverySum.html(price);
							deliverySumInput.val(price);
							totalSum.html(parseInt(price)
									+ parseInt(basketSum.html()));
							//$("#order_submit_button").attr('disabled', false);
						});
			});
})(jQuery);

