/*
    Booble.js
    by Christian Opitz
    Netzelf.de
    technik@netzelf.de
*/
 
 
var boobleClass = new Class({
	Implements: Options,  
	options: {
		classContainer: 'boobleContainer',
		classHead: 'boobleHead',
		classContent: 'boobleContent',
		classFoot: 'boobleFoot',
		classFlipX: 'boobleFlipX',
		classFlipY: 'boobleFlipY',
		classFlipXY: 'boobleFlipXY',
		selector: 'a.boobleLink',
		offset: { x: 10, y: 10 },
		removeDelay: 2500,
		src:null,
		title:null,
		width:'200px'
	},
	targets: new Array(),
	boobles: new Array(),
	initialize: function(options) {
		this.setOptions(options);
		this.active = -1;
		this.collision = false;
		this.focused = false;
	   	$$(this.options.selector).each(function(boobleLink, i){
	   		var rel = boobleLink.getAttribute('rel');
	   		if ($chk(rel)) {
	   			this.targets.push(rel);
				boobleLink.addEvent("mouseenter", this.attachBooble.bindWithEvent(this,i));
				boobleLink.addEvent("mouseleave", this.prepareDetach.bind(this));
			}
		}.bind(this));
	},
	attachBooble: function(event, i) {

		var e = new Event(event);
		
		if (this.active == i) return false;
		
    	if (this.active > -1) this.detachBooble(true);
    	
    	if ($chk(this.boobles[i]))
    		this.boobles[i].setStyle('display','block');
    	else {
    		this.setOptions(JSON.decode(this.targets[i]));
			this.createBooble(i,e);
		}
		this.active = i;
		this.corrigPosition(i,e);
	},
	createBooble: function(i,e) {
		this.boobles[i] = new Element('div', {
	      'class': this.options.classContainer,
	      styles:{
	        'z-index': '99999',
	        position: 'absolute',
	        top: (e.page.y+this.options.offset.y) + 'px',
	        left: (e.page.x+this.options.offset.x) + 'px',
	        width: this.options.width
	      }, events: {
	        mouseenter: function() { this.collision = true; }.bind(this),
	        mouseleave: function() { this.collision = false; }.bind(this)
	      }
	    });
	    new Element('div', { 'class': this.options.classHead }).set('html',this.options.title).inject(this.boobles[i]);
	    new Element('div', { 'class': this.options.classContent }).set('html',$$(this.options.src)[0].get('html')).inject(this.boobles[i]);
	    new Element('div', { 'class': this.options.classFoot }).inject(this.boobles[i]);
	    this.boobles[i].inject(document.body);
	    
	    this.boobles[i].getElements('input, textarea').each(function(item){
	    	item.addEvents({
		       focus: function() { this.focused = true; }.bind(this),
		       blur: function() { this.focused = false; }.bind(this)
		    });
	    }.bind(this));
	},
	corrigPosition: function(i,e) {
		this.boobles[i].setStyles({top: (e.page.y+this.options.offset.y) + 'px', left: (e.page.x+this.options.offset.x) + 'px' });
		
		var pos = {
			ws: window.getSize(),
			bs: this.boobles[i].getSize(),
			mp: e.client,
			os: this.options.offset,
			flip: false
	    }
	
	    if ((pos.ws.y - pos.mp.y - pos.os.y - pos.bs.y) < 0) {
			this.boobles[i].setStyle('top',(e.page.y - pos.bs.y - pos.os.y) + 'px');
			this.boobles[i].addClass(this.options.classFlipY);
			pos.flip = true;
	    }
	    if ((pos.ws.x - pos.mp.x - pos.os.x - pos.bs.x) < 0) {
			this.boobles[i].setStyle('left',(e.page.x - pos.bs.x - pos.os.x) + 'px');
			if (pos.flip) {
				this.boobles[i].removeClass(this.options.classFlipY);
				this.boobles[i].addClass(this.options.classFlipXY);
			}else
				this.boobles[i].addClass(this.options.classFlipX);
	    }
	},
	prepareDetach: function() {
    	this.detachBooble.delay(this.options.removeDelay,this);
  	},
	detachBooble: function() {
		if ((!this.collision && !this.focused) || arguments[0] == true) {
	      	this.boobles.each(function(item){item.setStyle('display','none')});
	  		this.active = -1;
	  		this.collision = false;
	  		this.focused = false;
		}else
			this.prepareDetach();
	}
});
window.addEvent('domready', function() {
  var c = new boobleClass();
});