/*
Minibox.js - A hoverbox that's as simple as it gets. No insane CSS, no HTML
             gymnastics to get some janky system to fire events properly, no
             weird JavaScript just to specify a freaking size. Give it an
             element to contain and it'll contain it without stripping events,
             IDs, etc. Close button optional.
             
             By: Tyson Tate
             Copyright: 2010 Dolores Labs, San Francisco, CA
*/

var Minibox = new Class({

  Implements: [Options, Events],
  
	options: {
		/*
		onLoad: $empty,
		onOpenFinish: $empty,
		onCloseFinish: $empty,
		*/
	  closeButton: null,
	  effectDuration: 300,
	  height: 500,
	  width: 400,
	  overlayOpacity: 0.5,
	  overlayColor: '#aaa'
	},

	initialize: function(content, options) {
		this.element = this.subject = $(content).store('minibox', this);
		this.setOptions(options);
		
		this.overlay = new Element('div', {
		  'class':'minibox_overlay',
		  'styles': {
        'position': 'fixed',
        'z-index': 9998,
        'top': 0,
        'left': 0,
        'width': '100%',
        'height': '100%',
        'background-color': this.options.overlayColor,
        'cursor': 'pointer'
		  }
		}).addEvent('click', this.close.bind(this)).inject(document.body);
		
		this.container = new Element('div', {
		  'class': 'minibox_container',
		  'styles': {
        'position': 'absolute',
        'padding': '10px 0',
		    'height': this.options.height - 20,
		    'width': this.options.width,
		    'overflow': 'auto',
		    'background-color': 'white',
        'z-index': 9999,
        '-moz-border-radius': '10px',
        '-webkit-border-radius': '10px',
        '-moz-box-shadow': '0px 10px 40px rgba(0,0,0,0.70)',
        '-webkit-box-shadow': '0px 10px 40px rgba(0,0,0,0.70)'
		  }
		}).inject(document.body);
		
		if (this.options.closeButton)
		  this.options.closeButton.addEvent('click', this.closeButtonClick.bind(this));
		
		this.effects = {
		  'overlay': new Fx.Tween(this.overlay, {
		    'property': 'opacity',
		    'duration': this.options.effectDuration
		  }).set(0),
		  'container': new Fx.Tween(this.container, {
		    'property': 'opacity',
		    'duration': this.options.effectDuration
		  }).set(0)
		};
		
		this.container.adopt(this.element.setStyle('display', 'inline-block'));
		
		window.addEvent('resize', this.updatePosition.bind(this));
		window.addEvent('scroll', this.updatePosition.bind(this));
		
		this.fireEvent('load', this);
	},
	
	open: function() {
	  this.display(this.options.effectDuration);
	},
	show: function() {
	  this.display(0);
	},
	
	display: function(duration) {
	  this.setDisplayProperty('block');
		this.updatePosition();
	  this.effects.overlay.start(this.options.overlayOpacity);
	  setTimeout(this.finishDisplay.bind(this), this.options.duration);
	},
	finishDisplay: function() {
	  this.effects.container.start(1);
	  this.fireEvent('openFinish', this);
	},
	
	closeButtonClick: function(e) {
	  this.close();
	  return false;
	},
	close: function() {
	  this.undisplay(this.options.effectDuration);
	},
	hide: function() {
	  this.undisplay(0);
	},
	
	undisplay: function(duration) {
	  this.effects.container.start(0);
	  setTimeout(this.finishUndisplay.pass(duration, this), duration);
	},
	finishUndisplay: function() {
	  this.effects.overlay.start(0);
	  
	  // TODO: (typeof finishUndisplay == 'hacky hack') == true
	  setTimeout(function(){
	    this.setDisplayProperty('none');
	    this.fireEvent('closeFinish', this);
	  }.bind(this), arguments[0]);
	},
	
	setDisplayProperty: function(display) {
	  this.overlay.setStyle('display', display);
	  this.container.setStyle('display', display);
	},
	
	updatePosition: function() {
	  var containerSize = this.container.getSize();
	  var windowSize = window.getSize();
	  var windowScroll = window.getScroll();
	  
	  this.container.setStyles({
	    'top': windowScroll.y + (windowSize.y - containerSize.y)/2,
	    'left': windowScroll.x + (windowSize.x - containerSize.x)/2
	  });
	}
});