var DynaPhotoViewer = Class.create();
DynaPhotoViewer.prototype = {
	initialize: function() {
		var data = $A(arguments);
		this.info = (data[0]) ? data[0] : {'id':'DynaPhotoViewer','title':'Photo Viewer'};
		
		this.version = .5;
		this.curr_photo = 0;
		this.start_photo = 0;
		this.end_photo = 0;
		this.anim = false;
		this.leftover = 0;
		
		this.layout = {'orientation':'horizontal','align':'left','visible_thumbs':3,'focus':'start','spacing':10,'border':2,'opacity':0.4,'duration':.5}
		this.photo_info = {'full':{},'thumb':{'w':104,'h':62,'dir':'thumbs/'},'focus':{'w':275,'h':164,'dir':''},'views':{'w':275,'h':164,'dir':''}}
		this.file_info = {'displayText':''}
		this.photos = [	{'title':'Photo title one','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'001.jpg','href':'http://www.apple.com/','views':[],'files':[{'title':'Test File One','fil__ename':'testfile_1.pdf','dir':'files/'}]},
						{'title':'Photo title two','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'002.jpg','href':'','views':[],'files':[]},
						{'title':'Photo title three','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'003.jpg','href':'','views':[],'files':[]},
						{'title':'Photo title four','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'004.jpg','href':'','views':[],'files':[]},
						{'title':'Photo title five','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'005.jpg','href':'','views':[],'files':[]},
						{'title':'Photo title six','text':'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.','dir':'images/','filename':'006.jpg','href':'','views':[],'files':[]}
					];
		
		this.display = {'viewer_title':true,'photo_title':true,'controls':true,'files':true}
		this.controls = {'previous':true,'next':true,'play':false,'larger':false}
		this.slideshow = {'loop':0,'speed':4,'pause':true,'continuous':false}
	},
	
	load:function () {
		if (this.photos.length > 0) {
			var self = this;
			
			this.preloadPhotos();
			
			if (!$(this.info.id)) {
				var body = document.getElementsByTagName('BODY')[0];
				var viewerContainer = document.createElement('div');
				viewerContainer.id = this.info.id;
				viewerContainer.className = 'DynaPhotoViewer';
				body.appendChild(viewerContainer);
			}
			
			if (this.display.viewer_title) { $(this.info.id).insert('<div class="viewer_title" id="' + this.info.id + '_title">' + this.info.title + '</div>'); }
			
			if (this.display.photo_title) { $(this.info.id).insert('<div class="viewer_photo_title" id="' + this.info.id + '_photo_title">' + this.photos[this.curr_photo].title + '</div>'); }
			
			if (this.display.files) { $(this.info.id).insert('<div class="viewer_photo_files" id="' + this.info.id + '_photo_files"></div>'); }
			
			$(this.info.id).insert('<div class="viewer_photo_thumbs" id="' + this.info.id + '_photo_thumbs"></div>');
			
			
			if (this.layout.visible_thumbs > 1) {
				if (this.layout.visible_thumbs > this.photos.length) { this.layout.visible_thumbs = this.photos.length; }
				
				this.leftover = Math.floor(this.layout.visible_thumbs / 2);
				switch (this.layout.focus) {
				case 'middle' :
					this.curr_photo = ( Math.ceil(this.photos.length / 2) - 1 );
					
					var loop = this.curr_photo;
					while (loop > -1) {
						if (loop == (this.curr_photo - this.leftover)) { break; }
						loop--;
					}
					this.start_photo = loop;
					
					loop = this.curr_photo;
					while (loop < this.photos.length) {
						if (loop == (this.curr_photo + this.leftover)) { break; }
						loop++;
					}
					this.end_photo = loop;
					
					break;
				case 'start' :
					this.end_photo = this.curr_photo + this.leftover;
					break;
				}
			}
			
	
			var photo_list = '';
			for (var i=this.start_photo;i<this.end_photo+1;i++) {
				var photo_classes = ['thumb'];
				var photo_src = this.photos[i].dir + this.photo_info.thumb.dir + this.photos[i].filename;
				if (i == this.curr_photo) { photo_classes.push('focus'); }
				photo_list += '<li class="' + photo_classes.join(' ') + '"><img src="' + photo_src + '" /></li>' + "\n";
			}
			$(this.info.id + '_photo_thumbs').insert('<ul>' + photo_list + '</ul>');
			
			var photo_thumbs_h = (this.photo_info.focus.h > this.photo_info.thumb.h) ? this.photo_info.focus.h : this.photo_info.thumb.h;
				photo_thumbs_h = photo_thumbs_h + (this.layout.spacing * 2) + (this.layout.border * 2);
			var photo_focus_w = (this.photo_info.focus.w > this.photo_info.thumb.w) ? this.photo_info.focus.w : this.photo_info.thumb.w;
			var photo_thumbs_w = (  (((this.layout.visible_thumbs - 1) * this.photo_info.thumb.w) + photo_focus_w) + ((this.layout.visible_thumbs + 1) * this.layout.spacing) + ((this.layout.visible_thumbs) * (this.layout.border * 2)) );

			// define / set photo_thumbs container styles
			var photo_thumbs_styles = '';
			photo_thumbs_styles += ",overflow:'hidden',position:'relative',height:'" + photo_thumbs_h + "px',width:'" + photo_thumbs_w + "px'";
			if (this.layout.align == 'center') { photo_thumbs_styles += ",position:'absolute',left:'50%',marginLeft:'" + (0-(photo_thumbs_w / 2)) + "px'"; }
			photo_thumbs_styles = "{" + photo_thumbs_styles.substr(1) + "}";
			$(this.info.id + '_photo_thumbs').setStyle(photo_thumbs_styles.evalJSON());
			
 			photo_thumbs_styles = ",overflow:'hidden',position:'relative',height:'" + photo_thumbs_h + "px',width:'" + photo_thumbs_w + "px'";
			if (this.layout.focus == 'start' && this.layout.visible_thumbs > 1) { photo_thumbs_styles += ",paddingLeft:'" + (this.photo_info.thumb.w + (this.layout.border * 2) + (this.layout.spacing)) + "px'"; }
			photo_thumbs_styles = "{" + photo_thumbs_styles.substr(1) + "}";
			$(this.info.id + '_photo_thumbs').down('ul').setStyle(photo_thumbs_styles.evalJSON());
			
			$(this.info.id + '_photo_thumbs').down('ul').select('li').each(function(thumb) {
																				var marginTop = (photo_thumbs_h / 2) - ( (self.photo_info.thumb.h + (self.layout.border * 2)) / 2);
																				var marginLeft = self.layout.spacing;
																				var width = self.photo_info.thumb.w;
																				var height = self.photo_info.thumb.h;
																				var opacity = self.layout.opacity;
																				if (thumb.hasClassName('focus')) {
																					marginTop = self.layout.spacing;
																					width = self.photo_info.focus.w;
																					height = self.photo_info.focus.h;
																					opacity = 1.0;
																				}
																				thumb.setStyle({opacity:opacity,borderWidth:self.layout.border+'px',cssFloat:'left',display:'inline',overflow:'hidden',width:width+'px',height:height+'px',marginTop:marginTop+'px',marginLeft:marginLeft+'px'});
																				thumb.down('img').setStyle({display:'block',margin:0,padding:0,width:width+'px',height:height+'px'});
																			});
			
			if (this.display.controls) {
				var controls = '';
				if (this.controls.previous) { controls += '<li class="control previous">previous</li>'; }
				if (this.controls.play) { controls += '<li class="control play">play</li>'; }
				if (this.controls.larger) { controls += '<li class="control larger">larger</li>'; }
				if (this.controls.next) { controls += '<li class="control next">next</li>'; }
				if (controls != '') { $(this.info.id).insert('<div class="viewer_controls" id="' + this.info.id + '_controls"><ul>' + controls + '</ul></div>'); }
			}
			
			
			this.displayPhotoFiles();
			this.displayPhotoTitle();
			
			//set event handlers
			Event.observe(this.info.id,"mouseout",this.outEvent.bindAsEventListener(this));
			Event.observe(this.info.id,"mouseover",this.overEvent.bindAsEventListener(this));
			Event.observe(this.info.id,"mouseup",this.upEvent.bindAsEventListener(this));
			
			new Effect.SlideDown(this.info.id);
			
		}
	},
	
	displayPhotoFiles:function () {
		var file_list = '';
		if (this.photos[this.curr_photo].files.length > 0) {
			var self = this;
			file_list = '<ul>';
			this.photos[this.curr_photo].files.each(function(file,index) {
				var display_text = '';
				if (self.file_info.displayText && self.file_info.displayText != '') {
					display_text = file.displayText;
				} else if (file.title && file.title != '') {
					display_text = file.title;
				} else {
					display_text = file.filename;
				}
				
				file_list += '<li class="file"><a href="' + file.dir + file.filename + '" target="_blank">' + display_text + '</a></li>';
			});
			file_list += '</ul>';
			
			$(this.info.id + '_photo_files').update(file_list);
		}
	},
	
	displayPhotoTitle:function() {
		$(this.info.id + '_photo_title').update(this.photos[this.curr_photo].title);
	},
	
	preloadPhotos:function () {
		var self = this;
		var images = [];
		this.photos.each(function(photo,index) {
			images[index] = new Image();
			images[index].src = photo.dir + self.photo_info.thumb.dir + photo.filename;
		});
	},
	
	
	upEvent:function(e) {
		var self = this;
		var target_el = Event.element(e);
		
		switch (target_el.tagName) {
		case 'IMG' :
			var selected_el = target_el.up('li');
			if (selected_el != 'undefined' && selected_el != null && selected_el.hasClassName('thumb')) { this.clickThumb(selected_el); }
			
			break;
		case 'LI' :
			if (target_el.hasClassName('control')) {
				if (target_el.hasClassName('previous')) {
					var selected_index = this.curr_photo - 1;
					if (selected_index > -1) {
						var selected_el = $(this.info.id + '_photo_thumbs').down('li.focus').previous(0);
						this.previousPhoto(selected_index,selected_el);
					}
				} else if (target_el.hasClassName('next')) {
					var selected_index = this.curr_photo + 1;
					if (selected_index < this.photos.length) {
						var selected_el = $(this.info.id + '_photo_thumbs').down('li.focus').next(0);
						this.nextPhoto(selected_index,selected_el);
					}
				}
			}
			break;
		}
	},
	
	overEvent:function(e) {
		var self = this;
		var target_el = Event.element(e);
		
		switch (target_el.tagName) {
		case 'IMG' :
			var parent_el = target_el.up('li');
			if (parent_el.hasClassName('thumb')) {
				parent_el.addClassName('hover');
			}
			break;
		case 'LI' :
			if (target_el.hasClassName('control')) {
				target_el.addClassName('hover');
			}
			break;
		}
	},
	
	outEvent:function(e) {
		var target_el = Event.element(e);
		var related_el = e.relatedTarget || e.toElement;
		while (related_el != target_el && related_el.nodeName != 'BODY') {
			related_el = related_el.parentNode;
		}
		if (related_el == target_el) return;
	
		switch (target_el.tagName) {
		case 'IMG' :
			var parent_el = target_el.up('li');
			if (parent_el.hasClassName('thumb')) {
				parent_el.removeClassName('hover');
			}
			break;
		case 'LI' :
			if (target_el.hasClassName('control')) {
				target_el.removeClassName('hover');
			}
			break;
		}
	},
	
	clickThumb:function(selected_el) {
		if (selected_el.hasClassName('focus')) {
			
			if (this.photos[this.curr_photo].href != '') {
				if (this.photos[this.curr_photo].href.substr(0,8) == '<script>') {
					this.photos[this.curr_photo].href.evalScripts();
				} else {
					window.location = this.photos[this.curr_photo].href;
				}
			}
			
		} else {
			var offset_index = 0;
			var selected_index = -1;
			
			// check back
			var next_el = selected_el.previous();
			while (next_el != 'undefined' && next_el != null) {
				offset_index++;
				if (next_el.hasClassName('focus')) {
					selected_index = this.curr_photo + offset_index;
					break;
				}
				next_el = next_el.previous();
			}
			
			// if not back then check forward
			if (selected_index < 0) {
				offset_index = 0;
				next_el = selected_el.next();
				while (next_el != 'undefined' && next_el != null) {
					offset_index++;
					if (next_el.hasClassName('focus')) {
						selected_index = this.curr_photo - offset_index;
						break;
					}
					next_el = next_el.next();
				}
			}

			if (selected_index > -1) {
				if (selected_index > this.curr_photo) {
					this.nextPhoto(selected_index,selected_el);
				} else if (selected_index < this.curr_photo) {
					this.previousPhoto(selected_index,selected_el);
				}
			}
		}
	},
	
	
	animTimer:function() {
		var self = this;
		new PeriodicalExecuter(function(pe) {
    		self.anim = false;
    		pe.stop();
		},this.layout.duration);
	},

	
	nextPhoto:function(selected_index,selected_el) {
		
		if (!this.anim) {
		this.anim = true;

		var focus_photo = $(this.info.id + '_photo_thumbs').down('li.focus');

		focus_photo.removeClassName('focus');
		selected_el.addClassName('focus');
				
		//add thumbs
		var photo_thumbs_h = (this.photo_info.focus.h > this.photo_info.thumb.h) ? this.photo_info.focus.h : this.photo_info.thumb.h;
				photo_thumbs_h = photo_thumbs_h + (this.layout.spacing * 2) + (this.layout.border * 2);
		var marginTop = (photo_thumbs_h / 2) - ( (this.photo_info.thumb.h + (this.layout.border * 2)) / 2);
		
		var addThumbs = '';
		var addedThumbs = 0;
		var advancedThumbs = selected_index - this.curr_photo;
		var addNumThumbs = ( (selected_index - this.curr_photo) < this.leftover ) ? this.leftover : selected_index - this.curr_photo;
		for (var i=0;i<addNumThumbs;i++) { 
			var nextThumb = selected_index + (i + 1);
			if (selected_el.next(i) == 'undefined' || selected_el.next(i) == null && (nextThumb < this.photos.length) ) {
				var photo_src = this.photos[nextThumb].dir + this.photo_info.thumb.dir + this.photos[nextThumb].filename;
				
				var marginLeft = this.layout.spacing;
				var width = this.photo_info.thumb.w;
				var height = this.photo_info.thumb.h;
				
				var opacity = (this.layout.opacity < 1) ? 'opacity:' + this.layout.opacity + ';-moz-opacity:this.layout.opacity;filter:alpha(opacity=' + (this.layout.opacity * 100) + ');' : '';
				var thumbStyles = opacity + 'border-width:' + this.layout.border + 'px;float:left;display:inline;overflow:hidden;width:' + width + 'px;height:' + height + 'px;margin-top:' + marginTop + 'px;margin-left:' + marginLeft + 'px;';
				var thumbImgStyles = 'width:' + width + 'px;height:' + height + 'px;margin:0;padding:0;display:block';
				addThumbs += '<li class="thumb" style="' + thumbStyles + '"><img style="' + thumbImgStyles + '" src="' + photo_src + '" /></li>';
				addedThumbs++;
			}
		}
		
		
		if (addedThumbs > 0) {
			var tmpWidth = $(this.info.id + '_photo_thumbs').down('ul').getWidth();
			var thumbsWidth = ( tmpWidth + (addedThumbs * (this.photo_info.thumb.w + (this.layout.border * 2) + (this.layout.spacing))) );
			$(this.info.id + '_photo_thumbs').down('ul').setStyle({width:thumbsWidth +'px'});
			$(this.info.id + '_photo_thumbs').down('ul').insert(addThumbs);
		}
		

		var moveThumbs_x = 0 - ( (this.photo_info.thumb.w + (this.layout.border * 2) + (this.layout.spacing * 1)) * advancedThumbs );
		if (this.photo_info.focus.w > this.photo_info.thumb.w) { 
			var scaleFocusPercent = (this.photo_info.thumb.w / this.photo_info.focus.w) * 100;
			var scaleSelectedPercent = (this.photo_info.focus.w / this.photo_info.thumb.w) * 100;
			
			new Effect.Parallel([	new Effect.Scale(focus_photo,scaleFocusPercent,{scaleMode:'contents',duration:this.layout.duration}),
									new Effect.Opacity(focus_photo,{from:1.0,to:this.layout.opacity,duration:this.layout.duration}),
									new Effect.Scale(focus_photo.down('img'), scaleFocusPercent,{duration:this.layout.duration}),
									new Effect.Move (focus_photo,{ x: 0, y: (marginTop - this.layout.spacing), mode: 'relative',duration:this.layout.duration}),
									new Effect.Scale(selected_el, scaleSelectedPercent,{scaleMode:'contents',duration:this.layout.duration}),
									new Effect.Opacity(selected_el,{from:this.layout.opacity,to:1.0,duration:this.layout.duration}),
									new Effect.Scale(selected_el.down('img'), scaleSelectedPercent,{duration:this.layout.duration}),
									new Effect.Move (selected_el,{ x: 0, y: (0 - (marginTop - this.layout.spacing)), mode: 'relative',duration:this.layout.duration}),
									new Effect.Move ($(this.info.id + '_photo_thumbs').down('ul'),{ x: moveThumbs_x, y: 0, mode: 'relative',duration:this.layout.duration})
								],{duration:this.layout.duration});
		} else {
			new Effect.Move ($(this.info.id + '_photo_thumbs').down('ul'),{ x: moveThumbs_x, y: 0, mode: 'relative',duration:this.layout.duration});
		}


		this.curr_photo = selected_index;
		
		if (this.display.photo_title) { this.displayPhotoTitle(); }
		if (this.display.files) { this.displayPhotoFiles(); }
		
		this.animTimer();
		}
	},
	
	previousPhoto:function(selected_index,selected_el) {
		if (!this.anim) {
		this.anim = true;
		var focus_photo = $(this.info.id + '_photo_thumbs').down('li.focus');
		
		
		focus_photo.removeClassName('focus');
		selected_el.addClassName('focus');
		
		//add thumbs
		var photo_thumbs_h = (this.photo_info.focus.h > this.photo_info.thumb.h) ? this.photo_info.focus.h : this.photo_info.thumb.h;
				photo_thumbs_h = photo_thumbs_h + (this.layout.spacing * 2) + (this.layout.border * 2);
		var marginTop = (photo_thumbs_h / 2) - ( (this.photo_info.thumb.h + (this.layout.border * 2)) / 2);
		
		var addThumbs = '';
		var addedThumbs = 0;
		var advancedThumbs = this.curr_photo - selected_index;
		var addNumThumbs = ( (this.curr_photo - selected_index) < this.leftover ) ? this.leftover : this.curr_photo - selected_index;
		
		
		for (var i=0;i<addNumThumbs;i++) { 
			var previousThumb = selected_index - (i + 1);
			if (selected_el.previous(i) == 'undefined' || selected_el.previous(i) == null && (previousThumb > -1) ) {
				var photo_src = this.photos[previousThumb].dir + this.photo_info.thumb.dir + this.photos[previousThumb].filename;
				
				var marginLeft = this.layout.spacing;
				var width = this.photo_info.thumb.w;
				var height = this.photo_info.thumb.h;
				
				var opacity = (this.layout.opacity < 1) ? 'opacity:' + this.layout.opacity + ';-moz-opacity:this.layout.opacity;filter:alpha(opacity=' + (this.layout.opacity * 100) + ');' : '';
				var thumbStyles = opacity + 'border-width:' + this.layout.border + 'px;float:left;display:inline;overflow:hidden;width:' + width + 'px;height:' + height + 'px;margin-top:' + marginTop + 'px;margin-left:' + marginLeft + 'px;';
				var thumbImgStyles = 'width:' + width + 'px;height:' + height + 'px;margin:0;padding:0;display:block';
				addThumbs += '<li class="thumb" style="' + thumbStyles + '"><img style="' + thumbImgStyles + '" src="' + photo_src + '" /></li>';
				addedThumbs++;
			}
		}
		
		if (addedThumbs > 0) {
			var tmpWidth = $(this.info.id + '_photo_thumbs').down('ul').getWidth();
			var addedSpace = (addedThumbs * (this.photo_info.thumb.w + (this.layout.border * 2) + (this.layout.spacing)));
			var thumbsWidth = (tmpWidth + addedSpace);
			$(this.info.id + '_photo_thumbs').down('ul').insert({'top':addThumbs});
			$(this.info.id + '_photo_thumbs').down('ul').setStyle({width:thumbsWidth+'px',left:(0 - addedSpace)+'px'});
		}



		var moveThumbs_x = (this.photo_info.thumb.w + (this.layout.border * 2) + (this.layout.spacing * 1)) * advancedThumbs;
		if (this.photo_info.focus.w > this.photo_info.thumb.w) { 
			var scaleFocusPercent = (this.photo_info.thumb.w / this.photo_info.focus.w) * 100;
			var scaleSelectedPercent = (this.photo_info.focus.w / this.photo_info.thumb.w) * 100;
			
			new Effect.Parallel([	new Effect.Scale(focus_photo, scaleFocusPercent,{scaleMode:'contents',duration:this.layout.duration}),
									new Effect.Opacity(focus_photo,{from:1.0,to:this.layout.opacity,duration:this.layout.duration}),
									new Effect.Scale(focus_photo.down('img'), scaleFocusPercent,{duration:this.layout.duration}),
									new Effect.Move (focus_photo,{ x: 0, y: (marginTop - this.layout.spacing), mode: 'relative',duration:this.layout.duration}),
									new Effect.Scale(selected_el, scaleSelectedPercent,{scaleMode:'contents',duration:this.layout.duration}),
									new Effect.Opacity(selected_el,{from:this.layout.opacity,to:1.0,duration:this.layout.duration}),
									new Effect.Scale(selected_el.down('img'), scaleSelectedPercent,{duration:this.layout.duration}),
									new Effect.Move (selected_el,{ x: 0, y: (0 - (marginTop - this.layout.spacing)), mode: 'relative',duration:this.layout.duration}),
									new Effect.Move ($(this.info.id + '_photo_thumbs').down('ul'),{ x: moveThumbs_x, y: 0, mode: 'relative',duration:this.layout.duration})
								],{duration:this.layout.duration});
		} else {
			new Effect.Move ($(this.info.id + '_photo_thumbs').down('ul'),{ x: moveThumbs_x, y: 0, mode: 'relative',duration:this.layout.duration});
		}
		
		this.curr_photo = selected_index;
		if (this.display.photo_title) { this.displayPhotoTitle(); }
		if (this.display.files) { this.displayPhotoFiles(); }
		
		this.animTimer();
		}
	},
	
	beginLoop:function () {
		var self = this;
		this.loop_timer = new PeriodicalExecuter(function() { 
			var next_index = ( (self.curr_info_index + 1) >= self.show_info.length ) ? 0 : self.curr_info_index + 1;
			self.introChange(next_index,false);
			self.curr_info_index = next_index;
		}, this.loop_speed);
	}
}