REAL.Navigation = (function () {

	// Private variables
	var _$nav		= $("nav#main_nav ul li a");
		_$search	= $("#search-form");
		_cache		= {},
		_cacheName	= "";


	// Public variables
	var obj			= {};
		obj.lang	= "en";
		obj.changed	= new signals.Signal();

	// Private methods
	function init (route) {

		addEventListeners();
		createRouter();

		setFooterDown();
		if (hasher.getHash() === "" && route) {
			hasher.setHash(route);
		}
	}

	function addEventListeners() {

		_$nav.bind("click", onOpen, false);
		_$search.bind("submit", onSearch, false);
		$(window).bind("resize", setFooterDown, true);
	}

	function onOpen(e) {

		document.location.href = "#/" + $(this).attr("href");
		return false;
	}

	function onSearch(e) {

		var uri = "search/" + $("#search-input").val();
		document.location.href =  "#/"+encodeURI(uri);
		return false;
	}

	function createRouter() {

		// crossroads.js
		crossroads.addRoute('{section}/:subsection:', loadSection);

		// hasher.js
		hasher.initialized.add(crossroads.parse, crossroads);
		hasher.changed.add(crossroads.parse, crossroads);
		hasher.init();
	}

	function loadSection(section, subsection) {

		var $option = _$nav.parent().find('a[href$="' + section + '"]'),
			url		= $option.attr("data-url"),
			data	= { ajax: true };

		// select option and deselect the previous one
		_$nav.removeClass("selected");
		$option.addClass("selected");

		// load current section
		if (subsection) data.data = subsection;
		REAL.Preload.showed.dispatch();

		_cacheName = section+"-"+subsection;
		if (_cache[_cacheName]) {

			loadedSection(_cache[_cacheName]);
		} else {

			$("#topcontrol").click();
			$.get(url, data, loadedSection);
		}

		// dispatch the change of section
		obj.changed.dispatch(section, subsection);
	}

	function loadedSection(data) {

		$("#topcontrol").click();

		_cache[_cacheName] = data;
		$data = $(data);
		setTimeout(function() {

			setupBanner();
			setupClaim();
			setupBody();

			REAL.Preload.hided.dispatch();
		}, 400);
	}

	function setupBanner() {

		// banner
		if ($("body > #banner-cont").size() > 0) {

			$("body > #banner-cont").html($data.find("#banner-cont").html()).stop().css({ opacity: 0 }).show().delay(500).animate({ opacity: 1}, "slow");
			$("body > #banner-cont #banner").slides({
				preload: true,
				preloadImage: 'img/loading-black.gif',
				play: 5000,
				pause: 2500,
				hoverPause: true,
				effect: 'fade',
				crossfade: true
			});
		} else {

			$("body > #banner-cont").html("").stop().fadeOut("slow");
		}
	}

	function setupClaim() {

		// banner
		if ($data.find("#claim").size() > 0) {

			$("#claim").html($data.find("#claim").html()).stop().fadeIn("slow");
		} else {

			$("#claim").html("").stop().fadeOut("slow");
		}
	}

	function setupBody() {

		// banner
		if ($data.find("#body").size() > 0) {

			$("#body").html($data.find("#body").html());
			$("#body > section #banner").stop().css({opacity:0});
			setTimeout( function() {

				// part loader
				var $section = $("#body > section");

				if ($section.hasClass("load-part")){
					REAL.PartLoader.init("#body > section > article", parseInt($section.attr("data-num-part"), 10));
				}

				// ajax urls
				$("a.url-ajax").each(function(i) {
					var url = $(this).attr("href");
					$(this).attr("href", "#/"+ url);
				});

				// subnavigation (artists)
				setSubNavigation();

				// banner
				setInnerBanner($section);

				// artists
				if ($("#body > section").hasClass("artists-js")) REAL.Artists.init();

				// newsletter form
				if ($("#form-newsletter").size() > 0) {
					REAL.Form.init("#form-newsletter", "#form-newsletter-submit", "#form-newsletter-msg");
				}

				// twitter
				if ($section.find("a.twitter-share-button").size() > 0) {
					$.ajax({ url: 'http://platform.twitter.com/widgets.js', dataType: 'script', cache:true});
				}

				// contact
				if ($("#contact-form").size() > 0) {
					setH5F();
				}

				// aside height
				setTimeout(setAsideHeight, 20);


			}, 100);

		} else {

		}
	}

	function setSubNavigation () {

		var options = $("#body #sub_nav li");
		if (options.size() > 0) {

			options.find("a").bind("click", function (e) {

				var option = $(this).attr("href").split("/#/")[1];

				// move the scroll
				$target = $("#scroll-"+option);
				$('html, body').stop().animate({ 'scrollTop': $target.offset().top }, 500, 'swing');
				// select the option menu
				options.removeClass("selected");
				options.find("a[href$=" + option + "]").parent().addClass("selected");

				return false;
			}, false);
		}
	}

	function setInnerBanner ($element) {

		if ($element.find("#banner").size() > 0) {

			$element.find("#banner").slides({
				preload: true,
				preloadImage: 'img/loading.gif',
				play: 5000,
				pause: 2500,
				hoverPause: true,
				effect: 'slide'
			});

			$element.find("#banner").stop().css({opacity:0}).delay(200).animate({opacity:1}, "slow");
		}
	}

	function setH5F() {

		// placeholder >> H5F by Ryan Seddon > http://github.com/ryanseddon/H5F
		H5F.setup($("#contact-form").eq(0),{
			validClass: "valid",
			invalidClass: "invalid",
			requiredClass: "required"
		});

		var $form	= $('#contact-form'),
			$msg	= $('#contact-msg');

		$form.submit(function() {

			$msg.text("").hide();

			if ($form[0].checkValidity()){

				$.post("contact-send.php", $form.serialize(), function (data) {
					$msg.html(data).show();
				});
			} else {

				$msg.text("Fill all the required data").show();
			}

			return false;
		});
	}

	function setAsideHeight () {

		setFooterDown();

		var inc = parseInt($("#body aside").attr("data-aside-height"), 10);

		$("#body > aside article:last-child").height("auto");

		var sH = $("#body > section").height(),
			aH = $("#body > aside").height(),
			dif = sH - aH,
			element = $("#body > aside article:last-child");

		//if (dif > 0) {
			dif = element.height() + dif + inc;
			element.css({height: dif});
		//}
	}

	function setFooterDown () {

		var dH = $(window).height(),
			sH = $("#body").height(),
			sT = $("#body").position().top,
			hT = $("footer").height(),
			fT = dH - sH - sT - hT;

		if (fT > 0)	$("footer").css({marginTop: fT+"px"});
		else $("footer").css({marginTop: "0px"});
	}


	// Public methods
	obj.init			= init;
	obj.setAsideHeight	= setAsideHeight;
	obj.setFooterDown	= setFooterDown;

	return obj;

})();

