

window.addEvent('domready', function() {
	$$('.widget-feed').each(function(el) { new WidgetFeed(el) });
	$$('.widget-video').each(function(el) { new WidgetVideo(el) });
});




WidgetVideo = new Class({
	Implements: Options,
	options: {
		categories:	[],
		perpage:	4,
		startpage:	0,
		animation: {
			transition:	Fx.Transitions.Back.easeInOut,
			//transition:	Fx.Transitions.Sine.easeIn,
			step:		80,
			duration:	650,
			pause:		0
		}
	},
	curpage: 0,
	curdirection: 'up',
	total: 100,

	initialize: function(container) {
		this.container = $(container);
		if(!this.container) return;

		this.feedContainer = this.container.getElement('.wv-feed');
		this.playerContainer = this.container.getElement('.wv-player-container');
		if(!this.feedContainer || !this.playerContainer) return;

		this.setOptions( JSON.decode(this.container.getAttribute('data-feed')) );


		['up', 'down'].each(function(direction) {
			new Element('div', {
				'class': 'feed-arrow',
			})
			.addClass('feed-arrow-'+direction)
			.store('controller', this)
			.store('direction', direction)
			.addEvents({
				click: function() {
					var controller = this.retrieve('controller');
					(this.retrieve('direction') == 'up') ? controller.pageUp() : controller.pageDown();
				},
				mouseover: function() {
					var controller = this.retrieve('controller');
					if(this.retrieve('direction') == 'up') {
						if(controller.curpage > 0) this.addClass('hover');
					}
					else {
						if( ((controller.curpage + 1) * controller.options.perpage) >= controller.total ) return;
						else this.addClass('hover');
					}
				},
				mouseout: function() {
					this.removeClass('hover');
				}
			})
			.inject(this.feedContainer);			
		}.bind(this));


		this.request = new Request.JSON({
			url:		'/x/widgets/video',
			noCache:	true,
			link:		'ignore',
			method:		'post',
			onComplete: function(resp) {
				if(resp.success) this.loadData(resp);
			}.bind(this)
		});


		this.showPage( this.options.startpage );

	},

	pageUp: function() {
		this.showPage(this.curpage - 1);
		this.curdirection = 'down';
	},

	pageDown: function() {
		this.showPage(this.curpage + 1);
		this.curdirection = 'up';
	},

	showPage: function(page) {
		if(this.locked) return;

		if(page < 0) return;
		else if( (page * this.options.perpage) >= this.total ) return;

		this.curpage = page;
		var data = {
			categories:	this.options.categories,
			offset:		this.options.perpage * (this.curpage),
			limit:		this.options.perpage
		};
		this.request.send({ data: data });
	},


	loadData: function(resp) {
		if(this.locked) return;
		else this.locked = true;

		this.feedContainer.scrollTo(0, 0);
		this.total = resp.total;

		Array.from(resp.preload).each(function(href) { var n = new Image(); n.src = href; });

		var chain = new Chain().chain(function() {
			if(resp.items[0] && !this.playerContainer.getChildren().length) this.loadPreview(resp.items[0]);


			this.container.getElements('.wv-feed-item').addClass('wv-outgoing');
			resp.items.each(function(item) {
				var el = new Element('div', { 'class': 'wv-feed-item' })
					.addClass('wv-incoming')
					.setStyles({
						top: this.feedContainer.getHeight() * -2,
						backgroundImage: 'url("'+item.thumbs[0].url+'")'
					})
					.store('controller', this)
					.store('vdata', item)
					.set('title', item.title)
					.addEvent('click', function() {
						var controller = this.retrieve('controller');
						var vdata = this.retrieve('vdata');
						controller.loadPreview(vdata);
					})
					.inject(this.feedContainer)
				;
			}.bind(this));

			chain.callChain();
		}.bind(this)).chain(function() {
			this.animate(chain);
		}.bind(this)).chain(function() {
			this.locked = false;
		}.bind(this));
		chain.callChain();
		
		return;
	},

	Player: new Class({
		initialize: function(parent, vdata) {
			this.widget = parent;
			this.vdata = vdata;
			var self = this;

			if( swfobject.getFlashPlayerVersion().major.toInt() == 0 ) {
				window.open(vdata.href, '_blank');
				return;
			}
			var prv = this.widget.playerContainer.getElement('.wv-preview');
			if(!prv) return;

			this.divFrame = new Element('div')
				.set('id', String.uniqueID())
				.setStyles({
					position: 'absolute',
					padding: '0px',
					zIndex: 301,
					width: prv.getWidth(),
					height: prv.getHeight(),
					top: prv.getTop() - 2,
					left: prv.getLeft() - 2
				})
				.addClass('yt-player-frame')
			.inject($(document.body));

			// clone for preview
			this.divPlayer = this.widget.playerContainer.clone()
				.set('id', String.uniqueID()).addClass('yt-player').setStyles({ margin: '0px' })
			.inject( this.divFrame );

			// get rid of cloned title and button
			this.divPlayer.getElements('.wv-preview div').each(function(el) { $(el).destroy() });

			this.widget.playerContainer.setStyle('visibility', 'hidden');

			this.ytcontrols = new Element('div', { styles: { opacity: 0 } })
				.set('tween', { duration: 500 }).addClass('yt-frame-controls');
			new Element('div')
				.addClass('yt-youtube')
				.addEvent('click', function() { window.open(self.vdata.href, '_blank'); self.close();  })
			.inject(this.ytcontrols);

			new Element('div')
				.addClass('yt-close')
				.addEvent('click', function() { self.close() })
			.inject(this.ytcontrols);


			this.overlay = new Overlay({ zIndex: 300 });
			this.overlay.addEvents({
				complete: function() {
					if(this.overlay.status) {
						this.divPlayer.setStyle('border-color', '#106631');

						var db = $(document.body);
						var dim = { x: 640, y: 390 };

						new Fx.Morph(this.divFrame, {
							duration: 600,
							transition: Fx.Transitions.Sine.easeOut,
							onComplete: function() { this.loadyt() }.bind(this)
						}).start({
							top: ((db.getHeight() / 2) - (dim.y / 2) + db.getScroll().y - 20) * .90,
							left: (db.getWidth() / 2) - (dim.x / 2) - 20,
							width: dim.x, height: dim.y, padding: '20px'
						});

					} else {
						this.overlay.destroy();
					}
				}.bind(this)
			});
			this.overlay.show();
		},

		launchExternal: function() {
			window.open(this.vdata.href, '_blank');
			this.close();
		},

		loadyt: function() {
			this.ytcontrols.inject(this.divFrame, 'top').tween('opacity', 1);
			this.yt = new YouTube({
				v:	 this.vdata.identifier,
				v_title: this.vdata.title,
				autoplay: true,
				onLoad: function() { }
			})
			.addEvent('failure', function(swf) {
				this.launchExternal();
			});
			this.yt.embed(this.divPlayer.getElement('.wv-preview'));
		},

		close: function() {
			this.widget.playerContainer.setStyle('visibility', 'visible');
			if(this.overlay) this.overlay.hide();
			if(this.divFrame) {
				new Fx.Tween(this.divFrame, {
					duration: 300,
					onComplete: this.cleanup.bind(this)
				}).start('opacity', 0);
			} else this.cleanup();
		},
		cleanup: function() {
			if(this.yt) this.yt.destroy();
			delete this.yt;

			try {
				$(this.divPlayer).destroy();
				$(this.divFrame).destroy();
			} catch(e) { };
		}
	}),
	loadPreview: function(vdata) {
		this.playerContainer.empty();

		var th = vdata.thumbs[vdata.thumbs.length-1];

		var prv = new Element('div')
			.addClass('wv-preview')
			.setStyle('backgroundImage', 'url("'+th.url+'")')
		.inject(this.playerContainer);

		new Element('div')
			.addClass('video-title')
			.set('html', '<div>'+vdata.title+'</div>')
		.inject(prv);


		/****************************************/
		new Element('div')
			.addClass('button-play')
			.addEvent('click', function() {
				this.player = new this.Player(this, vdata)
			}.bind(this))
		.inject(prv);
	},

	animate: function(chain) {
		var fx = new WidgetPageChangeFx(this.feedContainer, {
			count:		this.options.perpage,
			transition:	this.options.animation.transition,
			step:		this.options.animation.step,
			duration:	this.options.animation.duration,
			pause:		this.options.animation.pause,

			outgoing:	'wv-outgoing',
			incoming:	'wv-incoming',
			direction:	this.curdirection
		});
		if(chain) fx.addEvent('complete', function() { chain.callChain() });
		fx.animate();
	}

});


