/*
	Slimbox v1.31 - The ultimate lightweight Lightbox clone
	by Christophe Beyls (http://www.digitalia.be) - MIT-style license.
	Inspired by the original Lightbox v2 by Lokesh Dhakar.
*/

function NewAjaxObject()
{
	if(!window.XMLHttpRequest)
	{           
        try
        {
	        return new ActiveXObject("Msxml2.XMLHTTP");	        
        }
        catch(e)
        {
	        try
	        { 
	            return new ActiveXObject("Microsoft.XMLHTTP"); 
	        }
	        catch(e){ }
        }
    }
    else return new XMLHttpRequest();
}

var Framebox = {

	init: function(options){
		this.options = Object.extend({
			resizeDuration: 400,
			resizeTransition: Fx.Transitions.sineInOut,
			initialWidth: 250,
			initialHeight: 250,
			animateCaption: true
		}, options || {});

		this.anchors = [];
		$each(document.links, function(el){
			if (el.rel && el.rel.test(/^framebox/i)){
				el.onclick = this.click.pass(el, this);
				this.anchors.push(el);
			}
		}, this);
		this.eventKeyDown = this.keyboardListener.bindAsEventListener(this);
		this.eventPosition = this.position.bind(this);

		this.overlay = new Element('div').setProperty('id', 'lbOverlay').injectInside(document.body);

		this.center = new Element('div').setProperty('id', 'lbCenter').setStyles({width: this.options.initialWidth+'px', height: this.options.initialHeight+'px', marginLeft: '-'+(this.options.initialWidth/2)+'px', display: 'none'}).injectInside(document.body);
		this.body = new Element('div').setProperty('id', 'lbImage').injectInside(this.center);
		
		this.guts = null; this.preloadingImages = [];
		
		this.prevLink = new Element('a').setProperties({id: 'lbPrevLink', href: '#'}).setStyle('display', 'none').injectInside(this.body);
		this.nextLink = this.prevLink.clone().setProperty('id', 'lbNextLink').injectInside(this.body);
		this.prevLink.onclick = this.previous.bind(this);
		this.nextLink.onclick = this.next.bind(this);
				
		this.bottomContainer = new Element('div').setProperty('id', 'lbBottomContainer').setStyle('display', 'none').injectInside(document.body);
		this.bottom = new Element('div').setProperty('id', 'lbBottom').injectInside(this.bottomContainer);
		new Element('a').setProperties({id: 'lbCloseLink', href: '#'}).injectInside(this.bottom).onclick = this.overlay.onclick = this.close.bind(this);
		this.caption = new Element('div').setProperty('id', 'lbCaption').injectInside(this.bottom);
		this.number = new Element('div').setProperty('id', 'lbNumber').injectInside(this.bottom);
		new Element('div').setStyle('clear', 'both').injectInside(this.bottom);

		var nextEffect = this.nextEffect.bind(this);
		this.fx = {
			overlay: this.overlay.effect('opacity', {duration: 500}).hide(),
			resize: this.center.effects({duration: this.options.resizeDuration, transition: this.options.resizeTransition, onComplete: nextEffect}),
			body: this.body.effect('opacity', {duration: 400, onComplete: nextEffect}),
			bottom: this.bottom.effect('margin-top', {duration: 400, onComplete: nextEffect})
		};		
	
	      this.preloadingPrev = NewAjaxObject();
	      this.preloadingNext = NewAjaxObject();
	   
	      this.preloadedPrev = null; //div	  
        this.preloadedNext = null; //div
	      
        this.activeFrame = undefined;
	},

  prep: function(text){
    
      var out, tmp = document.createElement('div');
      
      tmp.innerHTML = text; 
  	
      var divs = tmp.getElementsByTagName('div');
            
      for(var i=0;i<divs.length;i++) if(divs[i].id == 'main')
      { 
          out = divs[i].cloneNode(true); break; 
      }
              
      var imgs = out.getElementsByTagName('img')
      
      for(var i=0;i<imgs.length;i++) //try to force preloading of images
      {
       var pre = new Image(); pre.src = imgs[i].src; this.preloadingImages.push(pre);
      }
                              
      if(out) return out; //else...
                
      out = document.createElement('div');
        
      out.innerHTML = '<font color="white">Sorry, the data you\'ve requested does not exist or is unavailable at this time.</font>'; 
      
      return out;
  },
  
	click: function(link){

		if (link.rel.length == 8) return this.show(link.href, link.title);

		var j, frameNum, frames = [];
		this.anchors.each(function(el){
			if (el.rel == link.rel){
				for (j = 0; j < frames.length; j++) if(frames[j][0] == el.href) break;
				if (j == frames.length){
					frames.push([el.href, el.title]);
					if (el.href == link.href) frameNum = j;
				}
			}
		}, this);
		return this.open(frames, frameNum);
	},

	show: function(url, title){
		return this.open([[url, title]], 0);
	},

	open: function(frames, frameNum){

		this.frames = frames;
		this.position();
		this.setup(true);
		this.top = window.getScrollTop() + (window.getHeight() / 15);
		this.center.setStyles({top: this.top+'px', display: ''});
		this.fx.overlay.start(0.8);
		return this.changeImage(frameNum);
	},

	position: function(){
		this.overlay.setStyles({top: window.getScrollTop()+'px', height: window.getHeight()+'px'});
	},

	setup: function(open){
		var elements = $A(document.getElementsByTagName('object'));
		elements.extend(document.getElementsByTagName(window.ie ? 'select' : 'embed'));
		elements.each(function(el){
			if (open) el.lbBackupStyle = el.style.visibility;
			el.style.visibility = open ? 'hidden' : el.lbBackupStyle;
		});
		var fn = open ? 'addEvent' : 'removeEvent';
		window[fn]('scroll', this.eventPosition)[fn]('resize', this.eventPosition);
		document[fn]('keydown', this.eventKeyDown);
		this.step = 0;
	},

	keyboardListener: function(event){
		switch (event.keyCode){
			case 27: case 88: case 67: this.close(); break;
			case 37: case 80: this.previous(); break;	
			case 39: case 78: this.next();
		}
	},

	previous: function(){
		return this.changeImage(this.activeFrame-1);
	},

	next: function(){
		return this.changeImage(this.activeFrame+1);
	},

	changeImage: function(frameNum){

		if ( (frameNum < 0) || (frameNum >= this.frames.length)) return false; //this.step ||
				
		this.step = 1; var next = 0, prev = 0;
		
		if(this.activeFrame!=undefined)
		{		  
		    if(this.activeFrame==frameNum-1) next = 1; else if(this.activeFrame==frameNum+1) prev = 1;
		    
		      //else alert('changeImage(): this.activeFrame==frameNum');
		}
		
		this.mutex = 1;
		
		this.activeFrame = frameNum;
		
		this.center.style.backgroundColor = '';
		this.bottomContainer.style.display = this.prevLink.style.display = this.nextLink.style.display = 'none';
		this.fx.body.hide();
		this.center.className = 'lbLoading';
		    
		  

		if(next) //assuming next
		{
        this.preloadingPrev = this.preloading; this.preloading = this.preloadingNext; 		    		    
	      this.preloadedPrev = this.preloaded; this.preloaded = this.preloadedNext;	    
		}
		else if(prev) //assuming prev
		{
		    this.preloadingNext = this.preloading; this.preloading = this.preloadingPrev; 
		    this.preloadedNext = this.preloaded; this.preloaded = this.preloadedPrev;              	        
		}
		else 
		{
		      this.preloading = NewAjaxObject();
           
	        this.preloading.onload = this.nextInline.bind(this,this.activeFrame);
            
            this.preloading.open("GET",this.frames[this,this.activeFrame][0],true);
            this.preloading.send(null);
            		
        next = prev = 1;
        
		    //this.preloading.onload = this.nextEffect.bind(this);
		    //this.preloading.src = this.frames[frameNum][0];
    		
    }
    
    this.mutex = 0;
    
    
    if(next&&this.activeFrame+1<this.frames.length) 
		{ 	
		    this.preloadingNext = NewAjaxObject(); this.preloadedNext = null;
		    		    
	      this.preloadingNext.onload = this.nextInline.bind(this,this.activeFrame+1);
	        
			   this.preloadingNext.open("GET",this.frames[this.activeFrame+1][0],true); 
         
         this.preloadingNext.send(null);
		}
		
    if(prev&&this.activeFrame) //TODO: looping
		{
		    this.preloadingPrev = NewAjaxObject(); this.preloadedPrev = null;
		    
		    this.preloadingPrev.onload = this.nextInline.bind(this,this.activeFrame-1);
	        
			  this.preloadingPrev.open("GET",this.frames[this.activeFrame-1][0],true); 
        
        this.preloadingPrev.send(null);
		}
    
		if(this.preloaded) this.nextEffect();		
		            		    
		return false;
	},

    nextInline: function(Frame) //TODO: looping
    {
     //while(this.mutex); //should wait instead
     
     if(Frame==this.activeFrame) 
     {  
        this.preloaded = null; //clean cache
        
        this.preloaded = this.prep(this.preloading.responseText); 
     
        this.nextEffect(); //ready to go...
     }
     else if(Frame==this.activeFrame+1)
     {        
        this.preloadedNext = null; //clean cache
        
        this.preloadedNext = this.prep(this.preloadingNext.responseText);
        
        //alert('nextInline: next is ready');
     }
     else if(Frame==this.activeFrame-1)
     {     
        this.preloadedPrev = null; //clean cache
        
        this.preloadedPrev = this.prep(this.preloadingPrev.responseText);     
        
        //alert('nextInline: previous is ready');
     }    
     else return; //assuming late to the party 
     
     //alert('nextInline: '+ Frame + ' and ' + this.activeFrame + 'does not compute!'); //impossible!
     
    },

	nextEffect: function(){
		
		switch (this.step++){
		case 1:
			this.center.className = '';
//			this.body.style.backgroundImage = 'url('+this.frames[this.activeFrame][0]+')';         


                if(this.guts) this.body.removeChild(this.guts); 
                
                this.guts = this.preloaded; //save for later
                                                           
                this.body.appendChild(this.guts);
            

			this.body.style.width = this.bottom.style.width = '512px'; //this.preloading.width+'px'; //'440px';
			this.body.style.height = this.prevLink.style.height = this.nextLink.style.height = '384px'; //this.preloading.height+'px'; //'440px';

			this.caption.setHTML(this.frames[this.activeFrame][1] || '');
			this.number.setHTML((this.frames.length == 1) ? '' : (Ajaxbox_Object_Hack?(Ajaxbox_Object_Hack+' '):'Frame ')+(this.activeFrame+1)+' of '+this.frames.length);


			if (this.center.clientHeight != this.body.offsetHeight){
				this.fx.resize.start({height: this.body.offsetHeight});
				break;
			}
			this.step++;
		case 2:
			if (this.center.clientWidth != this.body.offsetWidth){
				this.fx.resize.start({width: this.body.offsetWidth, marginLeft: -this.body.offsetWidth/2});
				break;
			}
			this.step++;
		case 3:
			this.bottomContainer.setStyles({top: (this.top + this.center.clientHeight)+'px', height: '0px', marginLeft: this.center.style.marginLeft, display: ''});
			this.fx.body.start(1);
			break;
		case 4:
			this.center.style.backgroundColor = '#000';
			if (this.options.animateCaption){
				this.fx.bottom.set(-this.bottom.offsetHeight);
				this.bottomContainer.style.height = '';
				this.fx.bottom.start(0);
				break;
			}
			this.bottomContainer.style.height = '';
		case 5:
			if (this.activeFrame) this.prevLink.style.display = '';
			if (this.activeFrame != (this.frames.length - 1)) this.nextLink.style.display = '';
			this.step = 0;
		}
	},

	close: function(){
		if (this.step < 0) return;
		this.step = -1;
		if (this.preloading){
			this.preloading.onload = Class.empty;	this.preloading = null;
									
			this.preloadingPrev.onload = Class.empty;	this.preloadingPrev = null;
			this.preloadingNext.onload = Class.empty;	this.preloadingNext = null;
			
			this.preloadedPrev = null; this.preloadedNext = null;
			
			this.preloaded = null; 
		}
		for (var f in this.fx) this.fx[f].stop();
		this.center.style.display = this.bottomContainer.style.display = 'none';
		this.fx.overlay.chain(this.setup.pass(false, this)).start(0);
		
		this.activeFrame = undefined;
		
		return false;
	}
};

window.addEvent('domready', Framebox.init.bind(Framebox));
