//	еееееееееееее														// Copyright 2010 Kasper Lahti, Cascom. All Rights Reserved.
//	еееееееееееее														
//	еееееееееееееееее													// Javascript+JSON powered website framework
//	еееееееееееееееее													// $, Date.js, store.js, Modernizr, Google Maps API.
//	еееееееееееееееее													// kasper.lahti@cascom.se (Kasper Lahti)

'use strict';
var cascom = {};														// !Define namespace

cascom.data = {};														// Javascript database object
cascom.everything = [];													// Combo post array to sort boxes with
cascom.everytag = [];													// Combo tag array to build tag cloud with

cascom.inter = new Audio("sound/inter.wav");
cascom.tack = new Audio("sound/tack.wav");
cascom.tick = new Audio("sound/tick.wav");
cascom.inter = new Audio("sound/interopen.wav");

//console.log(cascom.data);

$(document).ready(function () {											// !Document is ready
	$('body').addClass('loading focus');								// Initialize body class
	cascom.context();													// Check context (OS)
	cascom.model('tags');												// Fetch model (Tags)
	cascom.view.page('manifesto');										// Show manifesto page
	$('.javascript').css('display', 'none');
});

$(window).ready(function () {											// !Window is ready
	window.onblur = function () {
		$('body').removeClass('focus').addClass('blur');
	};
	
	window.onfocus = function () {
		$('body').removeClass('blur').addClass('focus');
	};
	
	$('body').addClass('duo');
	
	$(window).bind('resize', cascom.window.resize);

	//$('#content').resizable({
	//	handles: 'w', 
	//	resize: cascom.window.resize
	//});
	
});

cascom.context = function () {

	var agent = navigator.userAgent,
		iPhone = agent.indexOf('iPhone') !== -1,
		iPod = agent.indexOf('iPod') !== -1,
		iPad = agent.indexOf('iPad') !== -1,
		iOS = iPhone || iPod || iPad,
		iOS0 = false,
		gecko = agent.indexOf('Gecko/') !== -1,
		webkit = agent.indexOf('WebKit/') !== -1;

	if (webkit) {
		cascom.context.engine = 'webkit';
	} else if (gecko) {
		cascom.context.engine = 'gecko';
	}
	
	if (iOS) {															// !	iOS device
	
		if (iPhone || iPod) {											// !		iPhone/iPod
			$('body').addClass('iPhone');
			$('head')
				.append('<link rel="stylesheet" type="text/css" href="css/iphone.css">')
				.append('<link rel="apple-touch-startup-image" href="graphics/iphone-touch-startup.png">')
				.append('<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 163dpi)" href="graphics/iphone-touch-icon.png" />')
				.append('<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 326dpi)" href="graphics/iphone4-touch-icon.png" />');
		} else if (iPad) {												// !		iPad
			$('body').addClass('iPad');
			$('head')
				.append('<link rel="stylesheet" type="text/css" href="css/ipad.css">')
				.append('<link rel="apple-touch-startup-image" href="graphics/ipad-touch-startup.png">')
				.append('<meta name="format-detection" content="telephone=no">')
				.append('<link rel="apple-touch-icon-precomposed" media="screen and (resolution: 132dpi)" href="graphics/ipad-touch-icon.png" />');
		}
		
		$('head').append('<meta name="apple-mobile-web-app-capable" content="yes">');
		$('head').append('<meta name="viewport" content="width=device-width, user-scalable=no;">');
		$('head').append('<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">');
		
		
		if (navigator.standalone) {								// !		Installed on homescreen
			
		} else {
			//$('section')
			//	.html('<h1 id="home-screen-install">Tap "+" and "Add to Home Screen" to install the portfolio app</h1>');
		}
		
		if (navigator.onLine) {									// !		Is Online

		} 
		
		$('body').bind('touchmove', function (e) {						// !		Prevent window touch scroll
			e.preventDefault();
		});
		
		$(document).bind('mousedown mouseup', function (e) {
			e.preventDefault();
		});
		
		$('.project').live('touchstart', function (e) {					// !		Triggers
			e.preventDefault();
			//var touch = e.touches[0];	
		});
		
		$('.browse article').live('touchmove', function (event) {
			var t = event.originalEvent,
				touch = t.touches[0],
				node = touch.target,
				posX = t.touches[0].pageX,
				posY = t.touches[0].pageY;
			$(this).css({
				'top' : posY,
				'left' : posX
			});
			//var test = e.changedTouches[0].clientX;
		});
	
		$('.project').live('touchend', function (e) {

		});
		
		$('#page').live('touchend', function () {
			$(this).fadeOut('medium');
		});
			
			
		
		$('article').bind('gesturestart', function (e) {				// !		Gestures
			
		});
		
		$('article').bind('gesturechange', function (e) {
			
		});
	
		$('article').bind('ongestureend', function (e) {
			
		});

		var updateOrientation = 'landscape';
		$(window)														// !		Orientation
			.bind('orientationchange', updateOrientation)
			.trigger('orientationchange');
		
		updateOrientation = function () {
			var orientation = window.innerWidth < window.innerHeight ? 'portrait' : 'landscape';
			$('body').removeClass('portrait landscape').addClass(orientation);
		};
		
		
	} else {															// !	PC machine

		if (agent.indexOf('Mac') !== -1) {
			$('body').addClass('tuned mac');							// !		Mac
			
			if (agent.indexOf('10_6') !== -1) {
				$('body').addClass('snow-leopard');
			} else if (agent.indexOf('10_5') !== -1) {
				$('body').addClass('leopard');
			} else if (agent.indexOf('10_4') !== -1) {
				$('body').addClass('tiger');
			} else if (agent.indexOf('10_3') !== -1) {
				$('body').addClass('panther');
			} else if (agent.indexOf('10_2') !== -1) {
				$('body').addClass('jaguar');
			} else if (agent.indexOf('10_1') !== -1) {
				$('body').addClass('puma');
			} else if (agent.indexOf('10_0') !== -1) {
				$('body').addClass('cheetah');
			}
	
		} else if (agent.indexOf('NT') !== -1) {						// !		Windows
			$('body').addClass('tuned nt');
			if (agent.indexOf('6.1') !== -1) {
				$('body').addClass('7');
			} else if (agent.indexOf('6.0') !== -1) {
				$('body').addClass('vista');
			} else if (agent.indexOf('5.2') !== -1) {
				$('body').addClass('xp');
			} else if (agent.indexOf('5.1') !== -1) {
				$('body').addClass('xp');
			}
		}

		cascom.view.sidebar();
		
	}
	
};

// ! 
cascom.tool = {};														// !Tools

cascom.tool.now = new Date();											// !	Now

cascom.tool.doubleDigit = function (val) {								// Converts 1,2,3 to 01,02,03
	if (val < 10) {
		val = '0' + val;
	}
	return val;
};

cascom.tool.slhash = function (desc, mode) {							// Separate hash tag from string
	var textParse = desc.split('#');
	switch (mode) {
	case 'text' :
		return textParse[0];
	
	case 'tags' :
		if (textParse[1] !== undefined) {
			return [textParse[1]];
		} else {
			return ['#'];
		}
		break;
	}
};

cascom.tool.unique = function (a) {									// Remove duplicates from array
	var uniq = [];
	o : 
	for (var i = 0, n = a.length; i < n; i++) {
		for (var x = 0, y = uniq.length; x < y; x++) {
			if (uniq[x] === a[i]) {
				continue o;
			}
		}
		uniq[uniq.length] = a[i];
	}
	return uniq;
};

cascom.tool.doubles = function (arr) {									// Filter duplicates in array
	var sortedArr = arr.sort(),
		double = [];
	for (var i = 0; i < arr.length - 1; i += 1) {
		if (sortedArr[i + 1] === sortedArr[i]) {
			double.push(sortedArr[i]);
		}
	}
	return cascom.tool.unique(double);
};

cascom.limit = 16;

