/**
 * @author Sergey Chikuyonok (serge.che@gmail.com)
 * @link http://chikuyonok.ru
 * 
 * @include "perlin-noise.js"
 */
$(function(){
	var root = $('#night-sky'),
		clients_root = root.find('.clients'),
		sky = root.find('.sky'),
		clients = clients_root.find('em'),
		star_namespace = 'star',
		star_anim_options = {
			transition: 'linear',
			namespace: star_namespace,
			onComplete: function(){
				this.start();
				this.is_forward = !this.is_forward;
			}
		},
		
		is_zoom_supported = (typeof(document.body.style.zoom) != 'undefined'),
		is_minimized = false,
		
		normal_color = '#fc7828',
		hilite_color = '#ffffff',
		
		stars = [],
		
		cursor_pos = -1,
		cur_sky_pos = 0,
		req_sky_pos = 0,
		
		current_scale = 1,
		
		window_width = 0,
		window_height = 0,
		sky_width = 0;
	
	function rnd(x1, x2) {
		return (x2 - x1) * Math.random() + x1;
	}
	
	function cacheSizes() {
		var w = $(window);
		window_width = w.width();
		window_height = w.height();
		checkVisibility();
	}
	
	function getRealScale(scale) {
		return 0.5 + 0.5 * scale;
	}
	
	var scaleClients = function(scale) {
		current_scale = scale;
		clients_root[0].style.fontSize = getRealScale(scale) + 'em';
	}
	
	var measureClientsWidth = function(scale) {
		var old_scale = current_scale;
		scaleClients(scale);
		var width = clients_root[0].offsetWidth;
		scaleClients(old_scale);
		return width;
	}
	
	if (typeof(document.body.style.webkitTransform) != 'undefined') {
		var scaleClients = function(scale) {
			current_scale = scale;
			clients_root[0].style.webkitTransform = 'scale(' + getRealScale(scale) + ')';
		}
		
		var measureClientsWidth = function(scale) {
			return clients_root[0].offsetWidth * getRealScale(scale);
		}
	}
	
	
	
	/**
	 * Мерцание звезды
	 * @param {Element} elem
	 */
	function blinkStar(evt) {
		if (is_minimized)
			return;
			
		var elem = this;
		var jq_elem = $(elem);
		if (jq_elem.data('is-blinking'))
			return
		
		var delay = 70;
		
		var link_inner = jq_elem.find('span');
		jq_elem.data('is-blinking', true);
		
		var img = jq_elem.find('img');
		
		if (!img.length) {
			var img = $('<img src="/f/i/stars-glow-blue.png"/>').css({
				width: link_inner.width() + 30,
				height: link_inner.height() + 30,
				opacity: 0
			}).appendTo(jq_elem);
		}
		
		jq_elem.css('color', hilite_color);
		
		setTimeout(function(){
			jq_elem.css('color', normal_color)
		}, delay);
		
		setTimeout(function(){
			jq_elem.css('color', hilite_color);
			
			$t(elem).tween({
				color: normal_color,
				time: 0.6,
				transition: 'easeincubic',
				onComplete: function() {
					jq_elem.data('is-blinking', false);
				}
			});
			
			img.css({
				opacity: 1,
				left: link_inner[0].offsetLeft - 15, 
				top: link_inner[0].offsetTop - 15
			});
			
			$t(img).tween({
				opacity: 0,
				transition: 'linear',
				time: 0.6
			});
			
			
			
		}, delay * 2);
		
//		$t(elem).tween({
//			color: hilite_color,
//			transition: 'easeoutcubic',
//			time: 0.2,
//			onComplete: function() {
//				
//			}
//		});
	}
	
	/**
	 * Проверяем видимость блоков/звезд на экране. Если блок не виден, то его 
	 * незачем анимировать.
	 */
	function checkVisibility() {
		$.each(stars, function(i, /* AnimProxy */ n){
			var top = n.elem.offsetTop,
				left = n.elem.offsetLeft + cur_sky_pos;
//			var pos = $(n.elem).offset();
			n.is_visible = (window_width > left && window_height > top);
		});
	}
	
	/**
	 * @param {Number} dx
	 * @param {Number} dy
	 * @param {Element} elem
	 */
	function AnimProxy(elem) {
		this.dx = rnd(-15, 15);
		this.dy = rnd(-10, 10);
		
		this.last_x = 0;
		this.last_y = 0;
		
		this.elem = elem;
		this.st = elem.style;
		this.tw = $t(this, star_anim_options);
		this.is_forward = true;
		this.is_visible = false;
		
		stars.push(this);
	}
	
	AnimProxy.prototype = {
		move: function(val) {
			if (!this.is_visible)
				return;
			
			if (!this.is_forward)
				val = 1 - val;
				
			var x = Math.round(this.dx * val),
				y = Math.round(this.dy * val);
				
			if (x != this.last_x || y != this.last_y) {
				this.st.left = (this.dx * val) + 'px';
				this.st.top = (this.dy * val) + 'px';
			}
			
			this.last_x = x;
			this.last_y = y;
		},
		
		start: function() {
			this.tw.addOptions({time: rnd(30, 35)}).percent(this.move);
		}
	};
	
	/**
	 * Хаотически размещаем звезды на странице
	 */
	function initStars() {
		var min_margin = 2,
			max_margin = 50,
			pi2 = Math.PI / 2,
			total_clients = clients.length,
			
//			total_blocks = 24,
			total_blocks = 0,
			max_width = 70,
			bz_sh = {
				x1: 0.1,
				y1: 0,
				
				c1x: -0.1,
				c1y: 0,
				
				c2x: 0.3,
				c2y: 0.86,
				
				x2: 1,
				y2: 1
			};
		
		for (var i = 0; i < total_blocks; i++) {
			var t = i / total_blocks;
//			var bz = jTweener.Utils.bezier3(t, bz_sh.x1, bz_sh.c1x, bz_sh.c2x, bz_sh.x2);
//			var width = Math.max(bz * max_width, 0);
			var width = (1 - Math.abs(Math.cos(pi2 * i / total_blocks)) ) * max_width;
//			var width = (1 - i / total_blocks) * max_width;
			
			$('<div class="wr"></div>')
				.css('width', width + 'em')
				.prependTo(clients_root);
				
			$('<div class="wl"></div>')
				.css('width', width + 'em')
				.prependTo(clients_root);
		}
			
		var total_clients = clients.length,
			last_y = -1,
			pad_width = 0,
			left = 150;
		clients.each(function(i, n){
			var elem = $(n);
			
			if (n.offsetTop != last_y)
				pad_width = rnd(0, 0.5);
			
			elem
				.css({
					top: rnd(-1.5, 1.5) + 'em',
					marginLeft: ((rnd(0, 1) * 0.5 + pad_width) * 15) + 'em',
					marginRight: ((rnd(0, 1) * 0.5 + pad_width) * 15) + 'em',
					left: (rnd(-left, left)) + 'px'
				})
				.wrapInner('<span/>')
				.mouseover(blinkStar);
				
			var anim_obj = new AnimProxy(elem.find('span')[0]);
//			anim_obj.start();
			
			last_y = n.offsetTop;
		});
	}
	
	/**
	 * Уменьшает звезды
	 */
	function minimize() {
		$t(clients_root).tween({
			scale: function(val){
				scaleClients(1 - val);
			},
			left: (window_width - measureClientsWidth(0)) / 2,
			transition: 'easeoutcubic',
			time: 1,
			onComplete: checkVisibility
		});
		
		
		
		is_minimized = true;
	}
	
	function maximize() {
		$t(clients_root).tween({
			scale: function(val){
				scaleClients(val);
			},
			left: (window_width - sky_width) * (cursor_pos / window_width),
			transition: 'easeinoutcubic',
			time: 1,
			onComplete: function() {
				checkVisibility();
				is_minimized = false;
			}
		});
	}
	
	var is_panning = false;
	
	function panStarsToCursor() {
		panStarsToPercent(cursor_pos / window_width)
	}
	
	function panStarsToPercent(percent) {
		// считаем координату, в которой должно быть небо
		req_sky_pos = (window_width - sky_width) * percent;
		startPanning();
	}
	
	function startPanning() {
		if (!is_panning) 
			panStarsToCursorAnim();
	}
	
	function panStarsToCursorAnim() {
		if (is_minimized) {
			is_panning = false;
			return;
		}
			
		var offset = (req_sky_pos - cur_sky_pos) * 0.2,
			max_offset = 50;
		if (Math.abs(offset) > max_offset)
			offset = max_offset * ( offset > 0 ? 1 : -1 );
			
			
		cur_sky_pos += Math.round(offset);
		clients_root.css('left', cur_sky_pos);
		sky.css('left', cur_sky_pos * 0.5);
		
		if (Math.abs(cur_sky_pos - req_sky_pos) > 2) {
			is_panning = true;
			setTimeout(panStarsToCursorAnim, 30);
		}
		else {
			is_panning = false;
			checkVisibility();
		}
	}
	
	function toggleTelescope() {
		var lens = $('#telescope .lens');
		lens.toggleClass('lens-opened').removeClass('lens-closed');
		var left = lens[0].offsetLeft,
			top = lens[0].offsetTop;
		
		lens.toggleClass('lens-opened');
		$t(lens).tween({
			top: top,
			left: left,
			time: 0.6,
			transition: 'easeinoutquad',
			onComplete: function() {
				lens.toggleClass('lens-opened').css({
					left: '',
					top: ''
				});
				
				if (!lens.hasClass('lens-opened'))
					lens.addClass('lens-closed');
			}
		});
	}
	
	initStars();
	
	$(window).resize(cacheSizes);
	cacheSizes();
	
	sky_width = clients_root.width();
	
	// звезды должны быть в минимизированном состоянии
	is_minimized = true;
	scaleClients(0);
	clients_root.css({left: (window_width - measureClientsWidth(0)) / 2});
	
	
	$('#telescope')
		.click(function(){
			if (is_minimized)
				maximize();
			else
				minimize();
			toggleTelescope();
		});
	
	$(document)
		.mousemove(function(/* Event */ evt) {
			cursor_pos = evt.pageX;
			if (!is_minimized)
				panStarsToCursor();
		});
		
//	$('#star').one('click', function(){
//		if (!is_minimized)
//			minimize();
//		dropStar();
//	});
	
	
});
