// Объявление глобальных переменных
var YES = true,
	NO = false,
	Observatory = $({});

// Объявление класса Blocnot
var Blocnot = function() {
	var containerSelector = this.containerSelector = '.container';
	this.container = $(containerSelector);
	this.images = {
		length: 0,
		loading: 0,
		push: function(url, selector) {
			if (!arguments.length) return NO;
			if (this[url]) {
				return this[url].loaded;
			} else {
				var dummy = this.createDummy(url);
				this.length++;
				this.loading++;
				this[url] = {
					loaded: NO,
					selector: selector,
					dummy: dummy
				}
				Observatory.bind('loaded.' + dummy.attr('class'), function(event, url) {
					var link = this[url];
					link.loaded = YES;
					this.appendImg(link.selector, url);
					this.loading--;
				}.bind(this));
				return NO;
			}
		},
		createDummy: function(url) {
			var img = $('<img>').addClass('dummy_' + (this.length + 1)).appendTo('body');
			return img
				.bind('load', function() {
					var target = $(this);
					Observatory.trigger('loaded.' + target.attr('class'), [target.attr('src')]);
					target.remove();
				})
				.attr('src', url);
		},
		appendImg: function(selector, url) {
			$(selector).attr('style', 'background-image:url("' + url + '"); _background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src="' + url + '", sizingMethod="crop");');
		}
	};
	this.ready = NO;
	this.formatRegEx = /--(.*[^\s])/;
	this.oldImageList = {};

	this.init();
};