// ! 
cascom.model = function (mode, request) {								// Model
	var limit = 1,
		all = ['bookmarks', 'photos', 'papers', 'posts', 'podcast', 'tweets', 'videos'];
	
	cascom.request = mode;
	cascom.reqtype = 'all';
	
	if (mode !== 'tags') {
		$('#content .browse.view').last().addClass('push').delay(500).remove();

		if ($('#' + mode).length === 0) {
			$('#content').append('<div id="' + mode + '-all" class="browse view"></div>');
		} else {
			$('#content .browse.view').removeClass('push');
		}
	}
	
	if (mode === 'all') {												// Load one post from each service
		cascom.request = 'all';
		
		$.each(all, function (i, req) {
			cascom.model.load(req, mode, limit);
		});
	} else if (mode === 'tags') {										// Get all the tags used on the different services
		cascom.request = 'all';
		
		$.each(all, function (i, req) {
			cascom.model.load(req, mode, limit);
		});
	} else if (mode === 'recent') {										// Load the most recent posts from selected service
		limit = cascom.limit;
		cascom.reqtype = request;
		cascom.reqpage = 1;
		cascom.model.load(request, mode, limit);
	} else if (mode === 'next') {										// Load the most recent posts from selected service
		limit = cascom.limit;
		cascom.reqtype = request;
		cascom.model.load(request, mode, limit, ++cascom.reqpage);
	} else if (mode === 'prev') {										// Load the most recent posts from selected service
		limit = cascom.limit;
		cascom.reqtype = request;
		cascom.model.load(request, mode, limit, --cascom.reqpage);
	} else if (mode === 'search') {										// Load all posts matching a tag
		limit = 20;
		cascom.request = request;
		cascom.reqtype = 'all';
		$.each(all, function (i, req) {
			cascom.model.load(req, request, limit);
		});
	}
};

cascom.model.load = function (type, request, limit, page) {
	var user = 'cascom',
		key = '',
		requestUrl = '',
		tagsUrl = '',
		tagUrl = '',
		jsonUrl = requestUrl,
		needUpdate = true,
		pageOffset = page !== undefined ? page : 1,
		preStore = store.get(type + request + 'page' + pageOffset);

	switch (type) {														// JSON settings
	case 'bookmarks' :													// !	Bookmarks
		
		requestUrl = 'http://feeds.delicious.com/v2/json/' + user + '?count=' + limit + '&callback=?';
		tagsUrl = 'http://feeds.delicious.com/v2/json/tags/' + user + '?callback=?';
		tagUrl = 'http://feeds.delicious.com/v2/json/' + user + '/' + request + '?count=' + limit + '&callback=?';
		break;
	
	case 'photos' :														// !	Photos
		user = '42869473@N06';
		key = 'b95c0a4f97d56dcf434da1e4131a85c8';
		var fields = 'description,date_taken,tags,geo,media,url_sq,url_t,url_s,url_m,url_o';
		
		requestUrl = 'http://api.flickr.com/services/rest/?method=flickr.people.getPublicPhotos&api_key=' + key + '&user_id=' + user + '&extras=' + fields + '&per_page=' + limit + '&page=' + pageOffset + '&format=json&jsoncallback=?';
		tagsUrl = 'http://api.flickr.com/services/rest/?method=flickr.tags.getListUser&api_key=' + key + '&user_id=' + user + '&format=json&jsoncallback=?';
		tagUrl = 'http://api.flickr.com/services/rest/?method=flickr.photos.search&tags=' + request + '&api_key=' + key + '&user_id=' + user + '&extras=' + fields + '&per_page=' + limit + '&page=' + pageOffset + '&format=json&jsoncallback=?';
		break;
	
	case 'papers' :														// !	Papers
		requestUrl = 'http://www.instapaper.com/starred/rss/342102/rYjZLtIEPdPOrIYBwDJorBFPKc?jsonp=?';
		break;
	
	case 'podcast' :													// !	Podcast
		requestUrl = 'http://huffduffer.com/' + user + '/json?page=' + limit + '&callback=?';
		//tagsUrl = 'http://huffduffer.com/' + user + '/json?callback=?';
		tagUrl = 'http://huffduffer.com/' + user + '/tags/' + request + '/json?page=' + limit + '&callback=?';
		break;
		
	case 'tracks' :														// !	Tracks
		key = 'a198d1f12b50e16f98c85a9191fa3130';
		user = 'soundberg';
		
		requestUrl = 'http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=' + user + '&limit=' + limit + '&page=' + pageOffset + '&api_key=' + key + '&format=json&callback=?';
		//tagsUrl = 'http://ws.audioscrobbler.com/2.0/?method=user.gettoptags&user=' + user + '&api_key=' + key + '&format=json&callback=?'
		break;
	
	case 'sounds' :														// !	Sounds
		user = 'soundberg',
		requestUrl = 'http://api.soundcloud.com/users/' + user + '/tracks.json?callback=?';
		//tagsUrl = 'http://api.soundcloud.com/users/' + user + '/tracks.json?callback=?';
		//tagUrl = 'http://api.soundcloud.com/users/' + user + '/tracks.json?q=' + request + '&callback=?';
		break;
	
	case 'posts' :														// !	Posts
		var url = 'blog.kasper.lahti.co';
		
		requestUrl = 'http://' + url + '/api/read/json?num=' + limit + '&start=' + limit * (pageOffset - 1) + '&callback=?';
		//tagsUrl = 'http://' + url + '/api/read/json?num=10&callback=?';
		tagUrl = 'http://' + url + '/api/read/json?tagged=' + request + '&num=' + limit + '&start=' + limit * (pageOffset - 1) + '&callback=?';
		break;
	
	case 'tweets' :														// !	Tweets
		var id = '15101222';
		user = 'kasperlahti';
		
		requestUrl = 'http://api.twitter.com/1/statuses/user_timeline.json?user_id=' + id + '&count=' + limit + '&page=' + pageOffset + '&callback=?';
		tagsUrl = 'http://api.twitter.com/1/statuses/user_timeline.json?user_id=' + id + '&count=50&callback=?';
		tagUrl = 'http://search.twitter.com/search.json?q=from%3A' + user + '&q=%23' + request + '&rpp=' + limit + '&page=' + pageOffset + '&callback=?';
		break;
	
	case 'videos' :														// !	Videos
		user = '2346851';
		
		requestUrl = 'http://vimeo.com/api/v2/' + user + '/all_videos.json?callback=?';
		//tagUrl = 'http://vimeo.com/api/rest/v2?format=json&method=vimeo.videos.search&per_page=' + limit + '&query=' + request + '&user_id=' + user + '&page=' + page + '&callback=?';
		break;
		
	case 'pages' :														// !	Pages
		requestUrl = 'http://blog.cascom.se/api/pages';
		
	case 'cv' :															// !	CV
		//requestUrl = 'http://api.linkedin.com/v1/people/url=http%3A%2F%2Fwww.linkedin.com%2Fin%2Fkasperlahti:public';
		// When they open up the public profile so it doesn't have to authenticate first
		break;
	}
	
	// !	Request URL Router
	if (request === 'all') {
		jsonUrl = requestUrl;
	} else if (request === 'recent' || request === 'next' || request === 'prev') {
		jsonUrl = requestUrl;
	} else if (request === 'tags') {
		jsonUrl = tagsUrl;
	} else {
		jsonUrl = tagUrl;
	}
	
	// !	Fetch JSON
	cascom.data[type] = cascom.data[type] || {};
	cascom.data[type][request] = cascom.data[type][request] || {};
	
	function checkNew(data) {
		var threshDate = new Date().add(-69).minutes(),
			breakDate = data.update.replace('T', ', ').split('.'),
			lastUpdate = Date.parse(breakDate[0]),
			needsUpdate = new Date(lastUpdate).isBefore(threshDate);
		//console.log('Last Update: ' + lastUpdate + ' / Limit: ' + threshDate);
		return needsUpdate;
	}
	
	if (preStore !== undefined) {
		cascom.data[type][request]['page' + pageOffset] = preStore;				// Move local store object to active cascom object
		if (navigator.onLine === false) {
			needUpdate = false;
		} else if (cascom.data[type][request]['page' + pageOffset][0] !== undefined) {
			needUpdate = checkNew(cascom.data[type][request]['page' + pageOffset][0]);
		} else if (cascom.data[type][request]['page' + pageOffset].update !== undefined) {
			needUpdate = checkNew(cascom.data[type][request]['page' + pageOffset]);
		}
	}
	if (jsonUrl === undefined || jsonUrl === '') {												// Skip if source isn't setup for that request
		
	} else if (needUpdate !== true) {											// Use localStorage copy if available and fresh
		//console.log('local');
		cascom.load.cue();
		if (request !== 'tags') {												// Skip if tag list
			cascom.view(cascom.data[type][request]['page' + pageOffset]);		// Send objects to view function
			cascom.control(cascom.data[type][request]['page' + pageOffset]);	// Send objects to controller function
		}
		cascom.load.ing();
	} else {
		cascom.load.cue();
		//console.log('remote');
		$.ajax({
			url: jsonUrl,
			success: function (data, textStatus, XMLHttpRequest) {
				if (data !== undefined) {
					cascom.data[type][request]['page' + pageOffset] = cascom.format(data, type, limit, request);
					store.set(												// Save a copy to local store
						type + request + 'page' + pageOffset, 
						cascom.data[type][request]['page' + pageOffset]
					);
				
					if (request !== 'tags') {												// Skip if tag list
						cascom.view(cascom.data[type][request]['page' + pageOffset]);		// Send objects to view function
						cascom.control(cascom.data[type][request]['page' + pageOffset]);	// Send objects to controller function
					}
				} else {
					console.log('ajaxerror');
				}
			}
		});
	}
};


