/**
 * @author jim
 */

/*
 * PopupTrigger - Generic trigger object for popups
 * 
 *  HTML: 
 *  	<div id="triggerDiv">dfsd sdfsdfs fsf </div>
 * 
 *  JS:
 * 		thisTrigger = new PopupTrigger('triggerDiv');
 * 
 *      or, if you want it to be "held on" by whatever it pops up (classes are just like in setHoverClass )
 *
 * 		thisTrigger = new PopupTrigger('triggerDiv', onClass, offClass); 
 *
 *
 *      thisTrigger.addPopup(popupElem);  add something with show() and hide() methods
 *      
 *      or
 *      
 *      pu = new Popup('popUpId', thisTrigger);
 * 
 */
var PopupTrigger = new Class({
	
    initialize: function(elementId, offClass, hoverClass)
	{
		
		this.element = $(elementId);		
			
		this.popups = [];
	
                this.hoverClass = hoverClass;
                this.offClass = offClass;

                if (this.hoverClass)
                    this.element.removeClass(this.hoverClass);

                if (this.offClass)
                    this.element.addClass(this.offClass);

 		this.boundHoverOnFn  = this.hoverOn.bindWithEvent(this);
 		this.boundHoverOffFn = this.hoverOff.bindWithEvent(this);
				
		this.element.addEvents({
			mouseenter: this.boundHoverOnFn,
			mouseleave: this.boundHoverOffFn
		});				
			
        },
  
	hoverOn: function()
	{
		this.popups.forEach(function(p)
		{
   			p.show();
		});	
					
	},

	hoverOff: function()
	{
		this.popups.forEach(function(p)
		{
			p.hide();
		});	
	},
	
	showOn: function()
	{
            if (this.offClass)
                this.element.removeClass(this.offClass);

	    if (this.hoverClass)
                this.element.addClass(this.hoverClass);
	},
	
	showOff: function()
	{
	    if (this.hoverClass)
                this.element.removeClass(this.hoverClass);

            if (this.offClass)
                this.element.addClass(this.offClass);
			
	},	
	
    addPopup: function(popupElem)
	{	
		this.popups.push(popupElem);		
	}

});

/*
 *  HoverImg class
 * 
 *  HTML: 
 *  	<img id="hovertest" src="images2/hovertest_1.gif" />
 * 
 *  JS:
 * 		hoverThing = new HoverImg('hovertest', 'images2/hovertest_2.gif' );
 *  
 *  	hoverThing.lockOn();
 *  	hoverThing.lockOff();
 *  	hoverThing.unlock();  
 *  
 *      hoverThing.addSlave(slaveImg, slaveSrcUrl);    Sets hoverthing as trigger for the slaveImg
 *      
 *      hoverThing.addPopup(popupElem);  add something with show() and hide() methods
 */

var HoverImg = new Class({
	
    initialize: function(elementId, hoverImg)
	{
		
		this.element = $(elementId);
		this.defaultImgSrc = this.element.getProperty('src');
		this.hoverImgSrc = hoverImg;
		this.bLocked = false;
		this.bHovered = false;
		this.onCount = 0;			
	
		this.slaves = [];
			
		this.popups = [];
	
 		this.boundHoverOnFn  = this.hoverOn.bindWithEvent(this);
 		this.boundHoverOffFn = this.hoverOff.bindWithEvent(this);
				
		this.element.addEvents({
			mouseenter: this.boundHoverOnFn,
			mouseleave: this.boundHoverOffFn
		});				
			
    },
	
	showOn: function()
	{
		if (!this.bLocked)
		{
			this.onCount++;			
			this.element.setProperty('src', this.hoverImgSrc);				
		}	
				
	},
	
	showOff: function()
	{
		if (!this.bLocked)
		{
			this.onCount--;
			if (this.onCount <=0)
			{
				this.onCount = 0;			
				this.element.setProperty('src', this.defaultImgSrc);
			}			
		}		
	},	
	
	hoverOn: function()
	{
		this.showOn();
		
		this.slaves.forEach(function(slavePair)
		{
   			slavePair[0].setSrc(slavePair[1]);
		});
				
		this.popups.forEach(function(p)
		{
   			p.show();
		});	
					
		this.bHovered = true;
	},

	hoverOff: function()
	{
		this.showOff();

		this.slaves.forEach(function(slavePair)
		{
			slavePair[0].reset();	
		});
			
		this.popups.forEach(function(p)
		{
			p.hide();
		});	

				
		this.isHovered = false;
	},
	
	lockOn: function()
	{
		this.element.setProperty('src', this.hoverImgSrc);
		this.bLocked = true;	
	},
	
	lockOff: function()
	{
		this.element.setProperty('src', this.defaultImgSrc);
		this.bLocked = true;	
	},	
	
	unlock: function()
	{
		this.bLocked = false;
		
		if (this.bHovered)	
			this.element.setProperty('src', this.hoverImgSrc);
		else	
			this.element.setProperty('src', this.defaultImgSrc);				
	},

    addSlave: function(slaveElement, slaveUrl)
	{
		var slavePair = [];
		slavePair[0] = slaveElement;
		slavePair[1] = slaveUrl;
		
		this.slaves.push(slavePair);		
	},

    addPopup: function(popupElem)
	{	
		this.popups.push(popupElem);		
	}

});


