
var HistoryManager;
window.addEvent('domready', function () {
	HistoryManager = new HistoryManagerX();
	HistoryManager.initialize({
		iframeSrc: top.baseUrl + '/_blank.html'
	});
	new PriceGuide();

	new ClearField('price-guide-search-field', ['filter']);

	$$('a.price-guide-basket-basket-link').addEvent('click', function (evt) {
		evt.stop();
		var url = top.siteUrl + '/prices/print';
		var width = 680;
		var height = 600;
		var title = 'dandadPrices';
		var x = (800 - width) / 2;
		var y = (600 - height) / 2;
		if (screen) {
			y = (screen.availHeight - height) / 2;
			x = (screen.availWidth - width) / 2;
		}
		var properties = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=' + width + ',height=' + height + ',screenX=' + x + ',screenY=' + y + ',top=' + y + ',left=' + x;
		window.open(url, title, properties);
	});

	HistoryManager.start();
});

var PriceGuide = new Class({
	history: null,
	current: null,
	basket: null,
	selected: [],
	results: null,
	currency: 'gbp',
	checkboxes: $H({}),
	currencySelector: null,
	initialize: function () {
		this.basket = new PriceGuide.Basket(this);
		this.basket.update();
		this.initCol($('price-guide-col1'));
		var regex = /^pg\/(\d+)\/?([A-Z]+)?\/?(\d+)?/;
		this.history = HistoryManager.register(
			'pg',								// key
			[],									// defaults
			function (values) {
				var url = new PriceGuide.Url(values);
				if (url.isSet()) {
					// compare the current with the new url
					var keys = ['group', 'medium', 'category'];
					var c = $H();
					keys.each(function (key) {
						c[key] = null;
					});
					if (this.current) {
						var c = this.current;
					}
					var urls = [];
					var urlStrings = [];
					var keys = ['group', 'medium', 'category'];
					keys.each(function (key, i) {
						if (url[key] != c[key]) {
							var args = [];
							for (var j = 0; j <= i; j++) {
								var v = url[keys[j]];
								args.push(v);
							}
							var u = new PriceGuide.Url(args);
							var s = u.toUrl();
							// prevent the same url from being loaded twice
							// this could happen when traversing back down
							if (!urlStrings.contains(s)) {
								urls.push(u)
								urlStrings.push(s);
							}
						}
					});
					urls.each(function (u) {
						this.load(u);
					}, this);
				}
			}.bind(this),						// onMatch
			function(values) {
				var url = new PriceGuide.Url(values);
				return url.toHash();
			}.bind(this),						// onGenerate
			regex,								// regex
			{}									// options
		);
		$('price-guide-search-form').addEvent('submit', function(evt) {
			evt.stop();
			var el = $(evt.target);
			this.search($('price-guide-search-field').get('value'));
		}.bind(this));

		var select = $$('.price-guide-select-currency select').pop();
		this.currencySelector = new PseudoSelect(select);
		this.currencySelector.addEvent('change', this.evtSelectCurrency.bind(this));
		this.setCurrency();
	},
	initCol: function (el) {
		el.getElements('li a').addEvent('click', this.evtLink.bindWithEvent(this));

		var ids = this.basket.getIds();
		ids.each(function (id) {
			var e = $(id);
			if (e) {
				e.set('checked', true);
			}
		});

		var labels = el.getElements('.price-guide-category-products label');
		if (labels) {
			this.checkboxes.empty();
			labels.addClass('replaced');
			labels.each(function (label) {
				var cb = new PseudoCheckbox(label);
				cb.addEvent('check', this.evtChecked.bind(this));
				cb.addEvent('uncheck', this.evtUnchecked.bind(this));;
				this.checkboxes.set(label.get('for'), cb);
			}, this);
		}

		el.getElements('a.price-guide-category-desc-more').addEvent('click', function (evt) {
			evt.stop();
			el.getElements('.price-guide-category-desc-summary').setStyle('display', 'none');
			el.getElements('.price-guide-category-desc-full').setStyle('display', 'block');
		}.bindWithEvent(this, el));
	},
	evtLink: function (evt) {
		var el = $(evt.target);
		var url = this.urlFromId(el.get('id'));
	},
	evtChecked: function (checkbox) {
		var id = checkbox.get('id');

		// add to basket
		var prices = $H({
			gbp: $(id + '-price-gbp').get('value').toInt(),
			usd: $(id + '-price-usd').get('value').toInt(),
			eur: $(id + '-price-eur').get('value').toInt()
		});
		var type = $(id + '-campaign').get('value');
		var name = checkbox.get('value');

		this.basket.add(id, name, type, prices);
	},
	evtUnchecked: function (checkbox) {
		var id = checkbox.get('id');
		this.basket.remove(id);
	},
	loaded: function (url, responseTree, responseElements, responseHTML, responseJavaScript) {
		var url = this.urlFromHref(url);

		var el = $('price-guide-col' + url.col);
		if (url.col == 4) {
			el.adopt(responseTree);
		}
		else {
			var col4 = $('price-guide-col4');
			$A(responseTree).each(function (e) {
				e = $(e);
				if ($type(e) == 'element' && e.hasClass('price-guide-category')) {
					if (this.current && this.current.col == url.col) {
						col4.adopt(e);
					}
				}
				else {
					el.adopt(e);
				}
			}, this);
		}
		this.filterResults();
		this.initCol(el);
		this.setCols();
	},
	load: function (url) {
		for (var i = url.col; i <= 4; i++) {
			$('price-guide-col' + i).empty();
		}
		for (var i = 0; i < 4; i++) {
			$$('#price-guide-heading' + i).removeClass('on');
		}
		$$('#price-guide-heading' + url.col).addClass('on');

		var old = this.current;
		this.current = url;
		this.fetch(url, old);
	},
	fetch: function (url, old) {
		this.setCols();
		var r = new Request.HTML({
			url: url.toUrl(),
			onSuccess: function () {
				var args = [url];
				args.extend($A(arguments));
				f = this.loaded.bind(this, args);
				f();
			}.bind(this),
			onFailure: function () {
				if (old) {
					this.current = old;
					this.setCols();
				}
				alert('Request failed');
			}.bind(this)
		}).send();
	},
	urlFromUrl: function (str) {
		if ($type(str) != 'string') {
			return str;
		}
	},
	urlFromHref: function (str) {
		if ($type(str) != 'string') {
			return str;
		}
		var str = new String(str);
		var p = str.indexOf('#');
		var hash = str.substr(p + 1);

		var parts = hash.split('/');
		parts = parts.slice(1);
		return new PriceGuide.Url(parts);
	},
	urlFromId: function (str) {
		var str = new String(str);
		var parts = str.split('-');
		parts = parts.slice(1);
		return new PriceGuide.Url(parts);
	},
	splitUrl: function (url) {
		var url = new String(url);
		var p = url.indexOf('#');
		var hash = url.substr(p + 1);

		var parts = hash.split('/');
		var str = parts.join('-');
		return this.split(str);
	},
	splitId: function (id) {
		var id = new String(id);
		var parts = id.split('-');
		parts = parts.slice(1);
		var str = parts.join('-');
		return this.split(str);
	},
	split: function (str) {
		var regex = /^(\d+)-?([A-Z]+)?-?(\d+)?/;
		var matches = regex.exec(str);
		var data = $H({
			group: null,
			medium: null,
			category: null,
			col: null
		});
		if (matches) {
			if (matches[1]) {
				data.group = matches[1];
				data.col = 2;
			}
			if (matches[2]) {
				data.medium = matches[2];
				data.col = 3;
			}
			if (matches[3]) {
				data.category = matches[3];
				data.col = 4;
			}
		}
		return data;
	},
	filterResults: function () {
		var data = this.results;
		if (!data) {
			return;
		}

		// filter groups
		$$('#price-guide-col1 a').each(function (el) {
			var parts = el.get('id').split('-');
			var id = parts.pop();
			var p = el.getParent();
			p.removeClass('filtered');
			if (!data.groups.contains(id)) {
				p.addClass('filtered');
			}
		});

		// filter mediums
		$$('#price-guide-col2 a').each(function (el) {
			var parts = el.get('id').split('-');
			var id = parts.pop();
			var p = el.getParent();
			p.removeClass('filtered');
			if (!data.mediums.contains(id)) {
				p.addClass('filtered');
			}
		});

		// filter categories
		$$('#price-guide-col3 a').each(function (el) {
			var parts = el.get('id').split('-');
			var id = parts.pop();
			var p = el.getParent();
			p.removeClass('filtered');
			if (!data.categories.contains(id)) {
				p.addClass('filtered');
			}
		});
	},
	search: function (q) {
		var url = top.siteUrl + '/prices/search/';
		var r = new Request.JSON({
			url: url,
			method: 'get',
			onSuccess: function (data) {
				data = $H(data)
				this.results = $H();
				data.each(function (value, key) {
					switch ($type(value)) {
						case 'object':
							// convert to an array
							value = $H(value).getValues();
							break;
						case 'array':
							break;
					}
					this.results[key] = value;
				}, this);
				this.filterResults();
			}.bind(this)
		}).send(Hash.toQueryString({
			q: q
		}));
	},
	evtSelectCurrency: function () {
		var currency = this.currencySelector.get('value');
		if (this.currency != currency) {
			this.setCurrency(currency);
		}
	},
	setCurrency: function (currency) {
		var currencies = ['gbp', 'usd', 'eur'];
		if (currency && currencies.contains(currency)) {
			this.currency = currency;
		}

		var el = $('price-guide-col4');
		currencies.each(function (c) {
			el.removeClass('price-guide-currency-' + c);
		});
		$('price-guide-col4').addClass('price-guide-currency-' + this.currency);

		this.currencySelector.set('value', this.currency);
		this.basket.update();
	},
	setCols: function () {
		var url = this.current;
		if (url.category) {
			var col = $('price-guide-col3');
			col.getElements('a').removeClass('on');
			var id = url.toId(url.group, url.medium, url.category);
			var el = $(id);
			if (el) {
				el.addClass('on');
			}
		}
		if (url.medium) {
			var col = $('price-guide-col2');
			col.getElements('a').removeClass('on');
			var id = url.toId(url.group, url.medium);
			var el = $(id);
			if (el) {
				el.addClass('on');
			}
		}
		if (url.group) {
			var col = $('price-guide-col1');
			col.getElements('a').removeClass('on');
			var id = url.toId(url.group);
			var el = $(id);
			if (el) {
				el.addClass('on');
			}
		}
	}
});