cascom.format = function (json, type, limit, request) {
	if (request !== 'tags') {
		var temp = {},
			formatArray = [];
		
		switch (type) {
		
		case 'bookmarks' :												// !	Bookmarks
			$.each(json, function (index, item) {
				
				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : 'bookmark',
					title : item.d,
					tags : cascom.format.tags(item.t),
					url : item.u,
					time : cascom.format.date(item.dt)
				};
				
				formatArray[index] = temp;
				
			});
			break;
		
		case 'photos' :													// !	Photos
			$.each(json.photos.photo, function (index, item) {
				
				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : item.media,
					owner : item.owner,
					id : item.id,
					url : 'http://www.flickr.com/photos/' + item.owner + '/' + item.id,
					title : item.title,
					description : item.description._content,
					image : {
						square : {
							url : item.url_sq,
							width : item.width_sq,
							height : item.height_sq
						}, 
						thumb : {
							url : item.url_t,
							width : item.width_t,
							height : item.height_t
						},
						small : {
							url : item.url_s,
							width : item.width_s,
							height : item.height_s
						},
						medium : {
							url : item.url_m,
							width : item.width_m,
							height : item.height_m
						},
						large : {
							url : item.url_b,
							width : item.width_b,
							height : item.height_b
						},
						original : {
							url : item.url_o,
							width : item.width_o,
							height : item.height_o
						}
					},
					tags : cascom.format.tags(item.tags),
					geo : {
						lat : item.latitude,
						long : item.longitude
					},
					time : cascom.format.date(item.datetaken)
				};
				
				formatArray[index] = temp;
			});
			break;
		
		case 'papers' :													// !	Papers
			$.each(json.slice(0, limit), function (index, item) {
				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : 'paper',
					title : item.title,
					description : cascom.tool.slhash(item.selection, 'text'),
					tags : cascom.tool.slhash(item.selection, 'tags'),
					url : item.url,
					time : cascom.format.date(item.pubDate) 
				};
				
				formatArray[index] = temp;
				
			});
			break;
		
		case 'posts' :													// !	Posts
			$.each(json.posts, function (index, item) {
				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : 'post',
					subtype : item.type,
					title : titleCaps(item.slug.replace(/-/g, ' ')),
					tags : cascom.format.tags(item.tags),
					url : item.url,
					time : cascom.format.date(item['date-gmt'])
				};
				switch (item.type) {
				case 'photo' :											// !		Photo
					temp.photo = {
						url : {
							small : item['photo-url-250'],
							medium : item['photo-url-500'], 
							large : item['photo-url-1280']
						},
						caption : item['photo-caption'],
						width : item.width,
						height : item.height
					};
					break;
					
				case 'link' :											// !		Link
					temp.link = {
						url : item['link-url'],
						'text': item['link-text']
					};
					break;
					
				case 'quote' :											// !		Quote
					temp.quote = {
						url : item['quote-source'],
						'text': item['quote-text']
					};
					break;
				}
				
				formatArray[index] = temp;
				
			});
			break;
			
		case 'podcast' :												// !	Podcast
			//console.log(json);
			$.each(json, function (index, item) {
				
			});
			break;
		
		case 'sounds' :													// !	Sounds
			
			$.each(json, function (index, item) {
				var uploadTime = item.created_at.split(' '),
					releaseDate = item.release_year + '-' + cascom.tool.doubleDigit(item.release_month) + '-' + cascom.tool.doubleDigit(item.release_day) + 'T' + uploadTime[1];

				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : 'sound',
					title : item.title,
					tags : cascom.format.tags(item.tag_list),
					url : item.permalink_link,
					embedUrl : item.uri,
					image : item.artwork_url,
					waveform : item.waveform_url,
					stream : item.stream_url,
					time : cascom.format.date(releaseDate)
				};
				
				formatArray[index] = temp;
				if (formatArray[index].image === null) {
					formatArray[index].image = 'http://beta.cascom.se/graphics/placeholder.jpg';
				}
			
			});
			formatArray.sort(cascom.sortTime);
			formatArray = formatArray.slice(0, limit);
			//console.log(formatArray);
			break;
		
		case 'tracks' :													// !	Tracks
			var offset = 0;
			if (json.recenttracks.track.length === undefined) {
				formatArray[0] = cascom.format.track(0, json.recenttracks.track, request);
				offset = 1;
			} else {
				$.each(json.recenttracks.track, function (index, item) {
					formatArray[index + offset] = cascom.format.track(index, item, request);
				});
			}
				
			break;
		
		case 'tweets' :													// !	Tweets
			var jsontype = 'normal';
			if ($.isArray(json)) {
			} else {
				json = json.results;
				jsontype = 'search';
			}
			$.each(json, function (index, item) {
				var text = item.text.split(' ');
				if (jsontype === 'normal') {
					temp = {
						update : cascom.tool.now,
						index : index,
						heritage : request,
						title : text[0] + '&#8230;',
						type : 'tweet',
						'text': cascom.tool.slhash(item.text, 'text'),
						tags : cascom.format.tags(cascom.tool.slhash(item.text, 'tags')),
						name : item.user.name,
						screenname : item.user.screen_name,
						avatar : item.user.profile_image_url,
						time : cascom.format.date(item.created_at)
					};
				} else {
					temp = {
						update : cascom.tool.now,
						index : index,
						heritage : request,
						title : text[0] + '&#8230;',
						type : 'tweet',
						'text': cascom.tool.slhash(item.text, 'text'),
						tags : cascom.format.tags(cascom.tool.slhash(item.text, 'tags')),
						name : item.from_user,
						screenname : item.from_user,
						avatar : item.profile_image_url,
						time : cascom.format.date(item.created_at)
					};
				}
				if (item.geo !== null) {
					temp.geo = {
						lat : item.geo.coordinates[0],
						long : item.geo.coordinates[1]
					};
				}
			
				formatArray[index] = temp;
			
			});
			break;
		
		case 'videos' :													// !	Videos
			$.each(json, function (index, item) {
				console.log(json);
				var descTime = item.description.split('Created: '),
					description = descTime[0],
					uploadDate = item.upload_date.split(' ');
				if (descTime[1] == undefined) {
					descTime[1] = uploadDate[0];
				}
				temp = {
					update : cascom.tool.now,
					index : index,
					heritage : request,
					type : 'video',
					title : item.title,
					description : description,
					tags : cascom.format.tags(item.tags),
					url : item.url,
					image : {
						small : item.thumbnail_small,
						medium : item.thumbnail_medium,
						large : item.thumbnail_large
					},
					time : cascom.format.date(descTime[1] + ', ' + uploadDate[1])
				};
			
				formatArray[index] = temp; 
			
			});
			formatArray.sort(cascom.sortTime);
			formatArray = formatArray.slice(0, limit);
			
			break;
		}
		return formatArray;
		
	} else {															// ! Tags
		
		var tagIndex = 0,
			formatObject = {},
			tags = {},
			obj = {};

		switch (type) {
		case 'bookmarks' :												// !	Bookmarks
			tagIndex = 0;
			$.each(json, function (key, value) {
				tags[tagIndex++] = key;
			});
			obj = {
				heritage : request,
				type : 'tags', 
				update : cascom.tool.now,
				tags : tags
			};
			formatObject = obj;
			break;
			
		case 'photos' :													// !	Photos
			$.each(json.who.tags.tag, function (index, tag) {
				tags[index] = tag._content;
			});
			obj = {
				heritage : request,
				type : 'tags', 
				update : cascom.tool.now, 
				tags : tags
			};
			formatObject = obj;
			break;
			
		case 'posts' :													// !	Posts
			tagIndex = 0;
			$.each(json, function (index, item) {
				$.each(item.tag, function (i, t) {
					tags[tagIndex++] = t;
				});
			});
			obj = {
				heritage : request,
				type : 'tags', 
				update : cascom.tool.now, 
				tags : tags
			};
			formatObject = obj;
			break;
			
		case 'sounds' :													// !	Sounds
			tagIndex = 0;
			$.each(json, function (index, tag) {
				$.each(tag.tag_list.split(' '), function (i, t) {
					tags[tagIndex++] = t;
				});
			});
			obj = {
				heritage : request,
				type : 'tags', 
				update : cascom.tool.now, 
				tags : tags
			};
			formatObject = obj;
			break;
			
		case 'tracks' :													// !	Tracks
			obj = {
				heritage : request,
				type : 'tags', 
				update : cascom.tool.now, 
				tags : json.toptags['#text'].split(' ')
			};
			formatObject = obj;
			break;
				
		case 'tweets' :													// !	Tweets
			tagIndex = 0;
			$.each(json, function (index, tag) {
				var hashtags = cascom.format.tags(cascom.tool.slhash(tag.text, 'tags'));
				$.each(hashtags, function (i, t) {
					if (t !== '#') {
						tags[tagIndex++] = t;
					}
				});
			});
			obj = {
				heritage : request, 
				type : 'tags', 
				update : cascom.tool.now, 
				tags : tags
			};
			formatObject = obj;
			break;
		}
		return formatObject;
	}
};