WidgetFeed = new Class({
	Implements: Options,
	options: {
		feeds:		[],
		categories:	[],
		perpage:	4,
		startpage:	0,

		animation: {
			transition:	Fx.Transitions.Back.easeInOut,
			//transition:	Fx.Transitions.Sine.easeIn,
			step:		80,
			duration:	650,
			pause:		0
		}
	},
	curpage: 0,
	curdirection: 'up',
	total: 100,

	initialize: function(container) {

		this.container = $(container);
		if(!this.container) return;

		this.feedContainer = this.container.getElement('.wf-feed');
		if(!this.feedContainer) return;

		this.setOptions( JSON.decode(this.container.getAttribute('data-feed')) );


		this.container.getElements('.wf-soc')
			.store('controller', this)
			.addEvents({
				mouseover: function() {
					var controller = this.retrieve('controller');
					controller.container.getElements('.wf-social-roll-caption').setStyle('display', 'none');
					var cls = '.wf-social-roll-caption.'+this.className.split(/\s+/).pop();
					controller.container.getElements(cls).setStyle('display', 'block');
				},
				mouseout: function() {
					var controller = this.retrieve('controller');
					controller.container.getElements('.wf-social-roll-caption').setStyle('display', 'none');
				}
			})
		;

		['up', 'down'].each(function(direction) {
			new Element('div', {
				'class': 'feed-arrow',
			})
			.addClass('feed-arrow-'+direction)
			.store('controller', this)
			.store('direction', direction)
			.addEvents({
				click: function() {
					var controller = this.retrieve('controller');
					(this.retrieve('direction') == 'up') ? controller.pageUp() : controller.pageDown();
				},
				mouseover: function() {
					var controller = this.retrieve('controller');
					if(this.retrieve('direction') == 'up') {
						if(controller.curpage > 0) this.addClass('hover');
					}
					else {
						if( ((controller.curpage + 1) * controller.options.perpage) >= controller.total ) return;
						else this.addClass('hover');
					}
				},
				mouseout: function() {
					this.removeClass('hover');
				}
			})
			.inject(this.feedContainer);			
		}.bind(this));


		this.request = new Request.JSON({
			url:		'/x/widgets/feed',
			noCache:	true,
			link:		'ignore',
			method:		'post',
			onComplete: function(resp) {
				if(resp.success) this.loadData(resp);
			}.bind(this)
		});


		this.showPage( this.options.startpage );
	},

	pageUp: function() {
		this.showPage(this.curpage - 1);
		this.curdirection = 'down';
	},

	pageDown: function() {
		this.showPage(this.curpage + 1);
		this.curdirection = 'up';
	},

	showPage: function(page) {
		if(this.locked) return;

		if(page < 0) return;
		else if( (page * this.options.perpage) >= this.total ) return;

		this.curpage = page;
		var data = {
			feeds:		this.options.feeds,
			categories:	this.options.categories,
			offset:		this.options.perpage * (this.curpage),
			limit:		this.options.perpage
		};
		this.request.send({ data: data });
	},

	loadData: function(resp) {
		if(this.locked) return;
		else this.locked = true;

		this.feedContainer.scrollTo(0, 0);
		this.total = resp.total;

		var chain = new Chain().chain(function() {

			this.container.getElements('.wf-feed-item').addClass('wf-outgoing');

			var n = 0;
			resp.items.each(function(item) {
				var el = new Element('div', { 'class': 'wf-feed-item' })
					.addClass('wf-incoming')
					.setStyles({ top: this.feedContainer.getHeight() * -2 })
					.addEvent('click', function() { })
					.inject(this.feedContainer)
				;
				new Element('a', { href:item.href, title:item.feed.title+': '+item.title, target:'_blank' }).set('html', item.title).inject(el);
				if(++n < resp.items.length) new Element('div', { 'class': 'dotline' }).inject(el);
			}.bind(this));

			chain.callChain();
		}.bind(this)).chain(function() {
			this.animate(chain);
		}.bind(this)).chain(function() {
			this.locked = false;
		}.bind(this));
		chain.callChain();

		
		return;
	},

	animate: function(chain) {
		var fx = new WidgetPageChangeFx(this.feedContainer, {
			count:		this.options.perpage,
			transition:	this.options.animation.transition,
			step:		this.options.animation.step,
			duration:	this.options.animation.duration,
			pause:		this.options.animation.pause,

			outgoing:	'wf-outgoing',
			incoming:	'wf-incoming',
			direction:	this.curdirection
		});
		if(chain) fx.addEvent('complete', function() { chain.callChain() });
		fx.animate();
	}
});


