/********************************************* INDEX	- crosstown.js	v. 1.02**********************************************	@CROSSTOWN INIT/CONTROLLERS*	@GA*	@Menu*	@PatternType*	@LineType*	@VideoView*	@ArticleView*	@DeliciousView*	@CompetencesView*	@ContactView********************************************//*** CROSSTOWN INIT/CONTROLLERS*/$(function($){	$._window			= $(window);	$._html				= $('html');	$._body				= $('body');	$._animationSpeed	= 900;	$._animationEasing	= 'easeOutQuart';	$._doParallex		= ( navigator.userAgent.match(/(iPhone|iPod|iPad|BlackBerry|Android|webOS)/) ? false : true );	$._events 			= {		STORY_ENTERING	: 'Events.STORY_ENTERING'	}});function init(){	// Patterns	$('section[data-type]').each(function(index, element)	{		switch($(element).attr('data-type'))		{			case 'pattern':				new PatternType($(element));				break;			case 'line':				new LineType($(element));				break;		}	});	// Menu	if($._doParallex === true)	{		var menu	= new Menu();		menu.clicked.add(scrollToStory);		menu.init();	}	// Views	$('section[data-view]').each(function(index, element)	{		switch($(element).attr('data-view'))		{			case 'article':				new ArticleView($(element));				break;			case 'delicious':				new DeliciousView($(element));				break;			case 'competences':				new CompetencesView($(element));				break;			case 'contact':				new ContactView($(element));				break;			case 'video':				new VideoView($(element));				break;		}	});	// Cache data for each element with a data-type (story, sprite, background)	$('[data-type]').each(function(index, element)	{		var element	= $(element);		element.data('speed', parseFloat(element.attr('data-speed')));		element.data('offsetTop', parseFloat(element.attr('data-offsetTop')));		element.data('offsetLeft', element.attr('data-offsetLeft'));	});	// Manage the scrolling of each story	$('section[data-type="story"]').each(function(index, element)	{		// @data-scrollOffset	: Determines the extra amount of pixels needed before we "enter" the story		// @data-offsetTop		: The offset where the actual content begins within the story (Where we scrollTo when clicking on the menu)		var story	= $(element);		story.data('offsetTop', story.offset().top + parseFloat(story.data('offsetTop'))); // Add the "global" offset to the story's offsetTop		story.data('scrollOffset', story.offset().top + parseFloat(story.attr('data-scrollOffset')));		story.data('id', story.attr('id'));		story.data('patterns', story.find('[data-type="pattern"]'));		story.data('backgrounds', story.find('[data-type="background"]'));		$._window.scroll(function()		{			// If the story is in view			if((($._window.scrollTop() + $._window.height()) > story.data('scrollOffset')) && ((story.data('scrollOffset') + story.height()) > $._window.scrollTop()))			{				$._body.triggerHandler($._events.STORY_ENTERING, story.data('id'));			}			if($._doParallex === true)			{				// Move the story and it's paterns and backgrounds (Ideally, this should be inside the "is in view"-statement, but the large difference in story heights makes the rendering bad)				story.data('patterns').each(function(index, element)				{					var pattern = $(element);					pattern.css({ marginTop: -($._window.scrollTop()/pattern.data('speed')) + pattern.data('offsetTop') });				});				story.data('backgrounds').each(function(index, element)				{					var background	= $(element);					background.css({ backgroundPosition: (background.data('offsetLeft') || '50%') + ' ' + (-($._window.scrollTop()/background.data('speed')) + background.data('offsetTop')) + 'px' });				});			}		});	});	$._window.scroll(); // Trigger a scroll event to get all the offset positions in place...}function scrollToStory(id){	var story	= $('#'+id);	$._html.stop().animate({ scrollTop:story.data('offsetTop') }, { easing: $._animationEasing, duration: $._animationSpeed });	$._body.stop().animate({ scrollTop:story.data('offsetTop') }, { easing: $._animationEasing, duration: $._animationSpeed });}function addEvent(element, eventName, callback){	if(element.addEventListener) element.addEventListener(eventName, callback, false);	else element.attachEvent(eventName, callback, false);};/*** GA (Google Analytics tracking)*/var GA	= {	trackEvent: function(category, action, opt_label, opt_value)	{		_gaq.push(['_trackEvent', category, action, opt_label, ( !opt_value ? 1 : opt_value )]);	},	trackPageView: function(url)	{		if(url) _gaq.push(['_trackPageview', url]);	}};/*** Menu*/var Menu = function(){	var _this		= this;	this.nav		= $('nav#main');	this.items		= this.nav.find('ul li a');	this.clicked	= new signals.Signal();	this.init = function()	{		this.items.bind('click', this.onNavItemClicked);		$._body.bind($._events.STORY_ENTERING, this.onStoryEntered);		this.nav.css('margin-top', -Math.round(this.nav.height()/2)+'px');		this.nav.fadeIn(200);	}	this.onNavItemClicked = function(e)	{		$elem	= $(e.currentTarget);		GA.trackPageView($elem.attr('href').replace($._baseURL, '/'));		_this.clicked.dispatch($elem.attr('data-id'));		e.preventDefault();	}	this.onStoryEntered = function(e, id)	{		_this.items.parent('li').removeClass('active');		$.each(_this.items, function(index, element)		{			if($(element).attr('data-id') == id)			{				$(element).parent('li').addClass('active'); // Thank you IE!!!				return false;			}		});		e.preventDefault();	}};/*** PatternType*/var PatternType = function(view){	var _this	= this;	this.view	= view;	this.canvas	= this.view.find('canvas').get(0);	this.ctx	= this.canvas.getContext('2d');	this.image	= new Image();	this.init = function()	{		this.image.src		= $._baseURL+'images/backgrounds/grid'+this.view.attr('data-grid')+'.png';		this.image.onload	= this.onLoaded;	}	this.onLoaded = function()	{		var coords	= _this.view.attr('data-coords').split('|');		_this.ctx.beginPath();		_this.ctx.fillStyle	= _this.ctx.createPattern(_this.image, 'repeat');		$.each(coords, function(index, value)		{			var coord	= value.split(',');			if(index == 0) _this.ctx.moveTo(coord[0], coord[1]);			else _this.ctx.lineTo(coord[0], coord[1]);		});		_this.ctx.fill();		_this.ctx.closePath();	}	this.init();};/*** LineType*/var LineType = function(view){	var _this	= this;	this.view	= view;	this.canvas	= this.view.find('canvas').get(0);	this.ctx	= this.canvas.getContext('2d');	this.init = function()	{		var coords		= this.view.attr('data-coords').split(',');// x1,y1,x2,y2		var position	= this.view.attr('data-position').split(',');// left,top		this.view.css({left: parseInt(position[0]), top: parseInt(position[1])});// Setting width and height via jQuery "breaks" the actual width and height?!		this.ctx.beginPath();		this.ctx.strokeStyle	= '#ff3333';		this.ctx.moveTo(parseInt(coords[0]), parseInt(coords[1]));		this.ctx.lineTo(parseInt(coords[2]), parseInt(coords[3]));		this.ctx.stroke();		this.ctx.closePath();	}	this.init();};/*** VideoView	[data-view="video"]*/var VideoView = function(view){	var _this			= this;	this.view			= view;	this.id				= view.attr('id');	this.videoContainer	= $('#video-container');	this.placeholder	= this.videoContainer.find('.placeholder');	this.closeBtn		= this.videoContainer.find('.close');	this.background		= this.videoContainer.find('.background');	this.preloader		= this.videoContainer.find('.preloader');	this.offsetTop		= this.view.offset().top - Math.abs(parseInt(this.view.attr('data-offsetTop')));	this.minHeight		= 500;	this.videoID		= null;	this.froogaloop		= null;	this.player			= null;	this.init = function()	{		$('.playbtn').bind('click', this.onPlaybtnClicked);		this.closeBtn.bind('click', this.onCloseBtnClicked);	}	this.onCloseBtnClicked = function(e)	{		_this.stopAndCloseVideo();	}	this.onPlaybtnClicked = function(e)	{		$._window.bind('scroll', _this.onWindowScrolled);		_this.videoContainer.fadeIn();		_this.videoID	= $(e.currentTarget).parent('article').attr('data-videoID');		_this.loadVideo();	}	this.loadVideo = function()	{		this.preloader.show();		this.videoContainer.css({top: this.offsetTop, height: Math.max(this.minHeight, $._window.height()) });		this.background.height(Math.max(this.minHeight, $._window.height()));		$._html.stop().animate({ scrollTop: this.background.offset().top },{easing: $._animationEasing,duration: $._animationSpeed});		$._body.stop().animate({ scrollTop: this.background.offset().top },{easing: $._animationEasing,duration: $._animationSpeed});		this.placeholder.empty();		this.placeholder.html('<iframe id="player_1" src="http://player.vimeo.com/video/'+this.videoID+'?api=1&amp;player_id=player_1&autoplay=1&js_api=1" width="704" height="396" frameborder="0"></iframe>');		this.player	= $f(document.querySelectorAll('#player_1')[0]);		this.player.addEvent('ready', this.onVideoReady);		GA.trackEvent('VIDEOS', 'VIDEO_LOADING', _this.videoID);	}	this.onVideoReady = function(player)	{		_this.preloader.hide();		_this.player.removeEvent('ready');		_this.froogaloop	= $f('player_1');		_this.froogaloop.addEvent('finish', _this.onVideoFinished);		_this.froogaloop.api('setColor', 'ff3333');		GA.trackEvent('VIDEOS', 'VIDEO_LOADED', _this.videoID);	}	this.onVideoFinished = function(player)	{		_this.stopVideo();		GA.trackEvent('VIDEOS', 'VIDEO_COMPLETED', _this.videoID);	}	this.stopAndCloseVideo = function()	{		if(this.froogaloop)		{			this.froogaloop.removeEvent('finish');			this.froogaloop.api('unload');			this.froogaloop	= null;		}		this.placeholder.empty();		this.videoContainer.fadeOut();		$._window.unbind('scroll', this.onWindowScrolled);	}	this.onWindowScrolled = function(e)	{		if((($._window.scrollTop() + $._window.height()) < _this.videoContainer.offset().top) || ($._window.scrollTop() > (_this.videoContainer.offset().top + _this.videoContainer.height()))) _this.stopAndCloseVideo();	}	this.init();}/*** ArticleView	[data-view="article"]*/var ArticleView = function(view){	var _this				= this;	this.view				= view;	this.browser			= new ArticleBrowser(this.view.find('.browsing'));	this.nav				= new ArticleNavigation(this.view.find('nav'));	this.articleContainer	= this.view.find('.articles');	this.articles			= this.articleContainer.find('article');	this.totalArticles		= this.articles.length;	this.currentIndex		= 0;	this.trackingEnabled	= false; // 1st run	this.init = function()	{		this.browser.clicked.add(this.onBrowserClicked);		this.nav.clicked.add(this.onNavClicked);		this.showArticleAtIndex();		this.trackingEnabled	= true;	}	this.onBrowserClicked = function(dir)	{		if(dir == 'left') _this.currentIndex = ( _this.currentIndex - 1 < 0 ? _this.totalArticles - 1 : _this.currentIndex - 1 );		else _this.currentIndex = ( _this.currentIndex + 1 > _this.totalArticles - 1 ? 0 : _this.currentIndex + 1 );		_this.showArticleAtIndex();	}	this.onNavClicked = function(index)	{		_this.currentIndex	= index;		_this.showArticleAtIndex();	}	this.showArticleAtIndex = function()	{		if(this.trackingEnabled === true) GA.trackPageView(this.articleContainer.children().eq(this.currentIndex).attr('data-url'));		this.articleContainer.clearQueue();		this.articleContainer.stop();		this.articleContainer.animate({left: -this.currentIndex*100+'%'},{easing: $._animationEasing,duration: $._animationSpeed});		this.nav.setActive(this.currentIndex);	}	this.init();}var ArticleNavigation = function(view){	var _this		= this;	this.view		= view;	this.items		= this.view.find('ul li a');	this.clicked	= new signals.Signal();	this.init = function()	{		this.items.each(function(index, element) { $(element).bind('click', _this.onItemClicked); });	}	this.onItemClicked = function(e)	{		_this.clicked.dispatch(_this.items.index($(e.currentTarget)));		return false;	}	this.setActive = function(index)	{		this.items.removeClass('active');		this.items.eq(index).addClass('active');	}	this.init();}var ArticleBrowser = function(view){	var _this		= this;	this.view		= view;	this.leftArrow	= this.view.find('.left');	this.rightArrow	= this.view.find('.right');	this.clicked	= new signals.Signal();	this.init = function()	{		this.leftArrow.bind('click', this.onLeftArrowClicked);		this.rightArrow.bind('click', this.onRightArrowClicked);		this.view.show();	}	this.onLeftArrowClicked = function()	{		_this.clicked.dispatch('left');	}	this.onRightArrowClicked = function()	{		_this.clicked.dispatch('right');	}	this.init();}/*** DeliciousView	[data-view="delicious"]*/var DeliciousView = function(view){	var _this	= this;	this.view	= view;	this.init = function()	{		setTimeout(this.load, 2000);	}	this.load = function()	{		$.post($._baseURL+$._lang+'/ajax/delicious/',{feed:_this.view.attr('data-feed')}, _this.onLoaded);	}	this.onLoaded = function(response)	{		_this.view.find('.preloader').remove();		_this.view.find('.articles').append(response);		new ArticleView(_this.view);	}	this.init();}/*** CompetencesView	[data-view="competences"]*/var CompetencesView = function(view){	var _this			= this;	this.isLoading		= false;	this.view			= view;	this.preloader		= this.view.find('.preloader');	this.articleView	= this.view.find('.articleView');	this.placeholder	= this.articleView.find('.placeholder');	this.nav			= new CompetencesNavigation(this.view.find('nav.list'));	this.init = function()	{		this.nav.clicked.add(this.onNavClicked);	}	this.onNavClicked = function(id)	{		_this.load(id);	}	this.load = function(id)	{		if(this.isLoading === true) return false;		this.preloader.show();		this.placeholder.empty();		this.placeholder.hide();		this.isLoading	= true;		$.post($._baseURL+$._lang+'/ajax/competences/',{id:id}, this.onLoaded);	}	this.onLoaded = function(response)	{		_this.placeholder.html(response);		_this.preloader.hide();		_this.placeholder.fadeIn();		_this.isLoading	= false;		new ArticleView(_this.articleView);	}	this.init();}var CompetencesNavigation = function(view){	var _this		= this;	this.view		= view;	this.items		= this.view.find('ul li a');	this.clicked	= new signals.Signal();	this.init = function()	{		this.items.each(function(index, element) { $(element).bind('click', _this.onItemClicked); });	}	this.onItemClicked = function(e)	{		$elem	= $(e.currentTarget);		GA.trackPageView($elem.attr('href').replace($._baseURL, '/'));		_this.items.parent('li').removeClass('active'); // Thank you IE		$elem.parent('li').addClass('active');		_this.clicked.dispatch($elem.attr('data-id'));		return false;	}	this.setActive = function(index)	{		this.items.removeClass('active');		this.items.eq(index).addClass('active');	}	this.init();}/*** ContactView	[data-view="contact"]*/var ContactView = function(view){	var _this		= this;	this.isLoading	= false;	this.view		= view;	this.infoView	= this.view.find('.info ul');	this.init = function()	{		this.view.find('.info .icon').bind('click', this.toggleInfo);		this.view.find('dt a').each(function(index, element)		{			$(element).bind('click', _this.onItemClicked);		});	}	this.toggleInfo = function(e)	{		_this.infoView.slideToggle();	}	this.onItemClicked = function(e)	{		_this.view.find('dd.active').slideUp();		var dd	= $(e.currentTarget).parents('dl').find('dd');		if(dd.hasClass('active'))		{			dd.removeClass('active');		}		else		{			_this.view.find('dd.active').removeClass('active');			dd.addClass('active');			dd.slideDown();			GA.trackPageView(dd.siblings('dt').find('a').attr('href').replace($._baseURL, '/'));		}		return false;	}	this.init();}