cascom.format.track = function (index, item, request) {
	var temp = {},
		trackDateTime = cascom.tool.now.getFullYear() + '-' + cascom.tool.doubleDigit(cascom.tool.now.getMonth() + 1) + '-' + cascom.tool.doubleDigit(cascom.tool.now.getDate()) + 'T' + cascom.tool.doubleDigit(cascom.tool.now.getHours()) + ':' + cascom.tool.doubleDigit(cascom.tool.now.getMinutes()) + ':' + cascom.tool.doubleDigit(cascom.tool.now.getSeconds()),
		nowplaying = item['@attr'];
	if (nowplaying === undefined) {
		trackDateTime = item.date['#text'];
	}
	
	temp = {
		update : cascom.tool.now,
		index : index,
		heritage : request,
		type : 'track',
		title : item.name,
		artist : item.artist['#text'],
		album : item.album['#text'],
		tags : ['music'],
		url : item.url,
		image : {
			small : item.image[0]['#text'],
			medium : item.image[1]['#text'],
			large : item.image[2]['#text'],
			big : item.image[3]['#text']
		},
		time : cascom.format.date(trackDateTime)
	};
	return temp;
};

cascom.format.date = function (str, opt) {
	var d = Date.parse(str.replace('Z', '')),
		dt = d.toString('yyyy-MM-ddTHH:mm:ss'),
		f = d.toString('d MMMM, yyyy'),
		dateObj = { 
			date : d, 
			datetime : dt, 
			form : f 
		};
	return dateObj;
};

cascom.format.tags = function (tags) {
	
	if (tags.constructor !== Array) {
		tags = tags.split(' ');
	}
	
	var skip = -1;
	$.each(tags, function (index, tag) {
		if (tag === 'project') {
			skip = index;
		} else {
			tags[index] = tag.replace('-', ' ').replace(',', '').toLowerCase();
		}
	});
	if (skip > -1) {
		tags.splice(skip, 1);
	}
	return tags;
};


cascom.sortTime = function (a, b) {
	if (a.time.datetime < b.time.datetime) {
		return 1;
	}
	if (a.time.datetime > b.time.datetime) {
		return -1;
	}
	return 0;
};


// ! 
// !е View е

cascom.view = { index : 0 };

cascom.view = function (model) {
	$.each(model, function (index, item) {

		cascom.view.build.elements[cascom.view.index] = { 
			article : {} 
		};

		// Page Glimpse Settings
		var key = 'bfa0f7c482bbb251a660acf81b428906',
			placeholder = 'http://beta.cascom.se/graphics/placeholder.jpg',
			linkPreview = 'http://images.pageglimpse.com/v1/thumbnails?url=http://cascom.se&size=medium&nothumb=' + placeholder + '&devkey=' + key;

		switch (item.type) {
		
		case 'bookmark' : // !	Bookmark
			linkPreview = 'http://images.pageglimpse.com/v1/thumbnails?url=' + item.url + '&size=medium&nothumb=' + placeholder + '&devkey=' + key;
			linkPreview = 'http://images.shrinktheweb.com/xino.php?stwembed=1&stwu=cascom&stwaccesskeyid=c0e44e9b0d07a04&stwxmax=320&stwurl=' + item.url;
			
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'rel': 'bookmark',
						'text': item.title
					}
				},
				figure : {
					img : {
						src : linkPreview,
						alt : item.title
					}
				}
			};
			break;
		
		case 'photo' : // !	Photo
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': 'http://www.flickr.com/photos/' + item.owner + '/' + item.id,
						'text': item.title
					}
				},
				figure : {
					img : {
						src : item.image.small.url,
						alt : item.title
					}
				}
			};
			if (index === model.length + 1) { // replace + with - to add to last
				cascom.view.build.elements[model.length] = {
					article : {
						'className': 'more',
						h1 : {
							'a': {
								'href': '#more',
								'text': 'More'
							}
						}
					}
				};
			}
			break;
			
		case 'paper' : // !	Paper
			linkPreview = 'http://images.pageglimpse.com/v1/thumbnails?url=' + item.url + '&size=medium&nothumb=' + placeholder + '&devkey=' + key;
			linkPreview = 'http://images.shrinktheweb.com/xino.php?stwembed=1&stwu=cascom&stwaccesskeyid=c0e44e9b0d07a04&stwxmax=320&stwurl=' + item.url;

			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'rel': 'bookmark',
						'text': item.title
					}
				},
				figure : {
					img : {
						src : linkPreview,
						alt : item.title
					}
				}
			};
			break;
		
		case 'post' :													// !	Post
			switch (item.subtype) {
			case 'photo' :												// !		Photo
				cascom.view.build.elements[cascom.view.index].article = {
					id : '',
					'className': '',
					h1 : {
						'a': {
							'href': item.url,
							'rel': 'photo',
							'text': item.photo.caption.replace('<p>', '').replace('</p>', '')
						}
					},
					figure : {
						img : {
							src : item.photo.url.small,
							alt : item.photo.caption
						}
					}
				};
				break;
			
			case 'link' :												// !		Link
				cascom.view.build.elements[cascom.view.index].article = {
					id : '',
					'className': '',
					h1 : {
						'a': {
							'href': item.link.url,
							'rel': 'bookmark',
							'text': item.link.text
						}
					},
					div : {
						'text': '\u26A1'
					}
				};
				break;
				
			case 'quote' :												// !		Quote
				cascom.view.build.elements[cascom.view.index].article = {
					id : '',
					'className': '',
					h1 : {
						'a': {
							'href': item.url,
							'rel': 'quote',
							'text': '\u201C' + item.quote.text + '\u201D'
						}
					},
					div : {
						'text': '\u201D'
					}
				};
				break;
			}
			break;
		
		case 'sound' :													// !	Sound
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'text': item.title
					}
				},
				figure : {
					img : {
						src : item.image.replace('large', 'crop'),
						alt : item.title
					}
				}
			};
			break;
		
		case 'track' :													// !	Track
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'text': item.title
					}
				},
				figure : {
					img : {
						src : item.image.big,
						alt : item.artist + '-' + item.album
					}
				}
			};
			break;
		
		case 'tweet' :													// !	Tweet
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'text': item.title
					}
				}
			};
			break;
		
		case 'video' :													// !	Video
			cascom.view.build.elements[cascom.view.index].article = {
				id : '',
				'className': '',
				h1 : {
					'a': {
						'href': item.url,
						'text': item.title
					}
				},
				figure : {
					img : {
						src : item.image.large,
						alt : item.title
					}
				}
			};
			break;
			
		}
		
		cascom.view.build.elements[cascom.view.index].article.id = item.type + '-' + item.heritage + '-' + item.index;
		cascom.view.build.elements[cascom.view.index].article.className = item.type + ' loading';

		cascom.view.index++;
		
	});
	
	cascom.view.build.er('.browse.view');								// Build DOM elements from view builder object

};