/*
 *  SlaveImg class - an image that has other elements change its src, but remembers its default
 * 
 *  HTML: 
 *  	<img id="slavetest" src="images2/slavetest_1.gif" />
 * 
 *  JS:
 * 		slaveThing = new SlaveImg('hovertest');
 *  
 *  	slaveThing.setSrc('imageUrl');
 *   	slaveThing.reset(); // puts it back
 */

var SlaveImg = new Class({
	
    initialize: function(elementId)
	{
		
		this.element = $(elementId);
		this.defaultImgSrc = this.element.getProperty('src');	
						
    },
	
	setSrc: function(srcUrl)
	{
		this.element.setProperty('src', srcUrl);	
	},

	reset: function()
	{
		this.element.setProperty('src', this.defaultImgSrc);
	}

});

/*
 *  Popup class - a div (or other element) that is normall invisible, and that
 *  some other thing (a hoverImg, really) causes to become visible.
 * 
 *  HTML: 
 *  	<div id="popupDiv" >Stuff in here </div>
 * 
 *  JS:
 * 		popupThing = new Popup('popupDiv', triggerHoverImg);
 *  
 *  	popupThing.show(); // turns it on
 *      popupThing.hide(); // turns it off
 *      
 *      popupThing.addSlave(slaveImg, slaveSrcUrl);    Sets hoverthing as trigger for the slaveImg    
 *      
 * 
 */
var Popup = new Class({
	
    initialize: function(elementId, trigger)
	{
		this.slaves = [];		
		this.trigger = trigger;
		this.element = $(elementId);
		this.showCount = 0;
		this.element.setStyle('visibility', 'hidden');	
		this.bLocked = false;
		this.element.setStyle('z-index', 6); // default popup index
		
		this.boundHoverOnFn  = this.hoverOn.bindWithEvent(this);
 		this.boundHoverOffFn = this.hoverOff.bindWithEvent(this);
				
		this.element.addEvents({
			mouseenter: this.boundHoverOnFn,
			mouseleave: this.boundHoverOffFn
		});	
		
		trigger.addPopup(this);
		

    },

	hoverOn: function()
	{
		if (!this.bLocked)
		{		
			this.show();				
			this.trigger.showOn();		
		
			this.slaves.forEach(function(slavePair)
			{
   				slavePair[0].setSrc(slavePair[1]);
			});
						
		}

		this.bHovered = true;		
	},

	hoverOff: function()
	{
		if (!this.bLocked)
		{		
			this.hide();
		
			this.trigger.showOff()
		
			this.slaves.forEach(function(slavePair)
			{
   				slavePair[0].reset();	
			});
		}	

		this.bHovered = false;		
	},    

	lockOn: function()
	{
		this.element.setStyle('z-index', 3);		
		this.show();		
		this.bLocked = true;			
	},
	
	lockOff: function()
	{
		this.hide();	
		this.bLocked = true;			
	},	
	
	unlock: function()
	{
		this.bLocked = false;
		
		this.element.setStyle('z-index', 6);		
		
		if (this.bHovered)	
		{
			this.show();				
		}
		else
		{	
			this.hide()
		}		
	},

	show: function()
	{
		if (!this.bLocked)
		{
			this.showCount++;
			this.element.setStyle('visibility', 'visible');
		}
	},
	
	hide: function()
	{
		if (!this.bLocked)
		{
			this.showCount--;
			if (this.showCount <=0)
			{
				this.showCount = 0;
				this.element.setStyle('visibility', 'hidden');			
			}
		}
	},
	
    addSlave: function(slaveElement, slaveUrl)
	{
		var slavePair = [];
		slavePair[0] = slaveElement;
		slavePair[1] = slaveUrl;
		
		this.slaves.push(slavePair);		
	}

});
/*
 *  Menu class
 *  
 */

/*
 * Not a class or anything, but all I need for now...
 */

function setHoverClasses(selector, offClass, onClass)
{
	$$(selector).removeClass(onClass);
	$$(selector).addClass(offClass);	
	
	$$(selector).addEvents( {
		mouseenter: function (e) {
			this.removeClass(offClass);					
			this.addClass(onClass);		
		},
		mouseleave: function (e) {
			this.removeClass(onClass);					
			this.addClass(offClass);	
		}
	});		
}

// In case you want to cause a previously hovered thing to be locked at a given state
// Sorta assumes that there might be a class already applied which you have to get rid of
function lockHoverClasses(selector, classToLock, classToRemove)
{
	$$(selector).removeEvents('mouseenter');
	$$(selector).removeEvents('mouseleave');	
	
	$$(selector).removeClass(classToRemove);
	$$(selector).addClass(classToLock);		
}

 
/*
 * A class to handle menu-like attribure transistions on mouse entry and exit
 * 
 */
 
var BftMenu = new Class({
	
    initialize: function(contentElemSelector, onAttr, offAttr, timeMs){
		
        elems = $$(contentElemSelector);
		
		time = timeMs / 10;
		
		elems.each(function(element) {
 
 			element.setStyles(offAttr);
 
			var fx = new Fx.Styles(element, {duration: time, wait: false, transition:Fx.Transitions.Quad.easeInOut});
 
			element.addEvent('mouseenter', function(){
				fx.start(onAttr);
			});
 
			element.addEvent('mouseleave', function(){
				fx.start(offAttr);
			});
 
		});
	
	}
	
});


// this is included so I can open new windows class=opennew
function allowNewWindow()
{
    $$('a.opennew').setProperties({ target: '_blank' });
}
