/**
 * MooFlow - Image gallery
 *
 * Dependencies: MooTools 1.2
 *
 * @version			0.2.1
 *
 * @license			MIT-style license
 * @author			Tobias Wetzel <info [at] outcut.de>; adapted by Lennart Kruse <lennart [at] crusy.net>
 * @copyright		Author
 * @docmentation	http://outcut.de/MooFlow/Docmentation.html
 */ 

var allVideos = [];

var MooFlow = new Class({

	Implements: [Events, Options],
	
	options: {
		onStart: $empty,
		onClickView: $empty,
		onRequest: $empty,
		onResized: $empty,
		onEmptyinit: $empty,
		heightRatio: 0.6,
		offsetY: -220,
		factor: 125,
		useResize: true,
		useWindowResize: true,
		useViewer: true
	},
	
	initialize: function(element, options){
		this.MooFlow = element;
		this.setOptions(options);
		this.foc = 120;
		this.factor = this.options.factor;
		this.offY = this.options.offsetY;
		this.isFull = false;
		this.isLoading = false;
		this.inMotion = false;
		
		this.MooFlow.addClass('mf').setStyles({
			'overflow':'hidden',
			'position':'relative',
			'height':this.MooFlow.getSize().x*this.options.heightRatio,
			'opacity':0
		});
		
		if(this.options.useWindowResize) window.addEvent('resize', this.update.bind(this, 'init'));
		this.MooFlow.addEvent('mousewheel', this.wheelTo.bind(this));
		document.addEvent('keydown', this.keyTo.bind(this));
		
		this.getElements(this.MooFlow);
	},
	
	getElements: function(el){
		this.master = {'images':[]};
		var els = el.getChildren();
		if(!els.length) {this.fireEvent('emptyinit'); return;}
		$$(els).each(function(el){
			var hash = $H(el.getElement('img').getProperties('src'));
			hash.combine({'caption':el.getElement('h1').get('html')});
			if(el.getElement('div.caption')) hash.combine({'category':el.getElement('div.caption').get('html')});
			else hash.combine({'category':'&nbsp;'});
			hash.combine({'description':(el.getElements('p').get('html')).join('<br/><br/>')});
      hash.combine({'active':true});
      var appearsinslider = el.getProperty('class').toLowerCase().indexOf('appearsinslider')>-1;
      hash.combine({'appearsinslider':appearsinslider});
			if( appearsinslider ) this.master['images'].push(hash.getClean());
      allVideos.push(hash.getClean());
			el.dispose();
		}, this);
		this.clearMain();
	},

	clearMain: function(){
		if(this.details){this.details.fade(0);}
		if(!this.details){
			this.MooFlow.empty();
			this.createAniObj();
		}
	},
	
	getMooFlowElements: function(key){
		var els = [];
		this.master.images.each(function(el){ 
			els.push(el[key]); 
		});
		return els;
	},
	
	createAniObj: function(){
		this.aniFx = new Fx.Value({
			'transition': Fx.Transitions.Expo.easeOut,
			'link': 'cancel',
			'duration': 400,
			'onMotion': this.process.bind(this),
			'onStart': this.flowStart.bind(this),
			'onComplete': this.flowComplete.bind(this)
		});
		this.addLoader();
	},
	
	addLoader: function(){
		this.MooFlow.store('height', this.MooFlow.getSize().y);
		this.loader = new Element('div',{'class':'loader'}).inject(this.MooFlow);
		new Fx.Tween(this.MooFlow, {
			'duration': 800,
			'onComplete': this.preloadImg.bind(this)
		}).start('opacity', 1);
	},
	
	preloadImg: function(){
		this.loadedImages = new Asset.images(this.getMooFlowElements('src'), {
			'onComplete': this.loaded.bind(this),
			'onProgress': this.createMooFlowElement.bind(this)
		});
	},
	
	createMooFlowElement: function(counter, i){
		var obj = this.getCurrent(i);
		var img = this.loadedImages[i];
		obj['width'] = img.width;
		obj['height'] = img.height;
		img.removeProperties('width','height');

		obj['div'] = new Element('div').setStyles({
			'position':'absolute',
			'display':'none',
			'cursor':'pointer',
			'height': this.MooFlow.getSize().y
		}).inject(this.MooFlow);
		obj['con'] = new Element('div').setStyle('position','relative').inject(obj['div']);
		img.setStyles({'vertical-align':'bottom', 'width':'100%', 'height':'50%'});
		img.addEvents({'click': this.clickTo.bind(this, i)});
		img.inject(obj['con']);
	},
	
	loaded: function(){
		this.index = Math.floor((this.master.images.length-1)/2);
		this.iL = this.master.images.length-1;
/*		new Fx.Tween(this.loader, {
			'duration': 800,
			'onComplete': this.createUI.bind(this)
		}).start('opacity', 0);*/
    this.createUI();
	},
	
	createUI: function(){
		this.loader.dispose();
		this.details = this.details || new Element('div').addClass('details').set('opacity',0).inject( $('videos'), 'after' );
		this.cap = this.cap || new Element('div').addClass('caption').inject(this.details);
		this.desc = this.desc || new Element('div').addClass('description').inject(this.details);
    this.left = this.left || new Element('div').setProperty('id','left').setStyle('z-index',this.master.images.length).inject( $('videos'), 'after' ).addEvents({'click': this.prev.bind(this)}).set('tween',{duration:100});
    this.right = this.right || new Element('div').setProperty('id','right').setStyle('z-index',this.master.images.length).inject( $('videos'), 'after' ).addEvents({'click': this.next.bind(this)}).set('tween',{duration:100});
    $('videos').getParent().addEvents({
      'mouseenter': function(){
       $('left').fade(1);
       $('right').fade(1);
      },
      'mouseleave': function(){
        $('left').fade(0);
        $('right').fade(0);
      }
    });

		this.showUI();
	},
	
	showUI: function(){
    this.left.fade(0);
    this.right.fade(0);
		if(this.details) this.details.fade(1);
		this.fireEvent('start');
		this.update();
	},
	
	update: function(e){
		if(e == 'init') return;
		this.oW = this.MooFlow.getSize().x;
		this.sz = this.oW * 0.5;
		this.glideTo(this.index);
		this.isLoading = false;
	},
	
	setScreen: function(){
		if(this.isFull = !this.isFull){
			this.holder = new Element('div').inject(this.MooFlow,'after');
			this.MooFlow.wraps(new Element('div').inject(document.body));
			this.MooFlow.setStyles({'position':'absolute','z-index':'100','top':'0','left':'0','width':window.getSize().x,'height':window.getSize().y});
			if(this.options.useWindowResize){
				this._initResize = this.initResize.bind(this);
				window.addEvent('resize', this._initResize);
			}
		} else {
			this.MooFlow.wraps(this.holder);
			window.removeEvent('resize', this._initResize);
			delete this.holder, this._initResize;
			this.MooFlow.setStyles({'position':'relative','z-index':'','top':'','left':'','width':'','height':this.MooFlow.retrieve('height')});
		}
		this.fireEvent('resized', this.isFull);
		this.update();
	},
	
	initResize: function(){
		this.MooFlow.setStyles({'width':window.getSize().x,'height':window.getSize().y});
		this.update();
	},
	
	getCurrent: function(index){
		return this.master.images[$chk(index) ? index : this.index];
	},
	
	loadJSON: function(url){
		if(!url || this.isLoading) return;
		this.isLoading = true;
		new Request.JSON({
			'onComplete': function(data){
				if($chk(data)){
					this.master = data;
					this.clearMain();
					this.fireEvent('request', data);
				}
			}.bind(this)
		}, this).get(url);
	},
	
	loadHTML: function(url, filter){
		if(!url || !filter || this.isLoading) return;
		this.isLoading = true;
		new Request.HTML({
			'onSuccess': function(tree, els, htm){
				var result = new Element('div', {'html': htm}).getChildren(filter);
				this.getElements(result);
				this.fireEvent('request', result);
			}.bind(this)
		}, this).get(url);
	},
	
	flowStart: function(){
		this.inMotion = true;
	},
	
	flowComplete: function(){
		this.inMotion = false;
	},
	
	viewCallBack: function(index){
		if(this.index != index || this.inMotion) return;
		var el = $H(this.getCurrent());
		var returnObj = {};
		returnObj['coords'] = el.div.getElement('img').getCoordinates();
		el.each(function(v, k){
			if($type(v) == 'number' || $type(v) == 'string') returnObj[k] = v;
		}, this);
		this.fireEvent('clickView', returnObj);
	},
	prev: function(){
		if(this.index > 0) this.clickTo(this.index-1);
	},
	next: function(){
		if(this.index < this.iL) this.clickTo(this.index+1);
	},
	keyTo: function(e){
		switch (e.code){
			case 37: e.stop(); this.prev();	break;
			case 39: e.stop(); this.next();
		}
	},
	wheelTo: function(e){
		if(e.wheel > 0) this.prev();
		if(e.wheel < 0) this.next();
		e.stop().preventDefault();
	},
	clickTo: function(index){
		if(this.index == index){
			this.viewCallBack(index);
			return;
		}
		if(this.sli) this.sli.set(index);
		this.glideTo(index);
	},
	glideTo: function(index){
		this.index = index;
		this.aniFx.start(this.aniFx.get(), index*-this.foc);

		if(this.details) this.details.setStyle('height','');
		if(this.cap) this.cap.set('html', this.getCurrent().caption);
		if(this.desc) this.desc.set('html', this.getCurrent().description);


		if(this.details.getStyle('height').toInt()<97) this.details.setStyle('height','97px');

		/* new: */
		this.master.images[index].div.style.zIndex = this.master.images.length;
    this.master.images[index].con.style.left = '0';
    this.master.images[index].con.style.right = '0';

		for( i=index-1; i>=0; i-- )
    {
			this.master.images[i].div.style.zIndex = i;
      this.master.images[i].con.style.left = '13px';
      this.master.images[i].con.style.right = '0';
		}
    for( i=index+1; i<this.master.images.length; i++ )
		{
      this.master.images[i].div.style.zIndex = this.master.images.length-i;
      this.master.images[i].con.style.left = '0';
      this.master.images[i].con.style.right = '13px';
    };
  },
  
	process: function(x)
  {
		var z,W,H,zI=this.iL,foc=this.foc,f=this.factor,sz=this.sz,oW=this.oW,offY=this.offY,div,elh,elw;
		this.master.images.each(function(el){
			div = el.div.style;
			elw = el.width;
			elh = el.height;
			if(x>-foc*2 && x<foc*2)
      {
				with (Math)
        {
					z = sqrt(10000 + x * x) + 21;
					H = round((elh / elw * f) / z * sz);
					W = round(elw * H / elh);
					if(H >= elw * 0.5) W = round(f / z * sz);
					div.left = round(((x / z * sz) + sz) - (f * 0.5) / z * sz) + 'px';
					div.top = round(oW * 0.4 - H/2) + offY + 'px';
				}
				el.con.style.height = H*2 + 'px';
				div.width = W + 'px';
				div.display = 'block';
			}
      else
      {
				div.display = 'none';
			}
			x += foc;
		});
	}

});

Fx.Value = new Class({
	Extends: Fx,
	compute: function(from, to, delta){
		this.value = Fx.compute(from, to, delta);
		this.fireEvent('motion', this.value);
		return this.value;
	},
	get: function(){
		return this.value || 0;
	}
});

window.addEvent('domready', function(){
	$$('.MooFlowieze').each(function(mooflow){
		new MooFlow(mooflow);
	});
});