Hasbro.Overlay = new Class({
	options : {
		evtTriggerOn : 'mouseenter',
		evtTriggerOff : 'mouseleave',
		eftDuration : 250,
		eftFPS : 60,
		eftTransition : Fx.Transitions.Cubic.easeIn,
		hasDropShadow : false,
		hasFlashUnder : false, // work around Mac/FF/Flash opacity bug
		doEffect : false
	},
	initialize : function (id, options) {
		this.container = id;
		this.setOptions(options);
		this.triggers = this.container.getElements('a[class^=hsb_ol_trigger]');
		this.overlays = this.container.getElements('div[id^=hsb_ol_overlay]');
		this.overlayPairs = [];
		this.dropShadowContainers = [];
		this.dropShadow = Class.empty();
		var regEx = /^hsb_ol_(trigger|overlay)_(\w*)/;
		(window.gecko == true && navigator.platform.indexOf('Mac') > -1) ? this.isMacFF = true : this.isMacFF = false;

		if (this.isMacFF == true || window.ie6) this.options.hasDropShadow = false;  // make sure opaque drop shadow doesn't show for Mac FF
		
		if (this.options.evtTriggerOn == 'click' && this.options.evtTriggerOff == 'click') this.clkTrigger = true
		else this.clkTrigger = false;
		
		
		this.triggers.each (function(trigger) {
			var regExIDMatch = trigger.getProperty('class').match(regEx);
			var binder = regExIDMatch[2];
			
			this.overlays.each (function(overlay) {
				var overlayID = overlay.getProperty('id');
				if (overlayID.indexOf(binder) != -1) this.overlayPairs.push([trigger, overlay]);
			}.bind(this));
		}.bind(this));

		this.overlayPairs.each (function(overlayPair) {
			this.trigger = overlayPair[0];
			this.overlay = overlayPair[1];
			if (this.options.doEffect == true) this.overlay.setStyle('opacity', 0);  //initialize overlay opacity to 0 with JS rather than CSS so no CSS 2.0 validation errors
			
			this.olHeight = this.overlay.getStyle('height').toInt();
			this.olWidth = this.overlay.getSize().size.x;
			this.olZIdx = this.overlay.getStyle('z-index');
			this.olPosTop = this.overlay.getStyle('top').toInt();
			this.olPosLeft = this.overlay.getStyle('left').toInt();
			
			if (this.options.hasDropShadow) {
				this._buildDropShadow(this.olHeight, this.olWidth, this.olZIdx, '#000', this.olPosTop, this.olPosLeft);
				this.dropShadowContainer.injectAfter(this.overlay);
				
				this.dropShadowContainers = this.dropShadowContainers.include(this.dropShadowContainer);
			}
			
			if (window.ie6 && this.clkTrigger == false) {
				this._doIframeShim(this.olHeight, this.olWidth, this.olZIdx, this.olPosTop, this.olPosLeft);
				this.iframeShim.injectAfter(this.overlay);
			}
			
			if (this.clkTrigger == true) {
				new Hasbro.NullAnchor(this.container);
				this.trigger.addEvent(this.options.evtTriggerOn, this._doOverlayAppear.pass([this.overlay, this.dropShadowContainer], this));
				this.overlay.getElements('.hsb_ol_close').addEvent(this.options.evtTriggerOff, this._doOverlayHide.pass([this.overlay, this.dropShadowContainer], this));
			} else {
				this.trigger.addEvent(this.options.evtTriggerOn, this._doOverlayAppear.pass([this.overlay, this.dropShadowContainer, this.iframeShim], this));
				this.overlay.addEvent(this.options.evtTriggerOn, this._doOverlayAppear.pass([this.overlay, this.dropShadowContainer, this.iframeShim], this));
				this.trigger.addEvent(this.options.evtTriggerOff, this._doOverlayHide.pass([this.overlay, this.dropShadowContainer, this.iframeShim], this));
				this.overlay.addEvent(this.options.evtTriggerOff, this._doOverlayHide.pass([this.overlay, this.dropShadowContainer, this.iframeShim], this));
			}
		}.bind(this));
	},
	_doOverlayAppear : function (ol, ds, shim) {
		if (this.options.doEffect) {
			this._doEffect(ol);
			this.effect.start({'opacity' : 1});
			if ($defined(ds)) {
				this._doEffect(ds);
				this.effect.start({'opacity' : 0.4});
			}
			if ($defined(shim)) shim.setStyles({'visibility' : 'hidden', 'opacity' : 1});
		} else if (this.options.hasFlashUnder == true && this.isMacFF == true) {
			ol.setStyles({'visibility' : 'visible'});
		} else {
			ol.setStyles({'visibility' : 'visible', 'opacity' : 1});
			if ($defined(ds)) ds.setStyles({'visibility' : 'hidden', 'opacity' : 0.4});
			if ($defined(shim)) shim.setStyles({'visibility' : 'hidden', 'opacity' : 1});
		}
	},
	_doOverlayHide : function (ol, ds, shim) {
		if(this.options.doEffect) {
			this._doEffect(ol);
			this.effect.start({'opacity' : 0});
			if ($defined(ds)) {
				this._doEffect(ds);
				this.effect.start({'opacity' : 0});
			}
			if ($defined(shim)) shim.setStyles({'visibility' : 'hidden', 'opacity' : 0});
		} else if(this.options.hasFlashUnder == true && this.isMacFF == true) {
			ol.setStyles({'visibility' : 'hidden'});
		} else {
			ol.setStyles({'visibility' : 'hidden', 'opacity' : 0});
			if ($defined(ds)) ds.setStyles({'visibility' : 'hidden', 'opacity' : 0});
			if ($defined(shim)) shim.setStyles({'visibility' : 'hidden', 'opacity' : 0});
		}
		this.fireEvent('olClose');
	},
	_doEffect : function (el) {
		this.effect = el.effects({
			wait: false,
			duration: this.options.eftDuration,
			fps: this.options.eftFPS,
			transition: this.options.eftTransition
		});		
	},
	_buildDropShadow : function (h, w, zIdx, clr, t, lft) {
		(window.ie) ? zIdx += 1 : zIdx -= 1; // Fix for Drop Shadow appearing below Flash in IE   
		this.dropShadowContainer = new Element('div', {
			'styles' : {
				'position' : 'absolute',
				'opacity' : 0,
				'height' : h + 12,
				'width' : w,
				'z-index' : zIdx,
				'top' : t + 6,
				'left' : lft + 8
			},
			'properties' : {
				'class' : 'hsb_drop_shadow_container'
			}
		});
		this.dropShadow = new Element('div', {
			'styles' : {
				'height' : h,
				'width' : w,
				'background-color' : clr
			},
			'properties' : {
				'class' : 'hsb_drop_shadow'
			}
		});
		this.spacer = new Element('div', {
			'properties' : {
				'class' : 'hsb_spacer'
			}
		});
		this.dropShadow.injectInside(this.dropShadowContainer);
		this.spacer.injectAfter(this.dropShadow);
	},
	_doIframeShim : function(h, w, zIdx, t, lft) {
		this.iframeShim = new Element('iframe', {
			'styles' : {
				'height' : h + 1,
				'width' : w,
				'position' : 'absolute',
				'top' : t,
				'left' : lft,
				'background' : 'transparent',
				'z-index' : zIdx,
				'visibility' : 'hidden'
			},
			'properties' : {
				src : 'about:blank',
				scrolling : 'no',
				frameborder : 0
			} 
		});
		
	}
});
Hasbro.Overlay.implement(new Options);
Hasbro.Overlay.implement(new Events);