/*

Why are you looking at the code?

http://office-for.com

*/

var Photos = Class.create(
	{
    	// CONSTRUCTOR
	    initialize: function(p,s)
	    {
			// To ensure nocache
			delete this.photos; 
			delete this.sort;
			
			// Set up event listeners
		    this.enlarge_b = this.enlarge.bindAsEventListener(this);			
			this.loadImage_b = this.loadImage.bindAsEventListener(this);
			this.goTo_b = this.goTo.bindAsEventListener(this);			
			
	        this.next_b = this.next.bindAsEventListener(this);
	        this.prev_b = this.prev.bindAsEventListener(this);
	        this.reduce_b = this.reduce.bindAsEventListener(this);			
					
			// Set size related variables to the h / w of images
	        this.setSize(s);

			// Indices
	        this.r = 0;
	        this.c = 0;

			// Set rows value
			this.rows = Math.round(Math.sqrt(p.imgs.length));
			this.rows = (this.rows>6) ? 6 : this.rows
			
			// Photos array
	        this.photos = p.imgs;
			// Sort array
	        this.sort	= p.sort;

			if(p.statement != '')
				{
				$('statement').update('')
				$('statement').insert(p.statement);
				}
			else
				$('statement').update('');

			this.loaded = {};
	        this.loadImageCounter = 0;
	
			// Position $('photos') properly
			if(s==600) 
				$('photos').style.left = '0px'; 
			else
				$('photos').style.left = '50%'; 
			
			// Setup DOM elements	
			this.loadSetup();

			// If headed to a large image - call it
			if(s == 600)
				this.enlarge(undefined);
				
			// Start image loading loop
		    this.loadImage();				
		
	    	this.pe = new PeriodicalExecuter(this.focus.bindAsEventListener(this), 1);

	        return this;
	    },
	    // ----
	    // UTILITY METHODS
	    // ---
	    // Set class-wide size
	    setSize: function(s)
	    {
	        this.size = s;

	        this.width = (s == 100) ? 172 : s;
	        this.height = (s == 100) ? 120 : s;
	
	        this.width = (s == 600) ? 770 : this.width;
	        this.height = (s == 600) ? 540 : this.height;	
			
	    },
	    // Position li element
	    positionElement: function(d)
	    {
			// Left positioning varys with size
			if(this.size == 100)
	        	d.style.left = (this.c * this.width) - (this.width/2) + (this.c*3) + "px";
			else
				d.style.left = (this.c * this.width) + (this.width*2) + (this.c*3) + "px";
				
	        d.style.top = (this.r * this.height) + (this.r * 3) + "px";
	        d.style.width = this.width + "px";
	        d.style.height = this.height + "px";
	        d.style.backgroundColor = 'transparent';
	    },
		// Scrollto element
	    scroll: function(e,n)
	    {	
			off = e.cumulativeOffset();
	        l = Number(e.style.left.replace('px', ''))-(Math.round(document.viewport.getWidth()/2)-Math.round(this.width/2));
	        t = Number(e.style.top.replace('px', ''))+20;

	        window.scrollTo(l, t)
	    },
	    // Move through images
	    next: function(e)
	    {
			if(this.video != undefined)
				this.hideVideo();
			//$('p_'+this.selected).stopObserving('click', this.next_b);
			$('p_'+this.selected).style.opacity = '.2';
	        this.selected++;
	        if (this.selected == this.sort.length)
	        	this.selected = 0;

			$('p_'+this.selected).style.opacity = '1';
			//$('p_'+this.selected).observe('click', this.next_b);
			
	        var elem = $('p_' + this.selected);
			this.scroll(elem)
			document.location = "#"+document.location.hash.substr(1).split('.')[0]+"."+this.selected;
	    },
	    prev: function()
	    {
			if(this.video != undefined)
				this.hideVideo();
			$('p_'+this.selected).style.opacity = '.2';	
	        this.selected--;
	        if (this.selected == -1)
	        this.selected = this.sort.length - 1;
			$('p_'+this.selected).style.opacity = '1';

	        var elem = $('p_' + this.selected);
	        this.scroll(elem);
			document.location = "#"+document.location.hash.substr(1).split('.')[0]+"."+this.selected;	
	    },
		// Focus - set the opacity of the focussed image
	    focus: function()
	    {	
			// If in thumbnail mode - don't execute
			if(this.size==100)
				return;
			
	        this.photos.each(function(i)
				{
				var elem = $('p_'+i.id);
			
				var o = elem.cumulativeOffset();
				
				s = document.viewport.getScrollOffsets();
				l = o[0]-s.left;
				t = o[1]-s.top;
				
				v = document.viewport.getDimensions();
				vw = (v.width / 2);
				vh = 30; //(v.height / 2);
				
				// Test focus
				// (viewport.w/2) - (600/2) | (viewport.w/2) + (600/2)
				hw = this.width /2;
				if((l<=vw+hw && l>=vw-hw) && (t<=vh+hw && t>=vh-hw))
					elem.style.opacity = '1';
				else
					elem.style.opacity = '.2';
				}, this)
	    },
	    // ---
	    //
	    // ---
	
	
	    // ---
	    // CORE METHODS
	    // ---
	    // Image loader
		// Start at this.loadImageCounter and call back on each load
		// Until set it loaded
	    loadImage: function(e)
	    {	
			// If a callback is coming from another size - don't follow it. 
			if(e!=undefined && e.element().size != this.size)
				return;
			
	        var i = this.loadImageCounter;
		
			// Wrap around array if clicked in middle
	        if (this.loadImageCounter == this.sort.length && 
				this.selected != 0 &&
				this.lastLoad != 0)
		            i = this.loadImageCounter = 0;

			if(this.sort[i]==undefined)
				return false;
				
	        var elem = $('p_' + this.sort[i]);
			// If there's no existant image - load it
			if(elem.img == undefined || elem.img[this.size] == undefined)
				{
				var img = new Image();
	       		img.id = elem.id + "_img";
				img.size = this.size;
			
				// If it's not the last - call back
		        if (i != this.lastLoad || ((this.lastLoad == 0) && (i == this.sort.length)))
					{
			        this.callback = this.loadImage_b;
					this.img = img;
					//img.onload = this.callback;				
			        img.observe('load', this.callback);				
					}

 				img.src=elem.src;					

				// Create an img object
		        if (elem.img == undefined) 
					elem.img = {};
				}
				
			// If it's the last - label the set as loaded
			if (i == this.lastLoad && ((this.lastLoad != 0) || (i != this.sort.length)))
				{
				this.loaded[this.size] = 1;
				this.loadImageCounter = undefined;
				this.lastLoad = undefined;
				}				
				
			// Increment for the call back
	        this.loadImageCounter++;

			// If the image is already loaded - call back and return;
			if(elem.img[this.size] != undefined)
				{
				elem.img[this.size].show();
				elem.down('.loading').hide();
				this.loadImage();
				}
			// If the image needs to be loaded - insert the object, and store the object in the array.
			else
				{
				// Remove the loading information
				elem.down('.loading').hide();
				// Insert the loading image
		        elem.insert(img);
				// Add this size to it
		        elem.img[this.size] = img;
				}
	    },

	    // Setup grid 
		// Attach src / id data to each li object
	    loadSetup: function()
	    	{
			// Create UL
		    $('photos').insert(new Element('ul', {
		        id: 'photos_ul'
		    }));

		    this.photos.each(function(i) {
		        //
		        // Create all of the li elements
		        // Attach the src information - then load them in order
		        //
		        var d = new Element('li');
				if(Number(i.id)==0)
					d.insert("<h1 class=\"number\" style=\"font-weight:bold\">"+(i.id+1)+"</h1>");
				else
					d.insert("<h1 class=\"number\">"+(i.id+1)+"</h1>");
		        d.src = i[this.size].url;

		        $('photos_ul').insert(d);		
		
				if(this.size == 100)
					d.observe('click', this.enlarge_b);

		        d.style.position = 'absolute';
		        this.positionElement(d);
				d.insert(new Element('div', {'class':'loading'}).update('LOADING') );

		        this.c++;
		        if (this.c % this.rows == 0) {
		            this.c = 0;
		            this.r++;
		        }

		        if (this.photos['dom'] == undefined)
		        	this.photos['dom'] = [];

		        d.id = "p_" + i.id;
				d._id = i.id;
				if(i[600].video!=undefined)
					d._video = i[600].video;

		        this.photos['dom'].push(d);
		    },
		    this);
	
			//
			// Position the grid
			//
			$('photos').style.marginLeft = "-"+((this.rows*this.size)/2)+"px";
			
			if(s==600)
				{
				$('photos').style.width		= this.width*(this.rows+3)+"px";
				$('photos').style.height 	= this.height*(Math.round(this.sort.length/this.rows)+2)+"px";			
				}

			this.loadImageCounter = 0;
		    this.lastLoad = this.sort.length-1;
	    },
	
		// --
		// VIDEO
		// --
		showVideo: function(e)
			{
			s = $('p_'+this.selected);
			this.video = s;
			this.video.innerHTML = '<object width="'+this.width+'" height="'+this.height+'"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="'+s._video+'" /><embed src="'+s._video+'" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="'+this.width+'" height="'+this.height+'"></embed></object>';				
			},
		hideVideo: function()
			{
			this.video.innerHTML = '';
			this.video.insert(new Element('div', {'class':'loading'}).update('LOADING') );
			this.video.down('.loading').hide();
			this.video.insert(this.video.img[600]);
			this.video = undefined;
			},
		// --
		// --
	
		// GoTo - for image click
		goTo: function(e)
			{	
			if(this.dev==1) { console.log('goto'+e) }
			if(this.video != undefined)
				{
				this.hideVideo();
				}
				
			if(this.size == 100)
				{
				this.enlarging = 1;	
				this.enlarge(e)
				return;
				}
			else
				{
				if(e != undefined)	
					li = Event.findElement(e, 'li');
				else
					{
					// Sent from URL
					i = document.location.hash.substr(1).split('.')[1]
					li = $('p_'+i);
					}

				if(li == $('p_'+this.selected) && this.enlarging != 1)
					{
					if(this.dev==1) { console.log('enlarging? '+this.enlarging); }
					if($('p_'+this.selected)._video != undefined && this.enlarging != 1)
						this.showVideo();
					else
						this.next(li);
					}
				else
					{
					this.scroll(li)
					this.selected = li._id;
					}
				//document.location = "#"++"."+this.selected;
				s = document.location.hash.substr(1).split('.')[0];
				document.location.hash = s+"."+this.selected;
				}
			this.enlarging = 0;								

			},

	    // Enlarge from thumbnail
	    enlarge: function(e)
	    	{
			// Set enlarging - so goto knows destination
			this.enlarging = 1;		
			
			// Set up size of div
			$('photos').style.width 	= this.width*(this.rows+3)+"px";
			$('photos').style.height 	= this.height*(Math.round(this.sort.length/this.rows)+2)+"px";						
			
			// Add goto listener
			$('photos_ul').observe('click', this.goTo_b);						
				
			$('statement').hide();
			$('opt').show();
			$('photos').style.left = '30px';
			$('photos').style.marginLeft = '0px';
		
			if(e != undefined)
	        	i = Event.findElement(e, 'li')
			else
				i = $('p_'+document.location.hash.substr(1).split('.')[1]);
		
	        this.loadImageCounter = this.selected = i._id;
			this.lastLoad = this.loadImageCounter-1;
			if(this.lastLoad == -1) { this.lastLoad = this.sort.length }

	        $('next').observe('click', this.next_b);
	        $('prev').observe('click', this.prev_b);
	        $('thumbs').observe('click', this.reduce_b);	
			
			// If called from a thumbnail - update the size
			if(e!=undefined)
	        	this.updateSize(600);
	
			$('photos').style.width		= this.width*(this.rows+3)+"px";
			$('photos').style.height 	= this.height*(Math.round(this.sort.length/this.rows)+2)+"px";	
			
			// If called from a thumbnail - stop the loading proces
			if(e == undefined)	
				this.goTo(undefined);								

			this.photos.each(function(i) 
				{ 
				var elem = $('p_'+i.id); elem.style.opacity = '.2'; 
					elem.down('.loading').hide();
				});				
	    	},

	    // Return to thumbnails
	    reduce: function(e)
	    	{
			if(this.dev==1) { console.log('reduce'); }
			if(this.video != undefined)
				{
				r = this.video;
				this.hideVideo();
				$(r.img[600].id).hide();	
				}
			
			// Clear callbacks
			this.img.stopObserving('load', this.callback);		
			$('photos_ul').stopObserving('click', this.goTo_b);			
		
			// Show statement, hide nav options
			$('statement').show();
			$('opt').hide();	
			
			// Reset lastload, load counter
			this.lastLoad = this.sort.length-1;
			this.loadImageCounter = 0;
	        this.updateSize(100);

			$('photos').style.width 	= this.width*this.rows+"px";
			$('photos').style.height 	= this.height*((this.sort.length/this.rows)+2)+"px";
			$('photos').style.left		= '50%';
			$('photos').style.top		= '60px';
			$('photos').style.marginLeft = "-"+((this.rows*this.size)/2)+"px";					
			
			scrollTo(0,0)
			document.location = "#"+document.location.hash.substr(1).split('.')[0];			
	    	},

	    // Change size of grid
	    updateSize: function(s)
	    	{
	        this.c = 0;
	        this.r = 0;
	
	        lastSize = this.size;
	        this.setSize(s);
	
	        this.photos.each(function(i) {
	            var elem = $('p_' + i.id);
	            elem.src = i[this.size].url;
				
				if(elem.img!=undefined&&elem.img[lastSize]!=undefined)
	            	elem.img[lastSize].hide();

				// Add / remove enlarge listener
	            if (s > 100)
	            	elem.stopObserving('click', this.enlarge_b)
				if(s == 100)
					{
					elem.observe('click', this.enlarge_b)
					elem.style.opacity = '1'; 					
					}

				// Position elements
	            this.positionElement(elem);

				// If images are loaded - show them, if not, show loading status
				if(elem.img != undefined && elem.img[this.size] != undefined)
					{
					elem.img[this.size].show()
					elem.down('.loading').hide();					
					}
				else
					elem.down('.loading').show();

				// Rows / columns
	            this.c++;
	            if (this.c % this.rows == 0) {
	                this.c = 0;
	                this.r++;
	            }
	        },
	        this);
		
			//If the images for this size have not been loaded, load them.
			if(this.loaded[this.size] == undefined)
	        	this.loadImage();
	    	}
		});