PriceGuide.Url = new Class({
	key: 'pg',
	baseUrl: '',
	group: '',
	medium: '',
	category: '',
	col: '',
	initialize: function () {
		var args = ($type(arguments[0]) == 'array') ? arguments[0] : arguments;
		this.group = $defined(args[0]) ? args[0] : null;
		this.medium = $defined(args[1]) ? args[1] : null;
		this.category = $defined(args[2]) ? args[2] : null;

		var n = 0;
		for (var i = 0; i < 3; i++) {
			if (!args[i]) {
				break;
			}
		}

		this.col = i + 1;
		this.baseUrl = top.siteUrl + '/prices/ajax/';
	},
	isSet: function () {
		return (this.group);
	},
	merge: function (sep, parts) {
		var args = ($type(arguments[1]) == 'array' ) ? arguments[1] : $A(arguments).slice(1);
		var parts = $A(args);
		if (!parts.length) {
			var parts = [
				this.group,
				this.medium,
				this.category
			];
		}
		var a = [];
		for (var i = 0; i < parts.length; i++) {
			if (parts[i]) {
				a.push(parts[i])
			}
		}
		return a.join(sep);
	},
	toId: function () {
		return this.key + '-' + this.merge('-', $A(arguments));
	},
	toUrl: function () {
		return this.baseUrl + this.merge('/', $A(arguments));
	},
	toHash: function () {
		return this.key + '/' + this.merge('/', $A(arguments));
	}
});


