Element.implement({
	toggle: function() {
		if (this.getStyle('display') != 'none') this.setStyle('display','none');
		else this.setStyle('display','');
	},	
	lift: function() { this.toggle(); },
	toggleVis: function() {
		if (this.getStyle('visibility') != 'hidden') this.setStyle('visibility','hidden');
		else this.setStyle('visibility','visible');
	},	
	hide: function() {
		this.setStyle('display', 'none');
	},	
	show: function() {
		this.setStyle('display', '');
	},
	isShowing: function() {
		return this.getStyle('display') != 'none';
	},
	moveToBottom: function() {
		var w = this.clone(true, true);
		this.destroy();
		$(document.body).adopt(w);
		return w;
	},
	disable: function(txt)	{
		if( this.toString().indexOf('HTMLInput') > 0 ) {
			this.addClass('disabled');
			if(txt) this.value = txt;
			this.disabled = true;
			return;
		}
		
		$$('#' + this.id + ' select, #' + this.id + ' input').setProperty('disabled', true);
		
		if( $(this.id + '_disable') ) {
			$(this.id + '_disable').destroy();
		}
		
		this.setStyle('position', 'relative');
		if( !$(this.id + '_disable') ) {
			var coords = this.getSize();
			this.adopt(
				new Element('div', {
					'id': this.id + '_disable',
					'styles': {
						'background-color': !txt ? '#222' : '#' + txt,
						'width': coords.x,
						'height': coords.y,
						'top': '0',
						'left': '0',
						'position': 'absolute',
						'opacity': 0.8
					}
				})
			);
		}
	},
	
	enable: function(txt) {
		
		if( this.toString().indexOf('HTMLInput') > 0 ) {
			this.disabled = false;
			this.removeClass('disabled');
			if(txt) this.value = txt;
			return;
		}
		
		$$('#' + this.id + ' select, #' + this.id + ' input').setProperty('disabled', false);
		
		this.setStyle('position', '');
		if( $(this.id + '_disable') ) {
			$(this.id + '_disable').destroy();
		}
	},
	
	setWidth: function(num) {
		this.setStyle('width', num.toString() + 'px');
	},
	
	setHeight: function(num) {
		this.setStyle('height', num.toString() + 'px');
	},
	
	getWidth: function() {
		return this.isShowing() ? this.getSize().x : 0;
	},
	
	getHeight: function() {
		return this.isShowing() ? this.getSize().y : 0;
	},
	
	getX: function() {
		return this.getPosition().x;
	},
	
	setX: function(num) {
		this.setStyle('left', Math.round(num.toInt()) + 'px');
	},
	
	getY: function() {
		return this.getPosition().y;
	},
	
	setY: function(num) {
		this.setStyle('top', Math.round(num.toInt()) + 'px');
	},
	
	getBottomY: function() {
		return this.getHeight() + this.getPosition().y;
	}
});



/**
 * Dropdown class
 */
var Dropdown = new Class({
	options: {
     	delta_x: 0,
     	delta_y: 0,
     	onComplete: function(val) {}
    },

	initialize: function(element, dropdown, options) {
		this.setOptions(options);
		
		this.element  = $(element);
	    $(dropdown).moveToBottom();
	    this.dropdown = $(dropdown);
		
	    this.t = new Tooltip(element, dropdown, { position:'bl', onclick: true, delta_y: this.options.delta_y, delta_x: this.options.delta_x });
	    this.cur_item = '';
	    
	    this.items = this.dropdown.getFirst().getChildren();
	    
	    this.mouseClick   = this.itemTrigger.bind(this);
	    this.hideClick    = this.hideDropdown.bind(this);
	    
	    this.registerEvents();
	},
	
	registerEvents: function() {
		this.items.each( function(item) {
			if( item.className == 'hilite' ) this.cur_item = item.id;
	    	item.addEvent("mouseup", this.mouseClick);
	    }, this);
	},
	
	manualSelectItem: function(id) {
		this.selectItem(id);
		this.element.innerHTML = $(id).innerHTML;
	},
	
	selectItem: function(id) {
		this.items.each( function(item) {
			if( item.id == id ) {
				item.addClass('selected');
				this.cur_item  = id;
			} else {
				item.removeClass('selected');
			}
	    }, this);
	},
	
	itemTrigger: function(event) {	
		var e = new Event(event);
		var item = e.target;
		
		if( e.target.tagName == 'SPAN' ) {
			item = e.target.getParent();
		}
		e.stop();
		
		if( item.id == this.cur_item ) return false;
		
		this.selectItem(item.id);
		this.element.innerHTML = item.innerHTML;
		this.hideDropdown();
		this.options.onComplete(item.id);
	},
	
	hideDropdown: function() {
		this.t.wait = false;
		this.t.tooltipOff.delay(100, this.t);
	}
});
Dropdown.implement(new Options);