// !Build
cascom.view.build = cascom.view.build || {};
cascom.view.build.elements = cascom.view.build.elements || {};
cascom.view.build.temp = cascom.view.build.temp || {};

cascom.view.build.er = function (target) {
	$.each(cascom.view.build.elements, function (i, object) {
		$.each(object, function (tag, content) {
			cascom.view.build.block(tag, content, target);
		});
	});
	cascom.view.build.elements = [];
	cascom.view.index = 0;
};

cascom.view.build.block = function (tag, obj, target) {
	var element = $('<' + tag + '></' + tag + '>');
	if (obj.constructor === Array) {
		$.each(obj, function (i, t) {
			if ('object' === typeof(t)) {
				$.each(t, function (n, v) {
					if ('object' === typeof(v)) {
						element.appendTo(target);
						cascom.view.build.block(n, v, element);
					} else {
						if (n === 'text') {
							element.html(v);
						} else if (n === 'className') {
							element.addClass(v);
						} else {
							element.attr(n, v);
						}
					}
				});
			} else {
				$('<' + tag + '>')
					.html(t)
					.appendTo(target);
			}
		});
	} else if ('object' === typeof(obj)) {
		$.each(obj, function (name, value) {
			if ('object' !== typeof(value)) {					// Standard tag attributes
				if (name === 'text') {
					element.html(value);
				} else if (name === 'className') {
					element.addClass(value);
				} else {
					element.attr(name, value);
				}
			} else {
				cascom.view.build.block(name, value, element);
			}
		});
		if (tag === 'icon') {
			var iconData = element.attr('src');
			var iconTitle = element.attr('alt');
			if (cascom.context.engine === 'webkit' && Modernizr.svg) {
				element = $('<img />');
				element.attr('src', iconData + '.svg')
				element.attr('alt', iconTitle);
			} else if (cascom.context.engine === 'gecko' && Modernizr.svg) {
				element = $('<object></object>');
				element.attr('data', iconData + '.svg')
					.attr('type', 'image/svg+xml')
					.removeAttr('alt');
			} else {
				element = $('<img />');
				element.attr('src', iconData + '.png')
				element.attr('alt', iconTitle);
			}
		}
		element.appendTo(target);										// Append built tag to target
		
		if (tag === 'img' || tag === 'iframe') {						// This is a tag that loads
			element
				.addClass('loading')
				.load(function () {	
					$(this).removeClass('loading');						// When finished loading remove loading class
				});
		}
	} else {															// Basic Version
		//console.log('basic');
		$('<' + tag + '>')
			.text(content)
			.appendTo(target);
	}
};

// !Menus
cascom.view.sidebar = function () {

	$.getJSON('json/sidebar.json', function (data) {
		cascom.view.build.elements = [data];
		cascom.view.build.er('#sidebar');
	
		$('body').append('<div class="loader"><div class="spinner"></div></div>');
		cascom.view.icon('graphics/spinner-color', 'loading', 32, '.spinner');	
		
		$('nav h2').prepend('<span>&#9660;</span>');
		$('nav h2').bind('click', function () {
			if ($(this).next('ul').is(':visible')) {
				$(this).find('span').replaceWith('<span>&#9658;</span>');
				$(this).next('ul').css('display', 'none');
			} else {
				$(this).find('span').replaceWith('<span>&#9660;</span>');
				$(this).next('ul').css('display', 'block');
			}
		});
		
		cascom.control.page();
		cascom.control.source();
	});
};

cascom.view.tags = function (target, scope) {
	if (scope === 'select') {
		var dubTags = cascom.tool.doubles(cascom.everytag),
			sortedTags = dubTags.sort();
	} else {
		var uniTags = cascom.tool.unique(cascom.everytag),
			sortedTags = uniTags.sort();
	}
	$(target).empty();
	$.each(sortedTags, function (index, tag) {
		if (tag !== 'tags') {
			$(target).append('<li class="tag"><a href="#tag/' + tag + '">' + tag + '</a></li>\n');
			var currentTag = $('.all-tags li').eq(index).find('a');
			cascom.view.icon('graphics/tag', 'tag', 16, currentTag);
		}
	});
	cascom.control.tag();
};

cascom.view.page = function (page) {
	
	cascom.control.close();
	$('#content').addClass('bleed');
	$('aside').remove();

	var prevPage = $('.page, .browse');
	prevPage.addClass('push');
	$('#main header, #main footer').addClass('loading');
	
	setTimeout(function () {
		prevPage.remove();
		$('#' + page).removeClass('loading');
		$('#main > header, #main > footer').remove();
	}, 500);
	
	switch (page) {
	case 'manifesto' :
		cascom.view.page.manifesto();
		break;
	case 'profile' :
		cascom.view.page.profile();
		break;
	case 'colophon' :
		cascom.view.page.colophon();
		break;
	case 'tags' :
		cascom.view.page.tags();
		break;
	}
};

cascom.view.browse = function () {
	
	cascom.control.close();
	$('#content').removeClass('bleed');
	$('aside').remove();
	
	var prevPage = $('.page');
	prevPage.addClass('push');
	setTimeout(function () {
		prevPage.remove();
	}, 500);

	cascom.view.build.elements = [
		{ 
			'header': {
				'className': 'loading',
				'ul': [
					{ 'className': 'sort-by' },
					{
						'li': {
							'className': 'title',
							'a': {
								'href': '#sort/title',
								'rel': 'title',
								'text': 'Title'
							}
						}
					},
					{
						'li': {
							'className': 'time',
							'a': {
								'href': '#sort/time',
								'rel': 'time',
								'text': 'Time'
							}
						}
					},
					{
						'li': {
							'className': 'tags',
							'a': {
								'href': '#sort/tags',
								'rel': 'tags',
								'text': 'Tags'
							}
						}
					},
					{
						'li': {
							'className': 'type',
							'a': {
								'href': '#sort/type',
								'rel': 'type',
								'text': 'Type'
							}
						}
					}
				],
				'input': {
					'type': 'search',
					'placeholder': 'Search'
				}
			}
		},
		{ 
			'footer': [
				{ 'className': 'glossy loading' },
				{
					'ul': [
						{
							'className': 'pagination'
						},
						{
							'li': {
								'className': 'prev',
								'a': {
									'href': '#prev',
									'rel': 'prev',
									'text': '\u25C0 Previous'
								}
							}
						}
					]
				},
				{
					'ul': [
						{
							'className': 'pagination'
						},
						{
							'li': {
								'className': 'next',
								'a': {
									'href': '#next',
									'rel': 'next',
									'text': 'Next \u25BA'
								}
							}
						}
					]
				}
			]
		}
	];
	
	if ($('#main > header').length === 0 && $('#main > footer').length === 0) {
		cascom.view.build.er('#main');
		setTimeout(function () {
			$('#main header, #main footer').removeClass('loading');
		}, 500);
		cascom.control.sort();
		cascom.control.search();
		cascom.control.modal();
	}
};

cascom.view.image = function (src, alt, prependTo) {
	$('<img />')
		.attr('src', src) 
		.attr('alt', alt)
		.addClass('loading')
		.prependTo(prependTo)
		.load(function () {
			$(this).removeClass('loading'); 
		});
};

cascom.view.icon = function (file, name, size, prependTo, className) {
	var icon = '';

	if (cascom.context.engine === 'webkit' && Modernizr.svg) {
		icon = $('<img />')
			.attr('src', file + '.svg') 
			.attr('alt', name)
			.attr('width', size)
			.addClass('loading');
	} else if (cascom.context.engine === 'gecko' && Modernizr.svg) {
		icon = $('<object>')
			.attr('data', file + '.svg') 
			.attr('type', 'image/svg+xml')
			.attr('width', size)
			.addClass('loading');
	} else {
		icon = $('<img />')
			.attr('src', file + '.png') 
			.attr('alt', name)
			.attr('width', size)
			.addClass('loading');
	}
	if (className !== undefined) {
		icon.addClass(className);
	}
	if (prependTo !== undefined) {
		icon.prependTo(prependTo)
			.load(function () {
				$(this).removeClass('loading'); 
			});
	} else {
		return icon[0];
	}
};