WidgetPageChangeFx = new Class({
	Implements: [Options, Events],
	options: {
		count:		0,
		transition:	'null',
		step:		0,
		duration:	0,
		pause:		0,

		outgoing:	'',
		incoming:	'',
		direction:	'up'
	},
	initialize: function(container, options) {
		this.container = $(container);
		this.setOptions(options);

		this.outgoing = this.container.getElements('.'+this.options.outgoing).removeClass(this.options.outgoing);
		this.incoming = this.container.getElements('.'+this.options.incoming).removeClass(this.options.incoming);

		this.options.height = this.container.getHeight();
		this.options.rowheight = this.options.height / this.options.count;

		this.positions = {
			top:	new Array(this.options.count),
			mid:	new Array(this.options.count),
			bot:	new Array(this.options.count),
			rev:	{ top:[], mid:[], bot:[] }
		};

		for(var i=0; i<this.options.count; ++i) {
			this.positions.mid[i] = i * this.options.rowheight;
			this.positions.bot[i] = this.positions.mid[i] + this.options.height;
			this.positions.top[i] = this.positions.bot[i] * -1;
		}

		for(var i=this.options.count-1, n=0; i>=0; --i, ++n) {
			this.positions.rev.top[n] = this.positions.top[i];
			this.positions.rev.mid[n] = this.positions.mid[i];
			this.positions.rev.bot[n] = this.positions.bot[i];
		}

		// position incoming
		var lst = this.listEls(this.incoming);
		var pos = (this.options.direction=='up') ? this.positions.bot : this.positions.top;
		for(var i=0; i<this.options.count; ++i) {
			if(lst[i]) lst[i].setStyle('top', pos[i]);
		}

		
	},
	listEls: function(arr, reverse) {
		var out = [];
		if(reverse) for(var i=arr.length-1; i>=0; --i) out.push(arr[i]);
		else  for(var i=0; i<arr.length; ++i) out.push(arr[i]);
		return out;
	},

	animate: function() {
		var delay = 0;

		// outgoing
		var lst, pos;
		if( this.options.direction == 'up' ) {
			lst = this.listEls(this.outgoing, false);
			pos = this.positions.top;
		} else {
			lst = this.listEls(this.outgoing, true);
			pos = this.positions.bot;
		}
		if(lst.length > 0) {
			var index = 0;
			lst.each(function(el) {
				var _pos = pos[index];

				setTimeout(function() {
					new Fx.Tween(el, {
						duration: this.options.duration,
						transition: this.options.transition,
						onComplete: function() { el.destroy(); }
					}).start('top', _pos);
				}.bind(this), delay);

				delay += this.options.step; 
				++index;
			}.bind(this));

			// pause
			delay += this.options.pause;
		}

		// incoming
		var lst, pos;
		if( this.options.direction == 'up' ) {
			lst = this.listEls(this.incoming, false);
			pos = this.positions.mid;
		} else {
			lst = this.listEls(this.incoming, true);
			pos = this.positions.rev.mid;
		}
		var index = 0;
		lst.each(function(el) {
			var _pos = pos[index];
			setTimeout(function() {
				new Fx.Tween(el, {
					duration: this.options.duration,
					transition: this.options.transition
				}).start('top', _pos);
			}.bind(this), delay);

			delay += this.options.step; 
			++index;
		}.bind(this));

		setTimeout(function() { this.fireEvent('complete') }.bind(this), delay);
	}
});


