/*
Script: steadyBox.js
	License:
		Not open source.

	Author:
		Shane Thacker / SteadyMade.com
*/



var steadyBox = new Class({

	Implements: [Options],

	options: {
		duration: 300,
		transition: 'expo:out',
		yPos: 'm',
		xPos: 'm',
        overlay: true,
        tip: false,
        closeBtn: true,
        controller: '',
        spinnerParent: false,
        xOffset: 10,
        yOffset: 10 
	},

	initialize: function(link, options) {
		var self = this;
		this.setOptions(options);
		this.link = link;
		this.linkDims = this.link.getCoordinates();
		var uri = this.link.get('href').split('#')[1];
		this.ajax = (uri != undefined) ? false : true;
		if(uri != undefined) this.el = $(uri);
		if(!$('overlay') || !$('loader')) this.buildBox()
		else this.els();
		this.boxSetup();
	},

	buildBox: function() {
		var self = this;
		this.overlay = new Element('div', { 'id': 'overlay' }).inject(document.body, 'bottom');
		this.loader = new Element('div', { 'id': 'loader' }).inject(document.body, 'bottom');
		this.closeBtn = new Element('a', { 'id': 'close', 'html': '&nbsp;' }).setStyle('opacity', 0);
		this.bucket = new Element('div', { 'id': 'bucket' }).setStyle('opacity', 0);
		this.shadowbox = new Element('div', { 'id': 'shadowBox' });
		this.tip = new Element('span', { 'id': 'tip', 'html': '&nbsp;' }).inject(this.shadowbox, 'top');
		this.shadows = new Array('nw', 'n', 'ne', 'w', 'e', 'sw', 's', 'se');
		this.shadows.each(function(item, index) { s = new Element('div', {'class': item}); self.shadowbox.adopt(s); });
		$$(this.closeBtn, this.bucket, this.shadowbox).inject(this.loader, 'top');
	},

	els: function() {
		this.overlay = $('overlay');
		this.loader = $('loader');
		this.closeBtn = $('close')
		this.bucket = $('bucket');
		this.tip = $('tip');
	},

	boxSetup: function() {
		var self = this;

		if(this.options.spinnerParent){
			this.link.getParent().addClass('loading');
			this.loader.setStyles({ 'width': this.linkDims.width -26, 'height': this.linkDims.height -3, 'top': this.linkDims.top, 'left': this.linkDims.left + 13, 'z-index': 10000, 'opacity': 0 }).addClass('loading');
		} else {
			this.link.addClass('loading');
			this.loader.setStyles({ 'width': this.linkDims.width -26, 'height': this.linkDims.height -3, 'top': this.linkDims.top, 'left': this.linkDims.left + 13, 'z-index': 10000, 'opacity': .5 }).addClass('loading');
		}
        // this.loader.addClass('loading').setStyles({ 'width': this.linkDims.width -26, 'height': this.linkDims.height -3, 'top': this.linkDims.top, 'left': this.linkDims.left + 13, 'z-index': 10000, 'opacity': .5 });
        this.tip.setStyles({'bottom': '0', 'opacity': 0});

		this.tipOpacity = (this.options.tip) ? 1 : .01;
		this.overlayOpacity = (this.options.overlay) ? .5 : .01;
		this.closeOpacity = (this.options.closeBtn) ? 1 : .01;
		this.overlay.setStyles({ 'opacity': 0, 'width': '100%', 'height': window.getScrollSize().y });

		window.addEvents({ 'resize': self.resize.bind(self) });
		this.closeBtn.addEvents({ 'click': self.close.bind(self) });
		this.overlay.addEvents({ 'click': self.close.bind(self) });

		this.zoomFx = new Fx.Elements([this.closeBtn, this.loader, this.bucket, this.overlay, this.tip], { duration: this.options.duration, transition: this.options.transition });
		this.myFx = new Fx.Scroll(window, { duration: 500, transition: this.options.transition, wait: false });
		
		if(!this.ajax) {
			this.bucket.adopt(this.el);
			this.open();
			return;
		}
		this.load();
	},

	load: function(response) {
		var self = this;

		var str = self.link.get('href');
		if(str.search(/.png/i)!=-1||str.search(/.jpg/i)!=-1||str.search(/.jpeg/i)!=-1||str.search(/.gif/i)!=-1) {
			this.el = new Element('img', { 'class': 'bucket', 'src': str }).inject(self.bucket, 'top');
			this.el.onload = function(){ self.open(); }
		} else { 
		    var req = new Request({
		        onSuccess: self.success.bind(self),
                headers: {'X-Request': 'HTML'}
		    }).send({ method: 'get', url: self.link.get('href') }); }
	},

	success: function(responseTree, responseElements) {
		var self = this;

		this.bucket.set('html', responseTree);
		this.el = self.bucket.getFirst();
		// reqSuccess(response);
        if(this.options.controller != '') this.options.controller.setup();
		this.open();
	},

	positioning: function() {
		var self = this;

		this.elDims = this.bucket.getFirst().getCoordinates();
		// this.elDims = this.el.getCoordinates();
		this.linkDims = this.link.getCoordinates();
        
        // fit to screen
        // if(this.elDims.width > window.getSize().x || this.elDims.height > window.getSize().y) this.fit();

		switch(this.options.xPos) {
			case 'l': this.loader_x = (self.linkDims.left - self.elDims.width) - this.options.xOffset; break;
			case 'c': this.loader_x = (self.linkDims.left - (self.elDims.width/2)) + (self.linkDims.width/2); break;
			case 'r': this.loader_x = self.linkDims.right + this.options.xOffset; break;
			default: this.loader_x = ((window.getWidth() - this.elDims.width) / 2) + window.getScroll().x;
		}
		switch(this.options.yPos) {
			case 't': this.loader_y = self.linkDims.top - self.elDims.height - this.options.yOffset; break;
			case 'c': this.loader_y = (self.linkDims.top - (self.elDims.height/2)) + (self.linkDims.height/2); break;
			case 'b': this.loader_y = self.linkDims.bottom + this.options.yOffset; break;
			default: this.loader_y = ((window.getHeight() - self.elDims.height) / 2) + window.getScroll().y;
		}
        
        if(this.loader_y <= 30) this.loader_y = 30;
		return { x: this.loader_x, y: this.loader_y };
	},

	open: function() {
		var self = this;

        if(this.options.spinnerParent) this.link.getParent().removeClass('loading')
        else this.link.removeClass('loading');
		this.loader.removeClass('loading');
		this.zoomFx.start({ 
		    '1': { 'top': self.positioning().y, 'left': self.positioning().x, 'width': self.elDims.width, 'height': self.elDims.height, 'opacity': 1, 'visibility': 'visible' },
		    '3': { 'opacity': self.overlayOpacity },
		    '4': { 'bottom': -8, 'opacity': self.tipOpacity }
		}).chain(function(){
			this.start({ 
			    '0': { 'opacity': self.closeOpacity },
			    '2': { 'opacity': 1 }
			});
			self.slide();
		});
	},

	close: function(e) {
		if(e) e.stop();
		var self = this;
		this.zoomFx.start({ 
		    '0': { 'opacity': 0 },
		    '2': { 'opacity': 0 },
		    '4': { 'bottom': 0, 'opacity': 0 }
	     }).chain(function(){
			this.start({ 
			    '1': { 'top': self.linkDims.top + 3, 'left': self.linkDims.left + 13, 'width': self.linkDims.width - 26, 'height': self.linkDims.height - 6, 'z-index': 10000 },
			    '3': { 'opacity': 0 }
			});
		},
        function(){ this.start({ '1': { 'opacity': 0 } }) },
		function(){ self.reset() });
	},

	fit: function() {
		ratio = Math.min((window.getSize().x - 200) / this.elDims.width, (window.getSize().y - 200) / this.elDims.height);
		newWidth = ratio * this.elDims.width;
		newHeight = ratio * this.elDims.height;
		this.el.setStyles({ 'width': newWidth, 'height': newHeight });
		this.elDims.width = newWidth;
		this.elDims.height = newHeight;
	},

	slide: function() {
		var loaderDims = this.loader.getCoordinates();
		if(window.getScroll().y >= loaderDims.top) this.myFx.start(0, loaderDims.top - 30);
		if(loaderDims.bottom >= (window.getHeight() + window.getScroll().y)) this.myFx.start(0, loaderDims.top - 30);
	},

	resize: function() {
		this.overlay.setStyles({ 'height': window.getScrollSize().y });
		this.loader.setStyles({ 'top': this.positioning().y, 'left': this.positioning().x });
	},

    resizeBox: function(){
		var self = this;
		var test = this.bucket.getFirst().getCoordinates();

		this.zoomFx.start({
		    '1': { 'top': self.positioning().y, 'left': self.positioning().x, 'width': test.width, 'height': test.height }
		});
    },

	reset: function() {
        if(this.ajax == true) this.bucket.getChildren().destroy();
        else this.el.removeProperties('style', 'width', 'height').inject(document.body, 'bottom');
        this.loader.setStyles({ 'top': 0, 'left': 0, 'width': 1, 'height': 1 });
        this.overlay.removeEvents('click').setStyles({ 'width': 1, 'height': 1 });
        this.closeBtn.removeEvents('click').setStyle('opacity', 0);
        if(this.options.controller != '') this.options.controller.reset();
	}

});