cascom.view.tiles = function (src, alt, width, height, prependTo) {
	var w = width !== undefined ? width : 768,
		h = height !== undefined ? height : 768,
		rows = Math.round((h / cascom.window.tileSize) + 0.49),
		columns = Math.round((w / cascom.window.tileSize) + 0.49);
		
	$('<div>').attr('id', 'tiles').appendTo('#page');
	for (var row = 0; row < rows; ++row) {
		for (var column = 0; column < columns; ++column) {
			var tileY = row * cascom.window.tileSize,
				tileX = column * cascom.window.tileSize;
			$('<div>')
				.addClass('tile loading')
				.css({
					'width': cascom.window.tileSize + 'px',
					'height': cascom.window.tileSize + 'px',
					'top': tileY + 'px',
					'left': tileX + 'px',
					'background-image': 'url(' + src + ')',
					'background-position': (-tileX) + 'px ' + (-tileY) + 'px',
					'-webkit-transition-delay': column + row * 100 + 'ms'
				})
				.appendTo('#tiles');
		}
	}
	$('<img />')
		.attr('src', src)
		.attr('alt', alt)
		.css('display', 'none')
		.prependTo('#page')
		.load(function () {
			$('#tiles .tile').removeClass('loading'); 
		});

};


cascom.view.frame = function (item, target) {
	$('<iframe>')
		.attr('id', item.type + '-frame')
		.addClass('loading ' + item.type)
		.attr('src', item.url)
		.appendTo(target)
		.load(function () {
			$(this).removeClass('loading');
		})
	;
};

cascom.view.embed = function (embedUrl, target) {
	$.getJSON(embedUrl, function (json) {
		$(target).append(json.html);
	});
};

cascom.view.map = function (lat, lng) {

	var style = [
		{
			featureType: "road",
			elementType: "labels",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			featureType: "landscape",
			elementType: "all",
			stylers: [
				{ saturation: -100 },
				{ lightness: -75 }
			]
		},
		{
			featureType: "road",
			elementType: "geometry",
			stylers: [
				{ saturation: -100 },
				{ lightness: 100 }
			]
		},
		{
			featureType: "water",
			elementType: "all",
			stylers: [
				{ hue: "#00ffff" },
				{ saturation: 100 }
			]
		},
		{
			featureType: "transit",
			elementType: "all",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			featureType: "poi",
			elementType: "all",
			stylers: [
				{ visibility: "off" }
			]
		},
		{
			featureType: "administrative",
			elementType: "labels",
			stylers: [
				{ visibility: "off" }
			]
		}
	];
	
	
	var location = new google.maps.LatLng(lat, lng),
		options = {
			zoom: 7,
			center: location,
			disableDefaultUI: true,
			mapTypeIds: 'cmap'
		};
		
	cascom.map = new google.maps.Map($('.map').get(0), options);
		
		//var cMapType = new google.maps.StyledMapType(style, styledMapOptions),
		//cascom.map.mapTypes.set('cmap', cMapType),
		//cascom.map.setMapTypeId('cmap'),
	cascom.map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
	var marker = new google.maps.Marker({
		position: location,
		title: "Hello!"
	});
	
	marker.setIcon('graphics/map-marker.png');
	marker.setMap(cascom.map);
};

cascom.view.map.relocate = function (lat, lng) {
	var location = new google.maps.LatLng(lat, lng);
	cascom.map.panTo(location);
};

cascom.view.page.manifesto = function () {
	$.getJSON('json/manifesto.json', function (data) {
		cascom.view.build.elements = [data];
		cascom.view.build.er('#content');
	});
};

cascom.view.page.profile = function () {
	$.getJSON('json/profile.json', function (data) {
		cascom.view.build.elements = [data];
		cascom.view.build.er('#content');
		$('#profile button').bind('click', function() {
			cascom.view.contact();
		});
	});
};

cascom.view.page.colophon = function () {
	$.getJSON('json/colophon.json', function (data) {
		cascom.view.build.elements = [data];
		cascom.view.build.er('#content');
	});
};

cascom.view.page.tags = function () {

	$.getJSON('json/tags.json', function (data) {
		cascom.view.build.elements = [data];
	
		cascom.view.build.er('#content');
		
		cascom.view.tags('article#tags ul', 'all');
		
		cascom.control.tag();
	});
};

cascom.view.contact = function () {
	$('#main').append('<div id="contact-window"></div>');
	$('#contact-window').load('contact.html #contact', function() {
		$('input.close').bind('click', function() {
			$('#contact-window').remove();
		});
	});
};

function currentlyShowingTags() {
	var currentTags = [],
		tagCounter = 0;
	// Based on all loaded boxes. Use for project detail view (related items)?
	$.each(cascom.everything, function (index, box) { // Loop thru all box objects 
		$.each(box.tags, function (tagIndex, boxTag) { // Loop thru tags for each box
			currentTags[tagCounter++] = boxTag; // Add to tag array
		});
	});
	
	return cascom.tool.unique(currentTags); // Remove duplicates and send back array
}


// ! 
// !Ajax Events
$.ajaxSetup({
	type: 'GET',
	dataType: 'json'
});

$(document).ajaxStart(function () {
	//console.log('start');
	$('body').addClass('loading');
	cascom.load.done.count = 0;
});

$(document).ajaxSend(function () {
	//console.log('send');
});

$(document).ajaxComplete(function () {
	//console.log('complete');
	if (!cascom.load.ing.count) {
		cascom.load.ing.count = 0;
	}
	$('#cascom span').eq(cascom.load.ing.count++).removeClass('loading');
});

$(document).ajaxStop(function () {
	cascom.load.done();
});

$(document).ajaxError(function () {
	//console.log('error');
});

// !Loading

cascom.load = {};

cascom.load.cue = function () {
	if (!cascom.load.cue.count) {
		cascom.load.cue.count = 0;
	}
	$('#cascom span').eq(cascom.load.ing.count++).removeClass('loading');
};

cascom.load.ing = function () {
	if (!cascom.load.ing.count) {
		cascom.load.ing.count = 0;
	}
	cascom.load.cue.count = ++cascom.load.cue.count;
	if (cascom.load.ing.count < cascom.load.cue.count) {
		$('#cascom span').eq(cascom.load.ing.count).removeClass('loading');
	} else {
		cascom.load.done();
	}
};

cascom.load.done = function () {
	//console.log('done');
	$('body').removeClass('loading');
	cascom.combiner();

	cascom.load.cue.count = 0;
	cascom.load.ing.count = 0;
};

cascom.combiner = function () {
	var boxIndex = 0;													// Set combo index for everything
	var tagIndex = 0;													// & everytag array
	
	cascom.everything = [];												// Clear array before building new
	$.each(cascom.data, function (type, object) {						// Loop through database
		$.each(object, function (request, pages) {						// Check items
			$.each(pages, function (page, array) {						// Check items
				if (request === 'tags') {								// If this is a tag
					$.each(array.tags, function (key, item) {			// Grab all tags of that item
						cascom.everytag[tagIndex++] = item;				// Add to everytag array
					});
				} else if (page === 'page' + cascom.reqpage) {
					$.each(array, function (key, item) {				// Check if item is from latest model request
						if (cascom.request === item.heritage && (cascom.reqtype === item.type + 's' || cascom.reqtype === 'all')) {
							cascom.everything[boxIndex++] = item;		// Add to everything array
						}
					});
				}
			});
		});
	});

	if (cascom.everything.length >= cascom.limit) {
		$('footer .pagination li:eq(1)').css('display', 'inline-block');
	} else {
		$('footer .pagination li:eq(1)').css('display', 'none');
	}
	
	if (cascom.reqpage > 1) {
		$('footer .pagination li:eq(0)').css('display', 'inline-block');
	} else {
		$('footer .pagination li:eq(0)').css('display', 'none');
	}

	cascom.view.tags('.all-tags', 'select');

	cascom.window.resize();
	cascom.arrange();
};

