(function() {
	
	
	var bg = {};
	
	var md;
	var loader;
	var timers;
	var redirectTable = {};
	var currentPage = {};
	var images;
	var preloadImages;
	var currentLocation;
	var linkChanged = false;
	var scroller;
	var show_popup;
	var first_time = true;
	var bg_change_on_home = 2500;
	var bg_change_on_others = 7000;
 	var bg_change_duration = 1500;
	
	sbApi =
	{
		init: function()
		{
			md = $('#main_div');
			loader = $('#ajax_loader');
			timers = new Timers();
			
			currentPage.name = 'page_home';
			
			if(!supportedBrowser)
			{
				
				sbApi.trackPageview(location.href.replace('.html', ''));
				
				var time;
				if((time = document.cookie.match(/browser_warning=(\d+)/)))
				{
					if((new Date()).getTime() - parseInt(time[1]) < 60000 * 60 * 24 /*one day*/)
						return;
				}
				
				$('#browser_warning').click(function(){$(this).fadeOut()})
					.parent().show();
				
				document.cookie = 'browser_warning=' + (new Date()).getTime() + '; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/';
				//javascript:document.cookie = 'sublimio_developer=1; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/';void(0);
			
				return;
			}
			
			md.removeClass('no_js');
						
			//bg.content = $('#bg img.content');
			bg.top = $('#bg');
			
			sbApi.setupLinks(md);
			
			$(window).resize(sbApi.resizeBG);
			$('#bg').bind('next_bg', sbApi.resizeBG);
			$('#bg').bind('stop_slideshow', function(){ timers.stop('bg'); });
			$('#bg').bind('start_slideshow', function(){ timers.start('bg'); });
			
			$('#wait').show().css({zIndex:0, top: 0, bottom: 0});
			md.show();
			
			md.bind('go', sbApi.gotoPage);
			
			$.ajaxSetup(
			{	
				error: sbApi.onPageLoadError
			});
			
			$('#error_msg').click(function(){$(this).fadeOut()});
			
			currentLocation = location.hash;
			
			$(window).bind('hashchange', sbApi.checkLocation);
			
			var page = sbApi.getLink(location);
			var hash = location.hash.replace('#', '');
			
			
			
			if(hash && page != hash)
			{
				timers.addTimer('bg', sbApi.nextBG, bg_change_on_others, true);
				
				var name = hash.replace(/^page_/, '');
				
				md.data('page', (redirectTable[name])? 'page_' + redirectTable[name]: hash);
				md.trigger('go');
			}
			else
			{
				$(window).load(function()
				{
					timers.addTimer('bg', sbApi.nextBG, bg_change_on_home, true);
					
					sbApi.trackPageview();
					sbApi.fullPageInit();
				});
			}
		},
		
		nextBG: function()
		{
			var duration = bg_change_duration;
			this.timeout = bg_change_on_home + duration;
			
			if(document.cookie.match(/no_bg_slideshow=/))
				return;
			
			if(currentPage.name != 'page_home')
			{
				this.timeout = bg_change_on_others + duration;
			}
			
			$('#next_bg').trigger('next', [duration]);
			
			this.control.start(this.name);
		},
		
		onPageLoadError: function(request, status, error)
		{
			$('#error_msg').show().find('#msg').html("<h1>Error" + request.status + ' ' + request.statusText + " </h1><p>Error requesting page " + loader.data('page') + "</p>");
			sbApi.hideWait();
			loader.data('state', 'loaded');
		},
		
		fullPageInit: function()
		{
			sbApi.hideWait();
			
			sbApi.resizeBG();
		},
		
		hideWait: function()
		{
			$('#wait').fadeOut('slow', function(){$(this).attr('style', ' ').addClass('no_logo').hide();});
		},
		
		trackPageview: function(page)
		{
			if(!page)
				page = currentPage.name;
			
			pageTracker._trackPageview(page + '.html');
		},
		
		checkLocation: function()
		{
			if(location.hash == currentLocation && linkChanged)
				return;
			
			if(location.hash != currentLocation && !linkChanged)
			{
				currentLocation = location.hash;
				
				var hash = location.hash.replace('#', '');
				
				//console.log('go to' + location.hash + 'from' + currentLocation);
				
				var name = hash.replace(/^page_/, '');
				
				md.data('page', (redirectTable[name])? 'page_' + redirectTable[name]: hash);
				md.trigger('go');
			}
			
			currentLocation = location.hash;
			linkChanged = false;
		},
		
		getLink: function(link)
		{
			var path = link.pathname.replace('.html', '').split('/');
			
			return path[path.length - 1];
		},
		
		
		setupLinks: function(doc)
		{
			if(!doc)
				doc = md;
			
			$(doc).find('a').each(function()
			{
				if($(this).attr('href') == '')
				{
					$(this).hide();
					return;
				}
				
				if($(this).is('.meta_info, .untouch_link'))
					return;
				
				if(this.hostname == location.hostname && this.pathname.match(/html$/))
				{
					var page = sbApi.getLink(this);
					var is_popup = false;
					
					$(this).attr('href', '#' + page);
					
					$(this).addClass('_link').addClass(page + '__link');
					
					if(redirectTable[page.replace(/^page_/, '')])
						page = 'page_' + redirectTable[page.replace(/^page_/, '')];
					
					$(this).data('page', page);
					$(this).data('is_popup', is_popup);
					
					$(this).click(function() 
					{
						if(sbApi.gotoPage.apply(this))
						{
//							$(this).parent().find('a').removeClass('active');
//							$(this).addClass('active');
							
							return true;
						}
						
						return false;
					});
				}	
			});
		},
		
		setupScroller: function(doc)
		{
			if(!doc)
				doc = md;
				
			var content = doc.find('#content.scrollable');

			if(scroller)
				scroller.destroy();
				
			scroller = null;
			
			if(!content.length)
				return;
				
			var container = content.find('.mask');
			var data = content.find('.content');
			
			
			data.css({position: 'absolute', top: 'auto', bottom: 0});
				
			scroller = new Scroller(data, container, '#scroll_tab');
			
			scroller.hideTab = function()
			{
				this._tab.stop().animate({right: this._tab.width()}, 'slow');
			};
			
			scroller.showTab = function()
			{
				this._tab.stop().animate({right: 0}, 'slow');
			};
			
			if(content.is('.credits_page'))
			{
				var credits = $('#content div.credits');
				data.css({bottom: credits.height()});
				
				var oldUpdateMethod = scroller._updateSize;
				
				scroller._updateSize = function()
				{
					var t = scroller; 
					
					oldUpdateMethod();
					
					t._container_height -= credits.height();
					
					t._tab_parent_height -= credits.height();
				};
			}
						
			scroller.init();
			
			//scroller.startAutoscroll();
		},
		
		startScroller: function()
		{
			if (scroller) 
			{
				scroller.run();
				scroller.startAutoscroll();
			}
		},
		
		gotoPage: function()
		{
			
			if(Shadowbox.isActive())
			{
				linkChanged = true;
				Shadowbox.close();
			}
			
			if(scroller)
				scroller.stopAutoscroll();
			
			if(loader.data('state') == 'loading' || $(this).data('page') == currentPage.name)
				return false;
				
			if($(this).is('a'))
				linkChanged = true;
			
			var page = $(this).data('page');
			
			var page_info = sbApi.getPageInfo(page);
			
			if(page_info.is_popup)
			{
				if(currentPage.name == page_info.top_page)
					return sbApi.showPopup(page_info);
				else
				{
					show_popup = page_info;
					$('#wait').show();
					sbApi.loadPage(page_info.top_page);
				}
			}
			else
			{
				$('#wait').show();
				sbApi.loadPage(page);
			}
			
			return true;
		},
		
		showPopup: function(popup)
		{
			if(!popup)
				popup = show_popup;
			
			if(scroller)
				scroller.stopAutoscroll();
				
			var ret = true;
				
			if(popup && popup.is_popup)
			{
				var images = [];
		        
		        $('div.gallery_items.' + popup.page + '_gallery a.meta_info').each(function()
		        {
		        	images.push(this);
					
					var options = {
			        	player: 'img',
				        gallery: popup.page,
						title:{}
			        };
					
					var short_title = $(this).parent().find('.short_title');
					var long_title = $(this).parent().find('.long_title');
					
					options.title['short'] = (short_title)? short_title.html(): this.title;
					options.title['long'] = (long_title)? long_title.html(): this.innerHTMl;
					
					if (this.href.match(/\.flv$/)) 
					{
						options.player = 'flv';
						options.width = 512;
						options.height = 305;
					}
				
			        Shadowbox.addCache(this, options);
			        
			    });

				if(images.length)
				{
			    
				    md.one('popupClosed', function()
			        {
			        	
			        	if(!linkChanged)
			        	{		        	
				        	linkChanged = true;
				        	$.bbq.pushState('#' + popup.top_page);
			        	}
			        });
	
				    sbApi.trackPageview(popup.page);
					
			        Shadowbox.open(images[0]);
				}
				else
				{
					ret = false;
				}
			}
			
			show_popup = false;
			
			return ret;
		},
		
		getPageInfo: function(page)
		{
			var info = {'page': page, is_popup: false, top_page: ''};
			
			page = page.split('_');
				
			if(page.length > 3 && page[2] == 'popup')
			{
				info.is_popup = true;
				info.top_page = page[0] + '_' + page[1];
			}
			
			return info;
		},
		
		loadPage: function(page)
		{
			
			loader.data("state", "loading");
			loader.data("page", page);
			
			loader.data("request", $.get(page + '.html?ajax=1'/*&rnd=' + Math.random()*/, {}, sbApi.onPageDocumentLoad));
		},
		
		abortLoad: function()
		{
			loader.data('request').abort();
			loader.data('state', 'loaded');
			images = false;
			preloadImages = [];
		},
		
		onPageDocumentLoad: function(data)
		{
			loader.html(data);
			
			stylize(loader);
			
			loader.find('#content').css({visibility: 'hidden'});
			
			sbApi.setupLinks(loader);
		
			images = loader.find('img');
			preloadImages = [];
			
			sbApi.imgChecker();
		},
		
		imgChecker: function()
		{
			var ok = true;
			
			if(!images)
				return;
			
			images.each(function()
			{
				if(!this.complete && $(this).attr('src'))
				{
					ok = false;
					
					if(!this._checked)
					{
						var img = new Image();
						img.src = this.src;
						preloadImages.push(img);
						this._checked = true;
					}
				}
			});
			
			if(ok)
			{
				images = false;
				preloadImages = [];
				sbApi.onPageLoad();
			}
			else
				setTimeout(sbApi.imgChecker, 500);
		},
		
		onPageLoad: function()
		{
			if(loader.data('state') == 'loaded')
				return;

			sbApi.pageLeave(function()
			{
				
				loader.children().each(function() 
				{
					$('#' + this.id, md).replaceWith(this);
				});
				
				loader.html('');
				
				currentPage.name = loader.data('page');
				
				loader.data("state", "loaded");
				
				sbApi.fullPageInit();
				sbApi.setupScroller();
				
				sbApi.pageEnter(function()
				{
					sbApi.startScroller();
				});
				
				sbApi.colorLinks();
			
				sbApi.trackPageview();
				sbApi.showPopup();
				
			});
		},
		
		colorLinks: function()
		{
			md.find('a._link').removeClass('active');
			md.find('a.' + currentPage.name + '__link').addClass('active');
		},
		
		pageLeave: function(cb)
		{
			var content = md.find('#content');
			content.css({width: content.width(), right: 'auto'}).animate({marginLeft: -content.width() }, 'slow', function(){cb();});
		},
		
		pageEnter: function(cb)
		{
			//timers.start('bg');
			var content = md.find('#content');
			var right = content.css('right');
			content.css({width: content.width(), right: 'auto', marginLeft: -content.width(), visibility: 'visible'})
				.animate({marginLeft: 0}, 'slow', function()
				{
					$(this).attr('style', ' ');
					cb();
				});
		},
		
		resizeBG: function()
		{
			var contentTop = 0;
			var contentLeft = 0;
			
			if(!bg.top)
				return;
			
			var box = {width: bg.top.width(), height: bg.top.height()};
			
			bg.content = $('#bg .selected img.content');
			
			var contentAspect = bg.content.width() / bg.content.height();
			
			if(isNaN(contentAspect))
				return;
			
			var currAspect = box.width / box.height;
			
			if(currAspect >= contentAspect)
			{
				bg.content.css({marginTop: contentTop - ((box.width * (1 / contentAspect)) - box.height) / 2, marginLeft: contentLeft, width: '100%', height: 'auto'});
			}
			else
			{
				bg.content.css({marginTop: contentTop, marginLeft: contentLeft - ((box.height * contentAspect) - box.width) / 2, width: 'auto', height: box.height});
			}
		}
		
	};
	
	$(sbApi.init);
	
	
	var AfterAll = function()
	{
		this._counter = 0;
		
		this._fn = [];
		
		this.getCallBack = function(cb)
		{
			var t = this;
			
			++this._counter; 
			
			return function()
			{
				--t._counter;
				if(cb)
					cb.apply(this);
					
				if(t._counter == 0)
					t._afterAll(this);
			};
		};
		
	
		this.addAfterAllCB = function(fn)
		{
			this._fn.push(fn);
		};
		
		this._afterAll = function(obj)
		{
			for(var i = 0; i < this._fn.length; ++i)
				this._fn[i].apply(obj);
		};
		
	};
	
	var Timers = function()
	{
		this._timers = {};
		
		this.addTimer = function(name, cb, timeout, once)
		{
			once = !!once;
			
			if(this._timers[name])
				this.stop(name);
			else
				this._timers[name] = {};
			
			this._timers[name].name = name;
			this._timers[name].cb = cb;
			this._timers[name].timeout = timeout;
			this._timers[name].once = once;
			this._timers[name].control = this;
			
			this.start(name);
		}
		
		this.stop = function(name)
		{
			if(!this._timers[name])
				return;
			
			if(this._timers[name].timeoutId)
				clearTimeout(this._timers[name].timeoutId);
				
			if(this._timers[name].intervalId)
				clearInterval(this._timers[name].intervalId);
		}
		
		this.start = function(name)
		{
			if(!this._timers[name])
				return;
			
			this.stop(name);
				
			var timer = this._timers[name];
			
			if(timer.once)
			{
				timer.timeoutId = setTimeout(function(){timer.cb.apply(timer)}, timer.timeout);
			}
			else
			{
				timer.intervalId = setInterval(function(){timer.cb.apply(timer)}, timer.timeout);
			}
		}
		
		this.stopAll = function()
		{
			for(var n in this._timers)
			{
				this.stop(n);	
			}
		}
	};
	
	var Scroller = function(content, container, tab)
	{
		this._content = $(content);
		this._container = $(container);
		this._tab = $(tab);
		this._tab_height = this._tab.height();
		this._lastY = false;
				
		this._scroll = false;
	
		var t = this;
		
		t._content_height = 0;
		t._container_height = 0;
		t._tab_parent_height = 0;
	
		this.init = function()
		{
			this._tab.mousedown(this._mousedown);
			$(document).mouseup(this._mouseup);
			$(document).mousemove(this._mousemove);
			$(window).resize(this._updateSize);
			$(window).resize(this._setScrollPos);
			this._content.bind('DOMMouseScroll', this._mouseDOMWheel);
			this._content.bind('mousewheel', this._mouseWheel)
			
			this._updateSize();
			
			//this._content.css({marginTop: -this._container_height});
			//this._setScrollPos();
		};
		
		this.run = function()
		{
			//this._updateSize();
			this._content.attr('style', ' ');
			this._updateSize();
			this._placeTab(2000);
			this._setScrollPos();
		};
		
		this.destroy = function()
		{
			this.stopAutoscroll();
			
			this._tab.unbind('mousedown', this._mousedown);
			$(document).unbind('mouseup', this._mouseup);
			$(document).unbind('mousemove', this._mousemove);
			$(window).unbind('resize', this._updateSize);
			$(window).unbind('resize', this._setScrollPos);
			this._content.unbind('DOMMouseScroll', this._mouseDOMWheel);
			this._content.unbind('mousewheel', this._mouseWheel)
		};
		
		this.startAutoscroll = function()
		{
			this.stopAutoscroll();
			
			if(t._container_height > 0)
				return;
				
			this._placeTab(2000);
			this._setScrollPos();
			
			this._autoscroll = setTimeout(function()
			{
				
				var tab_pos = t._tab.position().top;
				//var step = (t._container_height / 15) * (t._tab_parent_height / t._container_height);
				var step = tab_pos / 10;
				
				if(step > 10)
					step = 10;
				else if(step < 1)
					step = 1;
					
				
				if(!t._placeTab(t._tab.position().top - step))
					t._autoscroll = setTimeout(arguments.callee, 10);
				
				t._setScrollPos();
				
			}, 500);
		};
		
		this.stopAutoscroll = function()
		{
			if(this._autoscroll)
				clearTimeout(this._autoscroll);
		};
		
		this._updateSize = function()
		{
			t._content_height = t._content.height();
			t._container_height = t._container.height() - t._content_height;
			t._tab_parent_height = t._tab.parent().height() - t._tab_height;
		};
		
		this._setScrollPos = function()
		{
		
			if(t._container_height > 0)
			{
				t._content.css({marginTop: 0});
				t.hideTab();
			}
			else
			{
				var tab_pos = t._tab.position().top;
				
				if (tab_pos > t._tab_parent_height) 
				{
					t._placeTab(tab_pos);
					tab_pos = t._tab.position().top;
				}
				
				t.showTab();
				
				t._content.css({marginTop: (tab_pos / t._tab_parent_height) * t._container_height });
			}
			
		};
		
		this.hideTab = function()
		{
			t._tab.hide();
		};
		
		this.showTab = function()
		{
			t._tab.show();
		};
		
		this._placeTab = function(new_pos)
		{
			var end = false;
			
			if(new_pos < 0)
			{
				new_pos = 0;
				end = true;
			}
			else if(new_pos > t._tab_parent_height)
			{
				new_pos = t._tab_parent_height;
				end = true;
			}
				
			t._tab.css({top: new_pos});
			
			return end;
		};
		
		this._mousemove = function(e)
		{
			if(!t._scroll)
				return true;
			
			var new_pos = t._last_tab_pos + (e.pageY - t._lastY);
			
			t._placeTab(new_pos);
			
			t._setScrollPos();
			
			e.stopImmediatePropagation();
			return false;
		};
		
		this._mousedown = function(e)
		{
			t._scroll = true;
			
			t.stopAutoscroll();
			
			t._last_tab_pos = t._tab.position().top;
			t._lastY = e.pageY;
			
			e.stopImmediatePropagation();
			return false;
			
		};
		
		this._mouseup = function(e)
		{
			t._scroll = false;
			//$(document).unbind('mousemove', this._mousemove);
		};
		
		this._mouseWheel = function(e)
		{
			var delta = -(e.wheelDelta/40) * 4;
		    
		    if (window.opera)
		    	delta = -delta;
				
			t._mouseScroll(delta);
			
			e.stopImmediatePropagation();
			return false;
		};
		
		this._mouseDOMWheel = function(e)
		{
			var delta = e.detail * 4;
			
			t._mouseScroll(delta);
			
			e.stopImmediatePropagation();
			return false;
		};
		
		this._mouseScroll = function(delta)
		{
			t.stopAutoscroll();
			
			var pos = t._tab.position().top + delta;
			
			t._placeTab(pos);
			
			t._setScrollPos();
		}
		
	}


})(jQuery);
