var frameDecorators = [];

function registerFrameDecorator(decorator)
{
	if(!frameDecorators.include(decorator))
		frameDecorators.push(decorator);
}

function decorate(root)
{
	frameDecorators.each(function(decorator) {
		decorator(root);
	});
}


function loadFrame(target, href, parameters)
{
	if(target != null)
	{
		target = $(target);
		target.addClassName('loading');
		target.scrollLeft = 0;
		target.scrollTop = 0;
		target.parentNode.scrollLeft = 0;
		target.parentNode.scrollTop = 0;
		new Ajax.Updater(target, href, {
			evalScripts:false,
			parameters:parameters,
			onComplete:function(response) {
				target.removeClassName('loading');
				response.responseText.extractScripts().each(function(script) {
					if(window.execScript)
					{
						window.execScript(script);
					}
					else
					{
						window.eval(script);
					}
				});
				decorate(target);
			}
		});
	}
}


var currentAnchor = null;
var currentAnchorParts = $H({});
function checkAnchor(def)
{
	var anchor = ''+document.location.hash;
	if(anchor.substr(0, 1) == '#') anchor = anchor.substr(1);
	if(currentAnchor == null  ||  currentAnchor != anchor)
	{
		currentAnchor = anchor;
		if(currentAnchor == '') currentAnchor = def;

		var query = $H(currentAnchor.parseQuery());
		query.each(function(pair) {
			if(currentAnchorParts.get(pair.key) != pair.value)
			{
				currentAnchorParts.set(pair.key, pair.value);
				loadFrame(pair.key, pair.value);
			}
		});
	}
}
function changeAnchor(frameId, uri)
{
	var anchorParts = currentAnchorParts.clone();
	anchorParts.set(frameId, uri);
	document.location.hash = anchorParts.toQueryString().gsub(/%2F/i, '/');
}

function decorateLinks(root)
{
	if(!root)
	{
		root = document.body;
	}

	root.select('.ajax-link').each(function(anchor) {
		anchor.removeClassName('ajax-link');
		var targetId = ''+anchor.target;
		if(targetId == '')
		{
			var frame = anchor.up('.ajax-frame');
			if(frame)
			{
				targetId = frame.identify();
			}
		}

		anchor.observe('click', function(event) {
			var href = anchor.getAttribute('href');
			if(anchor.hasClassName('history'))
			{
				changeAnchor(targetId, href);
			}
			else if(anchor.hasClassName('ajax-submit'))
			{
				var target = $(targetId);
				loadFrame(target, href, anchor.up('form').serialize({ hash:true }));
			}
			else
			{
				var target = $(targetId);
				if(anchor.hasClassName('ajax-lightbox'))
				{
					Lightbox.showBoxByAJAX(href, 800, 600);
				}
				else
				{
					loadFrame(target, href);
				}
			}
			event.stop();
		});
	});

	root.select('a.ajax-query').each(function(anchor) {
		anchor.removeClassName('ajax-query');

		anchor.observe('click', function(event) {
			location.search = Object.toQueryString(Object.extend(location.search.toQueryParams(), anchor.getAttribute('href').toQueryParams()));
			event.stop();
		});
	});

	root.select('select.ajax-query').each(function(el) {
		el.removeClassName('ajax-query');

		el.observe('change', function(event) {
			location.search = Object.toQueryString(Object.extend(location.search.toQueryParams(), el.value.toQueryParams()));
			event.stop();
		});

		var query = $H(el.value.toQueryParams()).merge(location.search.toQueryParams());
		var options =  $A(el.options);
		options.each(function(option) {
			var oquery = $H(option.value.toQueryParams());
			var found = true;
			oquery.each(function(i) {
				if(query.get(i.key) != i.value) found = false;
			});
			if(found)
			{
				el.selectedIndex = options.indexOf(option);
			}
		});
	});
}
registerFrameDecorator(decorateLinks);

document.observe('dom:loaded', function(event) {
	decorate(document.body);
});