cascom.arrange = function () {
	var mode = cascom.view.sortMode;
	function byMode(a, b) {
		switch (mode) {
		case 'title' : 
			if (a.title < b.title) {
				return -1;
			}
			if (a.title > b.title) {
				return 1;
			}
			return 0;
				
		case 'time' : 
			if (a.time.datetime < b.time.datetime) {
				return -1;
			}
			if (a.time.datetime > b.time.datetime) {
				return 1;
			}
			return 0;
				
		case 'tags' : 
			if (a.tags < b.tags) {
				return -1;
			}
			if (a.tags > b.tags) {
				return 1;
			}
			return 0;
				
		case 'type' : 
			if (a.type < b.type) {
				return -1;
			}
			if (a.type > b.type) {
				return 1;
			}
			return 0;
		}
	}
	
	cascom.everything.sort(byMode);
	
	var nrboxes = cascom.everything.length;
	if (cascom.view.sortMode === 'title') {
		cascom.window.columns = 1;
		var boxHeightSingle = Math.floor(nrboxes / cascom.window.columns) * cascom.window.tileSize; // Calculate container height
		$('.browse.view').css({
			'width' : 'auto',
			'height' : boxHeightSingle + 'px'
		});
	} else if (cascom.view.sortMode === 'time') {
		cascom.window.columns = 64;
		var boxWidth = (nrboxes) * cascom.window.tileSize;
		
		$('.browse.view').css({
			'width' : boxWidth + 32 + 'px',
			'height' : '100%'
		});
	} else {
		cascom.window.columns = Math.floor(cascom.window.contentWidth / cascom.window.tileSize); // Update number of columns to variable
		var boxHeight = Math.floor((nrboxes / cascom.window.columns) + 0.9) * cascom.window.tileSize; // Calculate container height
		
		$('.browse.view').css({
			'width' : 'auto',
			'height' : boxHeight + 'px'
		});
	}

	$.each(cascom.everything, function (index, box) {
		var heritage = cascom.everything[index].heritage,
			time = cascom.everything[index].time.datetime;
			
		$.each(cascom.data, function (model, object) {
			$.each(object, function (request, pages) {
				$.each(pages, function (page, post) {
					if (request !== 'tags') {
						$.each(post, function (key, item) {
							if (time === item.time.datetime && heritage === item.heritage) {
								cascom.move('#' + item.type + '-' + item.heritage + '-' + item.index, index, item.index);
							}
						});
					}
				});
			});
		});

		/*
		// DOM version
		$('article').each(function () { // Match object box with article box by time stamp
			var boxer = $(this);
			var heritageY = $(this).attr('id').split('-');
			var timeY = $(this).find('time').attr('time');
			if (timeX == timeY && heritageX == heritageY[1]) { // If same, add class with sorted position
				boxer.removeAttr('class').addClass(type + ' box box-' + ondex + ' positioned position-' + index);
				return true;
			}
		});
		*/
	});
	
};

cascom.move = function (target, position, delay) {								// Smooth arrangement of boxes
	
	var autoTop = Math.floor(position / cascom.window.columns) * cascom.window.tileSize,
		autoLeft = (position * cascom.window.tileSize) - (Math.floor(position / cascom.window.columns) * (cascom.window.columns * cascom.window.tileSize));

	$(target).removeClass('loading');
	
	if (Modernizr.csstransforms3d && Modernizr.csstransitions) {				// Hardware accelerated 3D CSS3 transition
		$(target)
			.css({
				'-webkit-transition-delay' : delay * 50 + 'ms', 
				'-webkit-transform' : 'translate3d(' + autoLeft + 'px, ' + autoTop + 'px, 0px)',
				'-moz-transition-delay' : delay * 50 + 'ms',
				'-moz-transform' : 'translate3d(' + autoLeft + 'px, ' + autoTop + 'px, 0px)',
				'-o-transition-delay' : delay * 50 + 'ms', 
				'-o-transform' : 'translate3d(' + autoLeft + 'px, ' + autoTop + 'px, 0px)'
			});

	} else if (Modernizr.csstransforms && Modernizr.csstransitions) {			// 2D CSS3 transition
		$(target)
			.css({
				'-webkit-transition-delay' : delay * 50 + 'ms',
				'-webkit-transform' : 'translate(' + autoLeft + 'px, ' + autoTop + 'px)',
				'-moz-transition-delay' : delay * 50 + 'ms',
				'-moz-transform' : 'translate(' + autoLeft + 'px, ' + autoTop + 'px)',
				'-o-transition-delay' : delay * 50 + 'ms',
				'-o-transform' : 'translate(' + autoLeft + 'px, ' + autoTop + 'px)'
			});
	} else {																	// $ animation
		$(target)
			.delay(delay * 50)
			.animate({
				left: '' + autoLeft + 'px', 
				top: '' + autoTop + 'px' 
			}, 'medium');
	}
};


