(function($) {
	
	var basket = (function() {
		
		var BASKET_URL = '/2009-sys/system-feeds/basket';
		
		function load() {
			$.post(BASKET_URL, {
				cm_action: 'create'
			}, run);
		}
		
		function queue(fn) {
			if (!ready) {
				queued.push(fn);
				load();
			}
			else fn();
		}
		
		function run() {
			var fn;
			ready = true;
			while (fn = queued.shift()) fn();
		}
		
		function update(data) {
			$('span.basket-item-count').text(data.result.length);
		}
		
		function updateCounters() {
			$('#saved-pages tbody .counter').html(function(i) {
				return (i + 1) + '.';
			}); 
		}
		
		var api = {}, ready = false, queued = [];
		
		api.add = function(pageId, content) {
			queue(function() {
				$.post(BASKET_URL, {
					cm_action: 'add',
					id: pageId,
					content: content
				}, update, 'json');
			});
		};
		
		api.clear = function() {
			queue(function() {
				$.post(BASKET_URL, {
					cm_action: 'clear'
				}, update, 'json');
			});
		};
		
		api.del = function(pageId) {
			queue(function() {
				$.post(BASKET_URL, {
					cm_action: 'del',
					id: pageId
				}, update, 'json');
			});
		};
		
		api.sort = function(map) {
			queue(function() {
				$.post(BASKET_URL, {
					cm_action: 'sort',
					order: map
				}, update, 'json');
			});
		};
		
		$('#tool-save-page').live('click', function(e) {
			e.preventDefault();
			if ($(this).hasClass('del')) {
				api.del(CM_PAGEID);
				$('#tool-save-page.del')
					.removeClass('del')
					.addClass('add')
					.text('Save page');
			}
			else {
				api.add(CM_PAGEID, $('#content').html());
				$('#tool-save-page.add')
					.removeClass('add')
					.addClass('del')
					.text('Remove page');
			}
			tip.display();
		});
		
		$('#saved-pages a.remove').live('click', function(e) {
			var row = $(this).closest('tr');
			api.del(row.attr('id').replace(/[^\d]/g, ''));
			if (row.siblings('tr').size()) {
				e.preventDefault();
				if (!row.prev('tr').size()) {
					row.next('tr').addClass('first');
				}
				row.remove();
				updateCounters();
			}
		});
		
		$('#saved-pages .sort').live('mousedown', function(e) {
		
			function deny(e) {
				return false;
			}
			
			function detach() {
				$(document).unbind({
					mouseup: up,
					mousemove: move,
					selectstart: deny
				});
			}
			
			function up(e) {
				detach();
				var map = {};
				$('#saved-pages tbody tr').each(function(i) {
					map['page:' + this.id.substr('page-'.length)] = i;
				});
				api.sort(map);
			}
			
			function move(e) {
				var pos = row.offset(), prev, next;
				if (e.pageY < pos.top) {
					prev = row.prev('tr');
					if (!prev.size()) return;
					prev.before(row).removeClass('first');
					if (row.is(':first-child')) row.addClass('first');
					updateCounters();
				}
				else if (e.pageY > pos.top + row.height()) {
					next = row.next('tr');
					if (!next.size()) return;
					next.after(row);
					row.removeClass('first');
					if (next.is(':first-child')) next.addClass('first');
					updateCounters();
				}
			}
			
			var row = $(this).closest('tr');
			
			$(document).bind({
				mouseup: up,
				mousemove: move,
				selectstart: deny
			});
			
			e.preventDefault();
		});
		
		return api;
	
	})();
	
	var tip = (function() {
		
		function bind(el) {
			context = el;
		}
			
		function cancel() {
			clearTimeout(timer);
		}
		
		function create() {
			return $(document.createElement('div')).addClass('tip').html([
				'<div class="tip-content"></div>',
				'<div class="tip-corners">',
					'<div class="ne"></div>',
					'<div class="se"></div>',
					'<div class="sw"></div>',
					'<div class="nw"></div>',
					'<div class="pin"></div>',
				'</div>'
			].join(''));
		}
	
		function display(callback) {
			cancel();
			var o = $(context).offset();
			if (!isNaN(o.left)) { // timing issue
				dom.find('.tip-content').text($(context).attr('title') || $(context).text());
				dom.css('visibility', 'hidden');
				$(document.body).append(dom);
				dom.css({
					left: o.left + ($(context).outerWidth() / 2) - dom.outerWidth() / 2,
					top: o.top - dom.outerHeight(),
					visibility: 'visible'
				});
			}
			if (typeof callback == 'function') callback();
		}
		
		function hide(callback) {
			cancel();
			lastCallback = callback;
			timer = setTimeout(function() {
				// retain event handlers
				var el = dom.get(0);
				if (el.parentNode) el.parentNode.removeChild(el);
				if (typeof callback == 'function') callback();
			}, 200);
		}
		
		function hideAgain() {
			hide(lastCallback);
		}
		
		var api = {}, context, timer, lastCallback, dom = create();
		
		dom.hover(cancel, hideAgain);
		
		api.bind = bind;
		api.display = display;
		api.hide = hide;
		
		$(window).scroll(hideAgain);
		
		return api;
		
	})();
	
	$(function() {
	
		function setAjaxUrl(url) {
			var join = (url.indexOf('?') != -1) ? '&' : '?';
			$('#tool-print').attr('href', url + join + $.param({ cm_print_version: 1}));
			if (window.pageTracker && pageTracker._trackPageview) {
				pageTracker._trackPageview(url);
			}
			return url;
		}
		
		function setAjaxContent(data) {
			document.title = data.match(/<title>([\s\S]+)<\/title>/)[1];
			CM_PAGEID = data.match(/CM_PAGEID = (\d+)/)[1];
		}
		
		// preload
		(function() {
			var images = [];
			$.each([
				'/files/outokumpu/img/search-go-over.png',
				'/files/outokumpu/img/text-size-dec-over.png',
				'/files/outokumpu/img/text-size-inc-over.png',
				'/files/outokumpu/img/tip.gif',
				'/files/outokumpu/img/tip-bg.gif',
				'/files/outokumpu/img/basket-del.gif',
				'/files/outokumpu/img/basket-add.gif'
			], function() {
				var img = new Image();
				img.src = this;
				images.push(img);
			});
		})();
	
		var toolbar = new function() {
		
			var tools = $('#tools');
			var minY = 291, margin = 27, lastY;
			var timer;
			
			function follow(delay) {
				move($(window).scrollTop() + margin, undefined, delay);
			}
			
			function move(to, callback, speed) {
				if (lastY === to) {
					if (callback) callback();
					return;
				}
				lastY = to = Math.max(minY, to);
				tools.toggleClass('scrolled', to > minY);
				tools.animate({ top: to }, speed, callback);
			}
			
			function reset(callback) {
				follow(150);
			}
			
			function scrolled() {
				return tools.is('.scrolled');
			}
			
			function tilt(by, callback) {
				move($(window).scrollTop() + margin + by, callback, 150);
			}
			
			this.follow = follow;
			this.move = move;
			this.reset = reset;
			this.scrolled = scrolled;
			this.tilt = tilt;
			
			return; // :(
			
			$(window).scroll(function() {
				clearTimeout(timer);
				timer = setTimeout(function() { follow(250); }, 450);
			});
			
		};
		
		var textSize = new function() {
		
			var steps = [], current = 0;
			
			function init() {
				if (steps.length) return;
				var rawSize = $(document.body).css('font-size');
				var value = parseFloat(rawSize);
				var unit = String(rawSize).replace(/^[\d.]+/, '');
				steps[0] = rawSize;
				var ratio = 1/6;
				for (var i = -1; i <= 3; ++i) {
					steps[i] = value * Math.pow(1 + ratio, i) + unit;
				}
			}
			
			function set(step) {
				init();
				if (!steps[step]) return;
				var size = steps[step];
				$(document.body).css('font-size', size);
				current = step;
			}
			
			this.decrease = function() {
				set(current - 1);
			};
			
			this.increase = function() {
				set(current + 1);
			};
			
		};
		
		var search = function(input, items) {
		
			var activeItem = $().eq(-1);
			var lastValue = input.val();
			var list = $(document.createElement('ul'))
				.addClass('autocomplete')
				.attr('id', input.attr('id') + '-autocomplete')
				.attr('autocomplete', 'off')
				.bind('click', select)
				.bind('mouseover mouseout', onItemHover)
				.fadeTo(0, 0)
				.insertAfter(input.closest('form'));

			function build(label, query) {
				var start = label.substr(0, query.length);
				if (start.toLowerCase() === query.toLowerCase()) {
					var item = $(document.createElement('li'));
					item.text(label.substr(query.length));
					item.prepend($(document.createElement('span')).addClass('hilite').text(start));
					return item.get(0);
				}
				return null;
			}			
			
			function hide() {
				lastLength = 0;
				activeItem.removeClass('active').eq(-1);
				list.fadeTo('slow', 0, function() {
					$(this).hide();
				});
			}
			
			function move(e) {
				activeItem.removeClass('active');
				switch (e.keyCode) {
					case 13: // enter
						select(e);
						break;
					case 38: // up
						activeItem = activeItem.prev('li');
						if (!activeItem.size()) activeItem = list.children(':last');
						e.preventDefault();
						break;
					case 40: // down
						activeItem = activeItem.next('li');
						if (!activeItem.size()) activeItem = list.children(':first');
						e.preventDefault();
						break;
				}
				activeItem.addClass('active');
			}
			
			function onItemHover(e) {
				activeItem.removeClass('active');
				var target = $(e.target);
				if (target.is('ul')) return;
				target = target.closest('li');
				target.toggleClass('active', e.type == 'mouseover');
				activeItem = target;
			}
			
			function update() {
				var val = input.val();
				if (val === lastValue) return;
				lastValue = val;
				if (val.length < 2) return hide();
				var found = search(input.val());
				if (found.childNodes.length) {
					list.empty().get(0).appendChild(found);
					show();
				}
				else hide();
			}
			
			function search(query) {
				var container = document.createDocumentFragment();
				for (var i = 0, l = items.length; i < l; ++i) {
					var item = build(items[i].term, query);
					if (item) container.appendChild(item);
				}
				return container;
			}
			
			function select(e) {
				if (!activeItem.size()) return;
				input.val(activeItem.text());
				input.get(0).form.submit();
			}
			
			function show() {
				list.stop(true).show().fadeTo('fast', 1);
			}
			
			input.bind('keydown', move);
			input.bind('keyup', update);
			input.bind('focus', update);
			input.bind('blur', hide);
		
		};
		
		(function() { // board of directors
		
			// slightly different in IE but that shouldn't matter much
			function createReflection(img, size) {
				var loader = new Image();
				var canvas = document.createElement('canvas');
				if (!canvas || !canvas.getContext) {
					if (loader.runtimeStyle && loader.runtimeStyle.filter !== undefined) {
						loader.className = 'reflection';
						loader.onload = function() {
							this.style.filter = [
								'flipv',
								'progid:DXImageTransform.Microsoft.Alpha(opacity=32, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=' + (size * 100) + ')'
							].join(' ');
						};
						loader.src = img.src;
						return loader;
					}
					else return null;
				}
				canvas.className = 'reflection';
				loader.onload = function() {
					var g, height, width, gradient;
					g = canvas.getContext('2d');
					height = size * this.height;
					width = this.width;
					canvas.width = width;
					canvas.height = height;
					g.translate(0, height);
					g.scale(1, -1);
					g.drawImage(this, 0, canvas.height - this.height + 1, width, this.height);
					g.globalCompositeOperation = 'destination-out';
					gradient = g.createLinearGradient(0, 0, 0, height);
					gradient.addColorStop(1, 'rgba(0, 0, 0, 0.68)');
					gradient.addColorStop(0.85, 'rgba(0, 0, 0, 0.75)');
					gradient.addColorStop(0.7, 'rgba(0, 0, 0, 0.9)');
					gradient.addColorStop(0, 'rgba(0, 0, 0, 1)');
					g.fillStyle = gradient;
					g.fillRect(0, 0, width, height);
					canvas = null;
				};
				loader.src = img.src;
				return canvas;
			};
			
			function prepareSlide() {
				return; // not needed anymore
				$('#bod-display div.photo img').each(function() {
					$(this).after(createReflection(this, 0.122));
				});
			}
			
			function move(to, fallback) {
				if (to.is('.bod-active')) return;
				if (!to.size()) to = fallback;
				$('#bod-list > .bod-active').removeClass('bod-active');
				to.addClass('bod-active');
				var url = to.find('a').attr('href');
				$('#bod-cover').stop().animate({ width: 0 }, 250, function() {
					$.get(setAjaxUrl(to.find('a').attr('href')), function(data) {
						setAjaxContent(data);
						$('#bod-profile').html(data.match(/<!-- BOD_PROFILE_START -->([\s\S]*?)<!-- BOD_PROFILE_END -->/)[0]);
						prepareSlide();
						$('#bod-cover').animate({ width: $('#bod-profile').width() }, 250);
					});
				});
			}
			
			function go(e) {
				e.preventDefault();
				move($(this));
			}
			
			function next(e) {
				e.preventDefault();
				move($('#bod-list > .bod-active').next(), $('#bod-list > .bod:first-child'));
			}
			
			function prev(e) {
				e.preventDefault();
				move($('#bod-list > .bod-active').prev(), $('#bod-list > .bod:last-child'));
			};
			
			$('#bod-display div.next a').click(next);
			$('#bod-display div.prev a').click(prev);
			$('#bod-list > .bod').click(go);
			
			prepareSlide();
			
		})();
		
		(function() { // infobox
		
			function activate() {
				$(this).closest('.infobox-tab-group')
					.children('div')
					.addClass('infobox-inactive')
					.eq($(this).prevAll('h3').size())
					.removeClass('infobox-inactive');
				$(this).removeClass('infobox-inactive-tab')
					.siblings('h3')
					.addClass('infobox-inactive-tab');
			}
	
			$('div.infobox-grouped-tab').each(function() {
				if ($(this).parent().is('.infobox-tab-group')) return;
				var first = !$(this).prev().is('.infobox-tab-group');
				if (first) {
					$(this).wrap($(document.createElement('div')).addClass('infobox-tab-group'));
				}
				else {
					$(this).addClass('infobox-inactive')
						.prev()
						.append(this);
				}
				$(this).parent('.infobox-tab-group')
					.children('div')
					.eq(0)
					.before($(this).find('h3')
						.clone()
						.addClass('infobox-tab')
						.toggleClass('infobox-inactive-tab', !first)
						.click(activate)
						.not(':has(span)')
						.wrapInner(document.createElement('span'))
						.end());
			});
		
		})();
		
		(function() { // image popups
		
			function dim(callback) {
				$(document.createElement('div'))
					.attr('id', 'dim')
					.css('opacity', 0)
					.appendTo(document.body)
					.click(undim)
					.fadeTo(150, 0.6, callback);
				$(document.body).addClass('dimmed');
			}
			
			function undim(e) {
				if (e) e.preventDefault();
				$('#dim-box').fadeOut('fast', function() {
					$(this).remove();
					$('#dim').fadeOut('fast', function() {
						$(this).remove();
						
					});
				});
				$(document.body).removeClass('dimmed');
			}
			
			function box(src) {
				var loader = new Image();
				loader.onload = function() {
					$('#dim').removeClass('dim-loading');
					$(document.createElement('div'))
						.attr('id', 'dim-box')
						.html([
							'<div class="controls">',
								'<a href="#" class="print">Print this</a>',
								'<a href="#" class="close">Close</a>',
							'</div>',
							'<div class="corners">',
								'<div class="ne"></span>',
								'<div class="se"></span>',
								'<div class="sw"></span>',
								'<div class="nw"></span>',
							'</div>'
						].join(''))
						.prepend(loader)
						.appendTo(document.body)
						.css({
							marginLeft: -(loader.width / 2) - 30,
							marginTop: -(loader.height / 2) - 45,
							opacity: 0
						})
						.fadeTo('fast', 1)
						.find('a.close')
							.click(undim)
							.end()
						.find('a.print')
							.click(print);
				};
				$('#dim').addClass('dim-loading');
				loader.src = src;
			}
			
			function print(e) {
				if (e) {
					e.preventDefault();
					e.stopPropagation();
				}
				$(document.body).addClass('dim-printing');
				window.print();
				$(document.body).removeClass('dim-printing');
			}
		
			$('a[target=_blank]:has(img)')
				.live('click', function(e) {
					e.preventDefault();
					this.blur();
					src = this.href;
					dim(function() {
						box(src);
					});
				})
				.each(function() {
					var float = $(this).find('img').css('float');
					$(this).addClass('zoom-image')
						.append('<span class="zoom">Zoom</span>')
						.toggleClass('zoom-image-' + float, float != 'none');
				});
			
		})();

		$.getJSON('/2009-sys/system-feeds/keywords', { cm_language: CM_TEMPLATELANG }, function(data) {
			$('div.search input').each(function() {
				new search($(this), data.result || []);
			});
		});
		
		$('#tools a.toggle').click(function(e) {
			var tools = $('#tools');
			if (tools.is('.collapsed')) {
				tools.animate({ right: 0 }, 150);
				tools.removeClass('collapsed');
			}
			else {
				tools.animate({ right: -159 }, 150);
				tools.addClass('collapsed');
			}
			e.preventDefault();
		});
		$('#tools .actions a').hover(
			function() {
				if ($('#tools').is(':animated')) return;
				tip.bind(this);
				tip.display();
			},
			function() {
				tip.hide();
			}
		);
		$('#text-size-dec').click(textSize.decrease);
		$('#text-size-inc').click(textSize.increase);
		$('div.downloads a.select-all, div.downloads a.select-none').click(function(e) {
			e.preventDefault();
			var checked = $(this).is('.select-all');
			$(this).closest('.downloads').find('input:checkbox').each(function() {
				this.checked = checked;
			});
			this.blur();
		});
		$('a.cm-email').each(function() {
			var val, i, mail = '';
			val = $(this).attr('href').replace(/^mailto:/, '');
			for (i = val.length - 2; i >= 0; i -= 2) {
				mail += String.fromCharCode(parseInt(val.substr(i, 2), 16));
			}
			$(this).attr('href', 'mailto:' + mail);
		});
		$('a.open-popup').live('click', function(e) {
			var options = [
				'width=650',
				'resizable=yes',
				'scrollbars=yes',
				'menubar=no',
				'toolbar=no',
				'location=yes',
				'directories=no',
				'status=yes'
			];
			if (window.open(this.href, this.target, options.join(','))) {
				e.preventDefault();
			}
		});
		$('a.open-opener').live('click', function(e) {
			var opener = window.opener;
			if (!opener) return;
			opener.location.href = this.href;
			e.preventDefault();
		});
		if ($.browser.msie && parseInt($.browser.version, 10) < 7) {
			$('tr, button, #nav li, #tools li').hover(
				function() {
					$(this).addClass('hover');
				},
				function() {
					$(this).removeClass('hover');
				}
			);
			$('span.button').hover(
				function() {
					$(this).addClass('button-hover');
				},
				function() {
					$(this).removeClass('button-hover');
				}
			);
			$('tr:first-child, #tools ul ul li:first-child, #tools .actions li:first-child').addClass('first');
		}
		function typo() {
			$('tr:first-child').addClass('first');
			$('h1 + p').addClass('p-after-h1');
			$('blockquote + h2').addClass('h2-after-blockquote');
			$('p + ul, p + ol').addClass('list-after-p');
			$('caption + tbody').addClass('tbody-after-caption');
			$('div.infobox + div.infobox').addClass('infobox-after-infobox');
		}
		typo();
	});
	
	if (!window.opera) try {
		document.execCommand('BackgroundImageCache', false, true);
	}
	catch (e) {}
	
})(jQuery);