/**
 * Tooltip Class
 */ 
var Tooltip = new Class({
	
	options: {
	  no_roll: false,
      default_css: false,
      position: false,  // tr, tl, br, bl
      delay: 0,			// delay before displaying
      onclick: false,   // have tooltip open onclick
      onfocus: false, 	// shows tooltip when onfocus
      mouseover: false, // can hover over tooltip, must be fixed in order for this to work
      width: 200,
      margin: "0px",
	  padding: "5px",
	  backgroundColor: "#cccccc",
	  min_distance_x: 5,
      min_distance_y: 5,
      delta_x: 0,
      delta_y: 0,
      zindex: 100000
    },

  	initialize: function(element, tool_tip, options) 
	{  	
	this.setOptions(options);

	//element = the thing you rollover
	//tool_tip = tooltip div itself
	//new Tooltip('e','e2', { position:'tr', delta_y:100, mouseover:true })

    if( tool_tip ) {
    	this.element = $(element);
    	this.no_listeners = false;
    } else {
    	this.no_listeners = true;
    }
    
	this.timer_on	  = false;
	this.timer_off	  = false;
    this.wait		  = false;
    
	if(!this.options.hide_delay) this.options.hide_delay = this.options.delay;

    if($(tool_tip)) {
    	this.tool_tip = $(tool_tip);
    } else {
 		this.tool_tip = $(element);
    }

    // hide the tool-tip by default
    this.tool_tip.style.display = 'none';

    if( tool_tip && !this.options.no_roll ) { // no element to listen to
	    if( !this.options.onclick && !this.options.onfocus ) {
		    this.eventMouseOver  = this.showTooltip.bind(this);
		    this.eventMouseOut   = this.hideTooltip.bind(this);
		    this.eventMouseMove  = this.moveTooltip.bind(this);
	    } 
	    else if( this.options.onfocus ) {
	    	//this.eventFocus  = this.showTooltip.bind(this);
		    //this.eventBlur   = this.hideTooltip.bind(this);
	    }
	    else {
	    	this.eventMouseDown  = this.toggleTooltip.bind(this);
	    	this.eventTurnOff    = this.tooltipOff.bind(this);
	    	this.eventWait       = this.tooltipWait.bind(this);
	    }
	    this.registerEvents();
    }
    
    window.addEvent("resize", this.moveTooltip.bind(this));
  },

  destroy: function() {
  	if( !this.options.onclick && !this.options.onfocus ) {
	    this.element.removeEvent("mouseover", this.eventMouseOver);
	    this.element.removeEvent("mouseout", this.eventMouseOut);
	    this.element.removeEvent("mousemove", this.eventMouseMove);
	    
	    if( this.options.mouseover ) {
			this.tool_tip.removeEvent("mouseover", this.eventMouseOver);
			this.tool_tip.removeEvent("mouseout", this.eventMouseOut);
	    }
  	}
  	else if( this.options.onfocus ) {
  		//this.element.removeEvent("focus", this.eventFocus);
	   // this.element.removeEvent("blur",  this.eventBlur);
  	}
  	else {
  		this.element.removeEvent("mousedown", this.eventMouseDown);
  		this.element.removeEvent("blur", this.eventTurnOff);
  		this.element.removeEvent("mouseup", this.eventWait);
  		$(document.body).removeEvent("click", this.eventTurnOff);
  	}
  },

  registerEvents: function() {
  	if( !this.options.onclick && !this.options.onfocus ) { // use mouse overs
	    this.element.addEvent("mouseover", this.eventMouseOver);
	    this.element.addEvent("mouseout", this.eventMouseOut);
	    this.element.addEvent("mousemove", this.eventMouseMove);
	    
	    if( this.options.mouseover ) {
	    	this.tool_tip.addEvent("mouseover", this.eventMouseOver)
	    	this.tool_tip.addEvent("mouseout", this.eventMouseOut)
	    }
  	} 
	else if( this.options.onfocus ) {
		//this.element.addEvent("focus", this.eventFocus);
	    //this.element.addEvent("blur",  this.eventBlur);
	} 
  	else { // use clicking
  		this.element.addEvent("mousedown", this.eventMouseDown);
  		this.element.addEvent("mouseup", this.eventWait);
  		$(document.body).addEvent("click", this.eventTurnOff);
  	}
  },
  
  tooltipWait: function(event) {
  	this.wait = true;
  },

  moveTooltip: function(event){	
	if( !this.options.position && event ) { // If not fixed
		var e = new Event(event);

		var mouse_x = e.client.x;
		var mouse_y = e.client.y;

		pos_y = (e.page.y - mouse_y) + mouse_y;
		pos_x = (e.page.x - mouse_x) + mouse_x;

//		var dimensions = this.tool_tip.getSize();
		var element_width = this.tool_tip.getWidth();
		var element_height = this.tool_tip.getHeight();
				
		if (mouse_y - element_height < this.options.min_distance_y) // hitting top
			pos_y = pos_y + this.options.min_distance_y;
		else 
			pos_y = pos_y - element_height - this.options.min_distance_y;
		
		
		if ((mouse_x + element_width + this.options.min_distance_x) >= (window.getWidth())) // hitting right
			pos_x = pos_x - element_width - this.options.min_distance_x;
		else
			pos_x = pos_x + this.options.min_distance_x;
		
	} 
	else // Fixed tooltip
	{ 
		var coords  = this.element.getPosition();
		var size    = this.element.getSize();
		
		switch (this.options.position) {
			case 'tr':
				pos_x = coords.x + size.x;
				pos_y = coords.y;
				break;
			
			case 'tl':
				pos_x = coords.x;
				pos_y = coords.y;
				break;
			
			case 'br':
				pos_x = coords.x + size.x;
				pos_y = coords.y + size.y;
				break;
			
			case 'bl':
				pos_x = coords.x;
				pos_y = coords.y + size.y;
				break;
		}
	}
	this.setStyles(pos_x, pos_y);
  },
	
  toggleTooltip: function(event) {
  	if(event) new Event(event).stop();
    this.moveTooltip(event);
    this.tooltipToggle();
  },
  
  showTooltip: function(event) {  	
    var e = new Event(event).stop();

    if( this.no_listeners ) {
  		this.tool_tip.innerHTML = e.target.title;
  	}
    
    this.moveTooltip(event);
    this.timer_on = this.tooltipOn.delay(this.options.delay,this);
    $clear(this.timer_off);
  },
  
  hideTooltip: function(event){
	this.timer_off = this.tooltipOff.delay(this.options.hide_delay,this);
  	$clear(this.timer_on);
  },
  
  tooltipToggle: function() {
  	if( this.tool_tip.style.display == 'none' ) 
  		this.tool_tip.style.display = '';
  	else 
  		this.tool_tip.style.display = 'none';
  },
  
  tooltipOn: function() {
  	this.tool_tip.style.display = '';
  },
  
  tooltipOff: function() {
  	if( !this.wait )
  		this.tool_tip.style.display = 'none';
  		
  	this.wait = false;
  },
  
  setStyles: function(x, y){
  	if( this.no_listeners ) { 
  		var real_width = this.tool_tip.getSize().x;
  		
  		if( real_width > this.options.width )
  			this.tool_tip.className = 'tooltip max-width';
  		else
  			this.tool_tip.className = 'tooltip';
  	}

    // set the right styles to position the tool tip
	 this.tool_tip.setStyle('position', 'absolute');
	 this.tool_tip.setStyle('top', (y + this.options.delta_y) + "px");
	 this.tool_tip.setStyle('left', (x + this.options.delta_x) + "px");
	 this.tool_tip.setStyle('z-index', this.options.zindex);
	
	  // apply default theme if wanted
	  if (this.options.default_css){
	  	this.tool_tip.setStyle('margin',this.options.margin);
	  	this.tool_tip.setStyle('padding',this.options.padding);
	  	this.tool_tip.setStyle('backgroundColor',this.options.backgroundColor);
	  	this.tool_tip.setStyle('z-index',this.options.zindex);
	  }	
  }
});
Tooltip.implement(new Options);