// Расширение прототипа класса Blocknot
Blocnot.prototype = {
	init: function() {
		var chroma = $('.b-form-cell-chroma-block'),
			formats = this.formatRegEx.exec($('.g-format-item.selected a').attr('class'));

		chroma.each(function(i, block) {
			this.setChroma($(block));
		}.bind(this));

		this.setListeners();
		formats && this.checkCustomFormats(formats[1]);

		this.fixForms();
		$('.caption-btn').each(function(i, tab) {
			tab = $(tab);

			var location = window.location.hash.substr(1),
				linkHash = this.linkToHash(tab.attr('href')),
				reg = new RegExp(location, 'i'),
				regData = reg.exec(linkHash);

			if (regData || linkHash == location) {
				tab.trigger('click');
			}
		}.bind(this));

		$('select', chroma).trigger('change');
		this.ready = YES;
	},

	setChroma: function(container) {
		var reg = /selected--s(\d+)/g,
			colors = $('.b-form-cell-chroma-saturation', container),
			colorsClass = colors.attr('class'),
			selectbox = $('select', container);

		colors.attr('class', colorsClass.replace(reg, 'selected--s' + selectbox.val()));
	},

	checkCustomFormats: function(selector) {
		var fields = $('.page-dim input'),
			isOther = (selector == 'other'),
			map = $('.page-size');

		fields
			[isOther ? 'removeClass' : 'addClass']('disabled')
			.attr('disabled', !isOther);
		map.removeClass().addClass(map.selector.substring(1) + ' ' + selector);
	},

	setListeners: function() {
		var timerID = null,
			ajax = null;

		this.container
			.delegate('.click-area', 'click', function(event) {
				var trigger = $(event.currentTarget),
					selector = '.' + trigger.attr('rel'),
					target = trigger.closest(selector),
					regData = this.formatRegEx.exec(trigger.attr('class'));

				$(selector)
					.removeClass('selected')
					.find('input[type="radio"]:checked')
					.attr('checked', NO);
				target.addClass('selected');
				target.find('input[type="radio"]').attr('checked', YES);
				regData && this.checkCustomFormats(regData[1]);
				this.request(trigger.attr('href'));
				return NO;
			}.bind(this))
			.delegate('.clickarea', 'click', function(event) {
				var trigger = $(event.currentTarget),
					target = trigger.parent();

				if (target.parent().hasClass('column')) {
					target
						.parent()
						.addClass('selected')
						.siblings('.selected')
						.removeClass('selected');
					trigger.next().trigger('click');
				}
				this.request(trigger.attr('href'), function() {
					$('body').trigger('reload-gallery');
				});
				return NO;
			}.bind(this))
			.delegate('.b-form-cell-paper_type-type input', 'change', function(event) {
				var parent = $(event.target).closest('.b-form-cell-paper_type'),
					type = $('input[name="paper_type"]', parent),
					density = $('.b-form-cell-paper_type-density', parent),
					selectedClassName = 'b-form-cell-paper_type--selected',
					data = {
						step: 1,
						paper_type: type.val(),
						paper_density: $('input:checked', density).val()
					};

				parent
					.addClass(selectedClassName)
					.siblings()
					.removeClass(selectedClassName);
				this.request(data);

				return NO;
			}.bind(this))
			.delegate('.b-form-cell-chroma-saturation-count select', 'change', function(event) {
				var target = $(event.target),
					parent = target.closest('.b-form-cell-chroma-block'),
					data = {
						step: 1
					};

				this.setChroma(parent);
				target.siblings('span').html(target.val());
				data[target.attr('name')] = target.val();
				this.ready && this.request(data);

				return NO;
			}.bind(this))
			.delegate('.b-form-cell-chroma-saturation-trigger', 'click', function(event) {
				var target = $(event.target),
					parent = target.closest('.b-form-cell-chroma-block'),
					selectbox = $('select', parent),
					index = target.attr('rel');

				selectbox
					.val(index)
					.trigger('change');

				return NO;
			}.bind(this))
			.delegate('.page-dim input', 'keydown', function(event) {
				var target = $(event.currentTarget),
					text = target.val(),
					symbol = String.fromCharCode(event.keyCode),
					regEx = /[^\d]/,
					acceptedCodes = {
						8: YES,
						9: YES,
						37: YES,
						39: YES,
						46: YES
					};

				if (event.keyCode == 38) {
					target.val(parseInt(text, 10) + 1);
				} else if (event.keyCode == 40) {
					target.val(parseInt(text, 10) - 1);
				}

				if (parseInt(target.val(), 10) < 10) {
					target.val(10);
					return NO;
				}

				if (!acceptedCodes[event.keyCode] && regEx.exec(symbol)) {
					return NO;
				}
			}.bind(this))
			.delegate('.page-dim input', 'keyup', function(event) {
				var target = $(event.currentTarget),
					name = target.attr('name'),
					text = target.val();

				timerID && clearTimeout(timerID);
				timerID = setTimeout(function() {
					this.request(name + '=' + (parseInt(text, 10) > 10 ? text : 10));
				}.bind(this), 500);
				return NO;
			}.bind(this))
			.delegate('.gallery a', 'click', function(event) {
				var trigger = $(event.currentTarget),
					target = trigger.closest('.item');

				target
					.addClass('selected')
					.siblings('.selected')
					.removeClass('selected');
				this.request(trigger.attr('href'), function() {
					var btn = $('.big-btn.disabled'),
						params = btn.attr('rel');

					if (params) {
						btn.attr('href', params);
					};
					btn
						.removeClass('disabled')
						.next()
						.slideUp('slow');
					Cufon.replace('.big-btn .typeface-js');
				});
				return NO;
			}.bind(this))
			.delegate('.caption-btn', 'click', function(event) {
				var target = $(event.currentTarget),
					url = target.attr('href'),
					additionalUrl = target.attr('rel'),
					jslink = window.location.hash,
					constForm = $('.recheck-me'),
					selectTab = function(target, data) {
						target
							.addClass('disabled self')
							.siblings('.caption-btn')
							.removeClass('disabled self');
						data && target
							.next()
							.html(data);
						target
							.next()
							.addClass('fixie')
							.slideDown('slow', function() {
								$(this).removeClass('fixie');
							})
							.siblings('.dummy-cont')
							.addClass('fixie')
							.slideUp('slow', function() {
								$(this).removeClass('fixie');
							});
					};

				ajax && ajax.abort();

				if (target.next().html() == '') {
					ajax = this.request({}, function(request) {
						selectTab(target, request);
						this.fixForms();
					}.bind(this), url.split('?')[0] + '/ajax' + additionalUrl, 'get', YES);
				} else {
					selectTab(target);
				}
				jslink = this.linkToHash(url);
				window.location.hash = jslink;
				this.request({
					step: 2,
					design_variant: jslink.split('#substep')[1]
				});
				constForm.attr('action', constForm.attr('action').split('#')[0] + jslink);
				return NO;
			}.bind(this));

		$('body').bind('reload-gallery', function() {
			var preloader = $('#gallery_preloader');

			preloader.show();
			$.get('/gallery', function(request) {
				$('#gallery').html(request);
				preloader.hide();
			});
		});
	},

	linkToHash: function(url) {
		var reg = /\/([^\/]+)$/,
			regData = reg.exec(url);

		return regData ? regData[1] : '?';
	},

	fixForms: function() {
		$('.fix-it').each(function(i, form) {
			form = $(form);

			var data = form.attr('action').split('/substep'),
				url = data[0] + '#substep' + data[1];

			form
				.attr('action', url)
				.removeClass('fix-it');
		});
	},

	request: function(data, callback, url, type, onlyCallback) {
		var data = data.length ? data.replace('?', '') : data;

		return $[type || 'getJSON'](url || '/calc', data, function(request) {
			if (!onlyCallback) {
				if (request.success == 'true') {
					$('#this-price, #this-price2').html(request.price);
	
					if (request.additional) {
						$('#this-price').next().html(request.additional);
					} else {
						$('#this-price').next().html('');
					}
					if (request.price == request.price_next) {
						$('#tvr1').hide();
						$('#tvr2').show();
					} else {
						$('#tvr2').hide();
						$('#tvr1').show();
					}
					if (request.count_next) {
						$('#new-count').html(request.count_next);
					}
					if (request.price_next) {
						$('#new-price').html(request.price_next);
					}
					if (request.total) {
						$('#total-price, #total-price2').html(request.total);
					}
					if (request.css) {
						$('.image-thumbnail').removeClass().addClass('image-thumbnail').addClass(request.css.join(' ').toLowerCase());
					}
					if (request.size) {
						$('.image-thumbnail .img-height').html(request.size[0]+' мм');
						$('.image-thumbnail .img-width').html(request.size[1]+' мм');
						$('input[name="format_w"]').val(request.size[0]);
						$('input[name="format_h"]').val(request.size[1]);
					}
					if (request.images) {
						this.preloadImages(request.images);
					}
				} else if (request.message) {
					alert(request.message);
				}
			}
			callback && callback(request);
		}.bind(this));
	},

	preloadImages: function(list) {
		var total = 0,
			imgMap = {
				0: '.image-thumbnail .main-img',
				1: '.image-thumbnail .inner-img',
				2: '.image-thumbnail .submain-img',
				3: '.image-thumbnail .design-img'
			},
			hasNew = NO,
			newList = {};

		$(list).each(function(i, img) {
			if (img && !this.oldImageList[img]) {
				hasNew = YES;
			};

			if (img) {
				var preloader = $('<img>').attr('rel', i);

				if (!this.oldImageList[img]) {
					hasNew = YES;
				};
				total++;
				newList[img] = YES;
				
				console.log(img)

				preloader
					.bind('load', function(event) {
						var image = $(event.target);
						
						console.log(image)

						$(imgMap[image.attr('rel')]).attr('style', 'background-image:url(' + image.attr('src') + '); _background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src="' + image.attr('src') + '", sizingMethod="crop");');
						total--;

						if (!total) {
							this.hidePreloader();
						}
					}.bind(this))
					.attr('src', img.toLowerCase());
			}
		}.bind(this));
		this.oldImageList = newList;

		if (hasNew) {
			this.showPreloader('формирование предпросмотра...');
		}
	},

	showPreloader: function(text) {
		$('.image-thumbnail').hide()
		$('#thumbnail_preloader').show().html(text);
	},

	hidePreloader: function() {
		$('#thumbnail_preloader').hide();
		$('.image-thumbnail').fadeIn('slow');
	}
};

// Расширение прототипа функций
$A = Array.from = function(iterable) {
	if (!iterable) {
		return [];
	}

	if (iterable.toArray) {
		return iterable.toArray();
	} else {
		var results = [];
		for (var i = 0, length = iterable.length; i < length; i++) {
			results.push(iterable[i]);
		}
		return results;
	}
};
$.extend( Function.prototype, {
	bind: function() {
		var __method = this, args = $A(arguments), object = args.shift();

		return function() {
			return __method.apply(object, args.concat($A(arguments)));
		};
	}
});

// Иницилизация класса Blocknot по onDomReady
$(function() {
	new Blocnot();
});