// ! 
// !е Controller е
cascom.control = function (model) {
	var target = '#page';
	
	$.each(model, function (index, item) {
		var article = $('#' + item.type + '-' + item.heritage + '-' + item.index);
		
		article.hover(function () {
			cascom.tick.currentTime = 0;
			cascom.tick.play();
		}, 
		function() {
		
		});
		
		article.bind('click dblclick mouseover mouseout', function (event) {
			event.stopPropagation();
			if (event.type === 'mouseover') {							// !Hover In
				$(this).addClass('hover');

			} else if (event.type === 'mouseout') {						// !Hover Out
				$(this).removeClass('hover');
				
			} else if (event.type === 'click') {						// !Click
				event.preventDefault();
				
				cascom.tack.play();
				
				$(this).addClass('selected').siblings().removeClass('selected');
				
				$('aside').remove();									// !	Meta
				
				cascom.view.build.elements = [
					{ 
						aside : {
							'header': {
								h1 : {
									'text': 'Info'
								}
							},
							'ul': [
								{ style : 'display: block;' },
								{
									'li': {
										'className': 'odd',
										p : {
											'text': 'Type: ' + titleCaps(item.subtype === undefined ? item.type : item.subtype)
										}
									}
								},
								{
									'li': {
										time : {
											datetime : item.time.datetime,
											pubdate : 'pubdate',
											'text': 'Created: ' + item.time.form
										}
									}
								}, 
								{
									'li': {
										'className': 'odd',
										'a': {
											'className': 'link',
											'text': 'Link: ' + item.title,
											'href': item.url
										}
									}
								},
								{
									'li': {
										p : {
											'text': 'Tags: '
										},
										'ul': {
											'className': 'tags',
											'li': item.tags
										}
									}
								}
							],
							div : {},
							footer : {
								'ul': [
									{
										'li': {
											'a': {
												'href': '#', 
												'text': 'Info'
											} 
										} 
									}, 
									{
										'li': {
											'a': {} 
										} 
									}
								]
							}
						}
					}
				];
				
				if (item.geo !== undefined) {
					cascom.view.build.elements[0].aside.header.h1 = {
						'text': 'Map'
					};
					cascom.view.build.elements[0].aside.ul[0] = {
						style : 'display: none;'
					};
					cascom.view.build.elements[0].aside.div = {
						'text': 'Map',
						'className': 'map'
					};
					cascom.view.build.elements[0].aside.footer.ul[1].li.a = {
						'href': '#',
						'text': 'Map'
					};
					cascom.view.build.elements[0].aside.ul[5] = {
						'li': {
							'className': 'odd',
							p : {
								'text': 'Lat: ' + item.geo.lat + ', Long: ' + item.geo.long
							}
						}
					};
				}
				
				switch (item.type) {
				
				case 'bookmark' :										// !	Bookmark
					
					break;
				
				case 'photo' :											// !	Photo
					cascom.view.build.elements[0].aside.ul[6] = {
						'li': {
							p : {
								'text': 'Dimensions: ' + item.image.original.width + 'x' + item.image.original.height
							}
						}
					};
					break;
					
				case 'post' :											// !	Post
					switch (item.subtype) {
					case 'photo' :										// !		Photo
						cascom.view.build.elements[0].aside.ul[5] = {
							'li': {
								'className': 'odd',
								p : {
									'text': 'Dimensions: ' + item.photo.width + 'x' + item.photo.height
								}
							}
						};
						break;
					case 'link' :										// !		Link
						break;
					case 'quote' :										// !		Quote
						break;
					}
					break;
					
				case 'tweet' :											// !	Tweet
					
					break;
				}
				
				cascom.view.build.er('#sidebar');

				$('aside footer li').click(function () {
					var i = $(this).index();
					if (i === 0) {
						$('aside h1').text('Info');
						$('aside > div').slideUp('fast');
						$('aside > ul').slideDown('fast');
					} else {
						$('aside h1').text('Map');
						$('aside > ul').slideUp('fast');
						$('aside > div').slideDown('fast');
					}
				});
				
				if ($('aside .map').length !== 0) {
					cascom.view.map(item.geo.lat, item.geo.long);
				}
				
			} else if (event.type === 'dblclick') {						// !Double Click
				event.preventDefault();
				cascom.inter.play();
				
				cascom.view.build.elements = [
					{
						article : {				// !	Header
							id : 'page',
							'className': 'view ' + item.type + ' loading',
							'header': {
								'className': 'itunes',
								'a': {
									'href': '#',
									'text': 'Back',
									span : {
										'text': '\u25C0'
									}
								},
								h1 : {
									'text': item.title
								}
							}
						}
					}
				];
				
				cascom.view.build.er('#main');
				
				setTimeout(function () {
					$(target).removeClass('loading').addClass('open');
				}, 50);
				
				switch (item.type) {
			
				case 'bookmark' :										// !	Bookmark
					cascom.view.frame(item, target);
					break;
				
				case 'photo' :											// !	Photo
					cascom.view.tiles(item.image.original.url, item.title, item.image.original.width, item.image.original.height, target);
					break;
				
				case 'paper' :											// !	Paper
					cascom.view.frame(item, target);
					break;
				
				case 'post' :											// !	Post
					switch (item.subtype) {
					case 'photo' :										// !		Photo
						cascom.view.image(item.photo.url.large, item.photo.caption, target);
						break;
					
					case 'link' :										// !		Link
						cascom.view.build.elements = [
							{
								'a': {
									'className': 'link',
									'href': item.link.url, 
									'rel': 'bookmark',
									'text': item.link.text
								}
							}
						];
						cascom.view.build.er(target);
						break;
						
					case 'quote' :										// !		Quote
						cascom.view.build.elements = [
							{
								blockquote : {
									'text': '\u201C' + item.quote.text + '\u201D'
								}, 
								cite : {
									'text': 'via: ' + item.quote.url
								}
							}
						];
						cascom.view.build.er(target);
						break;
					}
					break;
					
				case 'sound' :											// !	Sound
					var soundUrl = 'http://soundcloud.com/oembed?url=' + item.embedUrl + '&color=FFFFFF&format=js&callback=?';
					cascom.view.build.elements = [
						{
							img : {
								src : item.image.replace('large', 'crop'),
								alt : item.artist + ' - ' + item.album
							}
						}
					];
					cascom.view.build.er(target);
					cascom.view.embed(soundUrl, target);
					break;

				case 'track' :											// !	Track
					cascom.view.build.elements = [
						{
							h2 : {
								'text': item.title
							},
							h3 : {
								'text': item.artist
							},
							h4 : {
								'text': item.album
							},
							img : {
								src : item.image.big,
								alt : item.artist + ' - ' + item.album
							}
						}
					];
					cascom.view.build.er(target);
					break;
				
				case 'tweet' :											// !	Tweet
					cascom.view.build.elements = [
						{
							p : {
								'text': item.text
							},
							em : {
								'text': item.tags
							},
							'a': {
								'href': 'http://twitter.com/' + item.screenname,
								img : {
									src : item.avatar,
									alt : item.name
								}
							}
						}
					];
					
					cascom.view.build.er(target);
					break;
				
				case 'video' :											// !	Video
					var vimeoUrl = 'http://vimeo.com/api/oembed.json?url=' + item.url + '&portrait=false&title=false&color=ffffff&callback=?';
					cascom.view.embed(vimeoUrl, target);
					break;
				}
				
				$('.browse').addClass('push');
				$('#page header a').bind('click', function () {
					event.preventDefault();
					cascom.control.close();
				});
			}
		});
		
	});
};

cascom.control.close = function () {
	$('#page').removeClass('open');
	setTimeout(function () {
		$('#page').remove();
	}, 500);
	$('.browse').removeClass('push');
};


cascom.control.page = function () {
	$('.pages a').bind('click', function (event) {
		if ($(this).attr('rel') !== 'archive') {
			event.preventDefault();
		}

		$('nav li').removeClass('active');
		$(this).parent().addClass('active');
		
		var viewMode = $(this).attr('rel');
		
		cascom.view.page(viewMode);
	});
};

cascom.control.source = function () {
	$('.sources a').bind('click', function (event) {
		event.preventDefault();
		
		$('nav li').removeClass('active');
		$(this).parent().addClass('active');
		
		var source = $(this).attr('rel');
		$('.browse').addClass('push');
		setTimeout(function() {
			$('.browse').removeClass('push');
			if (source === 'all') {
				cascom.model('all');
			} else {
				cascom.model('recent', source);
			}
			cascom.view.browse();
		}, 500);
	});
};

cascom.control.tag = function () {
	$('.tag a').bind('click', function (event) {
		event.preventDefault();
		
		$('nav li').removeClass('active');
		$(this).parent().addClass('active');
		
		var thisTag = $(this).text().trim();
		
		cascom.model('search', thisTag);
		cascom.view.browse();
	});
};

cascom.control.sort = function () {
	$('.sort-by a').bind('click', function (event) {
		event.preventDefault();
		
		$(this).parent().addClass('active').siblings().removeClass('active');
		
		var sortMode = $(this).attr('rel');

		$('body')
			.removeClass('title time tags type')
			.addClass(sortMode);
		
		cascom.view.sortMode = sortMode;
		cascom.window.resize();
		cascom.arrange();
	});
};

cascom.control.selectTags = function () {
	$('.tag a').live('click', function (event) {
		event.preventDefault();
		var thisTag = $(this).text();
		$('.browse article').each(function () {
			var thisBox = $(this);
			$(this).addClass('inactive');
			var boxTags = [];
			$(this).find('.tag').each(function (index) {
				boxTags[index] = $(this).text();
			});
			
			$.each(boxTags, function (i, tag) {
				if (thisTag === tag) {
					thisBox.removeClass('inactive').addClass('active');
				}
			});
		});
	});
};

cascom.control.modal = function () {
	$('#main > footer a').bind('click', function (event) {
		event.preventDefault();
		
		var moduleBox = $(this).attr('rel');
		
		switch (moduleBox) {
		case 'contact' :
			cascom.view.contact();
			break;
		case 'prev' :
			cascom.model('prev', cascom.reqtype);
			cascom.view.browse();
			break;
		case 'next' :
			cascom.model('next', cascom.reqtype);
			cascom.view.browse();
			break;
		case 'reset' :
			localStorage.clear();
			//console.log('clear');
			break;
		}
	});
};

cascom.control.search = function () {
	$('input[type=search]').keyup(function (key) {
		if (key.which === 13) {
			var searchquery = $(this).val();
			cascom.model('search', searchquery);
		}
	});
};

// !Window
cascom.window = cascom.window || {width: 768, tileSize: 256, columns: 4};

cascom.window.resize = function (view) {
	
	var newWindowWidth = Math.floor(cascom.window.calculate() / cascom.window.tileSize); // Calculate number of tiles that fit
	if (cascom.window.columns !== newWindowWidth) { 					// New?
	
//		if (cascom.window.contentWidth > 768) {
//			cascom.window.tileSize = 256;
//			$('body')
//				.removeClass('unit')
//				.removeClass('trio')
//				.addClass('duo');
//		} else if (cascom.window.contentWidth > 512) {
//			cascom.window.tileSize = 192;
//			$('body')
//				.removeClass('unit')
//				.removeClass('duo')
//				.addClass('trio');
//		} else {
//			cascom.window.tileSize = 128;
//			$('body')
//				.removeClass('duo')
//				.removeClass('trio')
//				.addClass('unit');
//		}
		
		cascom.arrange();
		
	}
};

cascom.window.calculate = function () {
	cascom.window.contentWidth = $('body').width() - $('nav').outerWidth();
	$('#main').css('width', cascom.window.contentWidth + 'px');
	return cascom.window.contentWidth;
};
