var shadowbox = new Class({
	initialize: function(options){
		this.options= $extend(
			{
				fxduration:	800,	// number of milliseconds for transition
				maxWidth: 1024,
				maxHeight: 768,
				hideBackground: true,
				className:	"shadowbox",
				baseClass:	"sbOuter",
				constantContainerSize: false,
				constantImageSize: false,
				constantCaptionWidth: false	// set to true if you want the caption to be the same width as image (only effective with constantContainerSize)
			}, options || {}
		);
		//this.options.baseClass = '"'+this.options.baseClass+'"';
	//	this.links = document.body.getElements('a');
		this.links = $(document.body);
		this.links.each(function(a,i){
			if(a.hasClass(this.options.className)){
				a.href=a.get('href');
				a.addEvents({
					'click': function(){
						this.clickLink(i);
						return false;
					}.bind(this)
				});
			}
		},this);
	},
	
	getElementsList: function(){
		return $$("div."+this.options.baseClass,"div."+this.options.baseClass+' div',"div."+this.options.baseClass+' img',"div."+this.options.baseClass+' p',"div."+this.options.baseClass+' iframe');
	},
	
	createDivs: function(){
		if(!this.overlay){
			this.overlay = new Mask();
			this.overlay.addEvent('click',function(){this.close();}.bind(this));
			this.shadowbox = new Element('div',{'class':this.options.baseClass}).inject(document.body,'bottom');
			this.shadowbox.contents = new Element('div',{'class':'sbContent sbHeight sbWidth'}).inject(this.shadowbox);
			this.shadowbox.ctl = new Element('div',{'class':'sbCorners sbTL'}).inject(this.shadowbox);
			this.shadowbox.ctr = new Element('div',{'class':'sbCorners sbTR'}).inject(this.shadowbox);
			this.shadowbox.ctr.addEvents({
				'mouseover': function(){
					this.addClass('sbTROver');
				},
				'mouseout': function(){
					this.removeClass('sbTROver');
				},
				'click': function(){
					this.close();
				}.bind(this)
			},this);
			this.shadowbox.cbl = new Element('div',{'class':'sbCorners sbBL'}).inject(this.shadowbox);
			this.shadowbox.cbr = new Element('div',{'class':'sbCorners sbBR'}).inject(this.shadowbox);
			this.shadowbox.st = new Element('div',{'class':'sbVert sbT sbWidth'}).inject(this.shadowbox);
			this.shadowbox.sb = new Element('div',{'class':'sbVert sbB sbWidth'}).inject(this.shadowbox);
			this.shadowbox.sl = new Element('div',{'class':'sbHorz sbL sbHeight'}).inject(this.shadowbox);
			this.shadowbox.sr = new Element('div',{'class':'sbHorz sbR sbHeight'}).inject(this.shadowbox);
			this.shadowbox.imagebox = new Element('div',{'class':'sbContent sbHeight sbWidth'}).inject(this.shadowbox);
			this.shadowbox.imagebox.image = new Element('img').inject(this.shadowbox.imagebox);
			this.shadowbox.imagebox.caption = new Element('p').inject(this.shadowbox.imagebox);
			this.shadowbox.framebox = new Element('div',{'class':'sbContent sbHeight sbWidth'}).inject(this.shadowbox);
			this.shadowbox.framebox.frame = new IFrame({'scrolling':'auto','frameborder':'0','class':'sbContent sbHeight sbWidth'}).inject(this.shadowbox.framebox);
			this.shadowbox.framebox.caption = new Element('p').inject(this.shadowbox.framebox);
			this.shadowbox.spinner = new Spinner(this.shadowbox,{inject:{target:this.shadowbox.contents}});
			this.shadowbox.effect = new Fx.Elements(this.getElementsList(), {duration: this.options.fxduration, transition: Fx.Transitions.Sine.easeOut, link: 'chain'});
		}
	},
	
	resetStyles: function(){
		this.clearStyles();
		if(this.options.hideBackground) this.overlay.show();
		this.calcDims(this.shadowbox.getStyle('width'),this.shadowbox.getStyle('height'));
		c = this.centerBox(this.shadowbox.getStyle('width'),this.shadowbox.getStyle('height'));
		this.shadowbox.setStyles({'display':'block','left':c.boxX,'top':c.boxY,opacity: '0'});
		this.shadowbox.contents.setStyles({'display':'block',opacity: '0'});
		this.shadowbox.effect.start({
			'0': {'opacity': [0,1]},
			'1': {'opacity': [0,1]}
		});
		this.shadowbox.spinner.show();
	},
	
	setDimensions: function(){
		this.shadowbox.effect.start({
			'0':{'height':this.dims.boxH,'width':this.dims.boxW,'left':this.dims.boxX,'top':this.dims.boxY},
			'1':{'height':this.dims.conH,'width':this.dims.conW},
			'2':{'height':this.dims.conH,'width':this.dims.conW},
			'9':{'width':this.dims.conW},
			'10':{'width':this.dims.conW},
			'11':{'height':this.dims.conH},
			'12':{'height':this.dims.conH}
		});
	},
	
	calcDims: function(width,height){
		width = width.toInt();
		height = height.toInt();
		if((width>this.options.maxWidth)||(height>this.options.maxHeight)){
			scale = (height/this.options.maxHeight)>(width/this.options.maxWidth) ? height/this.options.maxHeight : width/this.options.maxWidth;
			width = (width/scale).toInt();
			height = (height/scale).toInt();
		}else if((this.options.constantImageSize)&&((height<this.options.maxHeight)&&(width<this.options.maxWidth))){
			scale = ((this.options.maxWidth/width)<(this.options.maxHeight/height)) ? this.options.maxWidth/width : this.options.maxHeight/height ;
			width = (width*scale).toInt();
			height = (height*scale).toInt();
		}
		boxW = (this.options.constantContainerSize) ? this.options.maxWidth : width;
		boxH = (this.options.constantContainerSize) ? this.options.maxHeight : height;
		// other heights are passed as integers
		if(arguments.length>2){
			for(i=2;i<arguments.length;i++){
				boxH+=arguments[i];
			}
		}
		conW = boxW; // need to set width now, so we don't have borders included
		conH = boxH; // need to set height now, so we don't have borders included
		boxW+= this.shadowbox.sl.getSize().x + this.shadowbox.sr.getSize().x;
		boxH+= this.shadowbox.st.getSize().y + this.shadowbox.sb.getSize().y;
		c = this.centerBox(boxW,boxH);
		this.dims = {
			'boxX':c.boxX,'boxY':c.boxY,
			'boxW':boxW,'boxH':boxH,
			'conW':conW,'conH':conH,
			'imgW':width,'imgH':height
		};
		
	},
	
	centerBox: function(width,height){
		width = width.toInt();
		height = height.toInt();
		boxX = document.window.getScroll().x+((document.window.getSize().x-width)/2);
		boxY = document.window.getScroll().y+((document.window.getSize().y-height)/2);
		boxX = (boxX<0) ? 0 : boxX;
		boxY = (boxY<0) ? 0 : boxY;
		return {'boxX':boxX,'boxY':boxY};
	},
	
	clickLink: function(link){
		this.linkNum = link;
		this.link = this.links[this.linkNum];
		this.createDivs();
		this.resetStyles();
		if((this.link.href.test(/jpg/i))||(this.link.href.test(/gif/i))||(this.link.href.test(/png/i))){
			this.loadImage();
		}else{
			this.loadFrame();
		}
		return false;
	},
	
	loadImage: function(){
		this.bigImage = new Image();
		this.bigImage.onload = this.viewImage.bind(this);
		this.bigImage.src = this.link.href;
	},
	
	viewImage: function(){
		this.shadowbox.imagebox.image.src = this.bigImage.src;
		this.shadowbox.imagebox.setStyles({'display':'block',opacity: '0'});
		this.shadowbox.imagebox.caption.set('html',this.link.title.replace('&','&amp;'));
		this.getImgHeight();
		this.setDimensions();
		this.shadowbox.imagebox.setStyles({'height':this.dims.conH,'width':this.dims.conW});
		this.shadowbox.imagebox.image.setStyles({'height':this.dims.imgH,'width':this.dims.imgW});
		if(this.options.constantCaptionWidth) this.shadowbox.imagebox.caption.setStyles({'width':this.dims.imgW});
		this.shadowbox.effect.start({
			'1': {'opacity': '0'},
			'2': {'opacity': '0'},
			'13':{'opacity': '1'},
			'15':{'opacity': '1'},
			'16':{'opacity': '1'}
		});
	},
	
	getImageHeight: function(){
		this.calcDims(this.bigImage.width.toInt(),this.bigImage.height.toInt(),this.scrollSizeWithMargins(this.shadowbox.imagebox.caption).y);
	},
	
	loadFrame: function(){
		this.shadowbox.framebox.frame.destroy();
		this.shadowbox.framebox.frame = new IFrame({'src':this.link.href,'scrolling':'auto','frameborder':'0','class':'sbFrame','height':this.options.maxHeight,'width':this.options.maxWidth}).inject(this.shadowbox.framebox,'top');
		this.shadowbox.framebox.setStyles({'display':'block',opacity: '0'});
		this.shadowbox.framebox.caption.set('html',this.link.title.replace('&','&amp;'));
		this.getFrameHeight();
		this.setDimensions();
		this.shadowbox.framebox.setStyles({'height':this.dims.conH,'width':this.dims.conW});
		this.shadowbox.effect.start({
			'1': {'opacity': '0'},
			'2': {'opacity': '0'},
			'14':{'opacity': '1'},
			'17':{'opacity': '1'},
			'18':{'opacity': '1'}
		});
	},
	
	getFrameHeight: function(){
		this.calcDims(this.options.maxWidth,this.options.maxHeight,this.scrollSizeWithMargins(this.shadowbox.framebox.caption).y);
	},
	
	scrollSizeWithMargins: function(e){
		d = e.getScrollSize();
		m = e.getStyles('marginTop','marginRight','marginBottom','marginLeft');
		x = d.x.toInt();
		y = d.y.toInt();
		t = m.marginTop.toInt();
		r = m.marginRight.toInt();
		b = m.marginBottom.toInt();
		l = m.marginLeft.toInt();
		return {'x':x+r+l,'y':y+t+b};
	},
	
	close: function(){
		this.shadowbox.effect.start({'0':{'opacity':'0'}});
		if(this.options.hideBackground) this.overlay.hide();
		this.clearStyles.delay(this.options.fxduration,this);
	},
	
	clearStyles: function(){
		this.getElementsList().removeProperty('style');
	}
});