PriceGuide.Basket = new Class({
	priceguide: null,
	items: [],
	cookie: null,
	options: {
		cookie: 'price-guide'
	},
	initialize: function(priceguide) {
		this.priceguide = priceguide;
		this.cookie = Cookie.read(this.options.cookie);
		if (this.cookie) {
			var c = JSON.decode(this.cookie);
			this.items = $A(c.items) || [];
			this.priceguide.currency = c.currency;
		}
	},
	add: function (id, name, type, prices) {
		this.items.push($H({
			id: id,
			name: name,
			type: type,
			prices: prices
		}));
		this.update();
		var elements = $$('#price-guide-basket-entries .price-guide-basket-entry');
		if (elements) {
			elements.getLast().highlight('#FFC100');
		}
	},
	remove: function (id) {
		var temp = [];
		var n = -1;
		this.items.each(function (item, i) {
			if (item.id != id) {
				temp.push(item);
			}
			else {
				n = i;
			}
		});
		if (n >= 0) {
			this.items = temp;
			var elements = $$('#price-guide-basket-entries .price-guide-basket-entry');
			var el = elements[n];
			el.get('tween').addEvent('complete', this.update.bind(this));
			el.highlight('#FFC100');
		}
	},
	getIds: function () {
		var ids = [];
		this.items.each(function (item) {
			ids.push(item.id);
		});
		return ids;
	},
	update: function () {
		var c = $H({
			currency: this.priceguide.currency,
			items: this.items
		});
		Cookie.write(this.options.cookie, JSON.encode(c), {'path': top.siteUrl + '/'});
		$('price-guide-basket-entries').empty();
		this.items.each(function (item) {
			var el = new Element('p', {'class': 'price-guide-basket-entry'}).inject($('price-guide-basket-entries'));
			if (!pgCampaigns[item.type]) {
				return;
			}
			var type = pgCampaigns[item.type];
			var url = this.priceguide.urlFromId(item.id);
			var e = new Element('a', {href: '#' + url.toHash(), text: item.name + ' / ' + type}).inject(el);
			el.set('html', el.get('html') + ' ');
			var e = new Element('a', {href: '#', text: 'Remove', 'class': 'price-guide-basket-entry-remove'}).inject(el);
			e.addEvent('click', this.evtClick.bindWithEvent(this, item.id));
		}.bind(this));
	},
	evtClick: function (evt, id) {
		evt.stop();
		var cb = this.priceguide.checkboxes.get(id);
		if (cb) {
			// prevent double clicking from calling it twice
			if (cb.get('checked')) {
				cb.uncheck();
				this.remove(id);
			}
		}
		else {
			this.remove(id);
		}
	},
	getTotal: function () {
		var total = 0;
		this.items.each(function (item) {
			total += item.prices[this.priceguide.currency];
		}, this);
		switch (this.priceguide.currency) {
			case 'gbp': total = '£' + total; break;
			case 'usd': total = '$' + total; break;
			case 'eur': total = '€' + total; break;
		}
		return total;
	}
});