(function($) {
	var arteriagallery = window.arteriagallery = typeof window.arteriagallery !== 'undefined' ? window.arteriagallery : {},
		Gallery;
		
	arteriagallery.Gallery = Gallery = function(options) {
		var defaults = {
			gallery: $('<div class="gallery">'),
			artwork: {
				model: $('<div class="artwork">')
			},
			artist: {
				model: $('<div class="artist">')
			},
			language: 'en',
			dataProvider: null,
			itemCount: false
		};
		var options = $.extend(defaults, options);
	
		this.options = options;
		this.listeners = [];
		this.artworks = [];
		this.currentPanel = false;
		this.receivedItemCount = 0;
		
		this.getArtworks();
	}
	Gallery.prototype = {
		calcResizedImageDimensions: function(data, width, height, resizeStrategy) {
			var calcw, calch, frmsurf, calcsuf, imgmode;
			calcw = calch = frmsurf = calcsurf = 0;
			
			imgmode = 'LANDSCAPE';
			
			frmsurf =  width * height;
			
			imgw = parseInt(data.imageWidth);
			imgh = parseInt(data.imageHeight);
			
			if (imgh && height && imgw / imgh < width / height) {
				imgmode = 'PORTRAIT';
			}
			
			switch (resizeStrategy.toUpperCase()) {
				case 'SCALE_TO_FIT':
					if ('PORTRAIT' == imgmode) {
						calch = height;
						calcw = calch * imgw / imgh;
						
					} else {
						calcw = width;
						calch = calcw * imgh / imgw;
					}
					break;
				case 'CROP':
					if ('LANDSCAPE' == imgmode) {
						calch = height;
						calcw = calch * imgw / imgh;
						
					} else {
						calcw = width;
						calch = calcw * imgh / imgw;
					}
					break;
				case 'RESIZE':
				default:
					calcw = width;
					calch = height;
			}
			
			return {width:calcw, height:calch};
		},
	
		/**
		 * Fonction addListener(listener)
		 *
		 * Ajoute un écouteur à la liste. La fonction prend un objet jQuery
		 * en paramètre. L'objet associe les événements pour lesquels
		 * il désire être notifié grâce à la méthode bind. 
		 *
		 * @param  listener  Un objet jQuery
		 *
		 */
		addListener: function(listener) {
			this.listeners.push(listener);
		},
		
	
		/**
		 * Fonction notifyListeners(event, data)
		 *
		 * Notifie un événement à la liste d'écouteurs.
		 *
		 */
		notifyListeners: function(event, data) {
			var i = 0, listener;
			
			while (!event.isImmediatePropagationStopped() && (listener = this.listeners[i++])) {
				listener.trigger(event, data);
			}
		},
		
		initArtworks: function(artworks) {
			var gallery = this, intervalId, index = 0;
			
			gallery.receivedItemCount += artworks.length;
			
			if (gallery.receivedItemCount > gallery.options.maxItemCount) {
				artworks = artworks.slice(0, gallery.options.maxItemCount - gallery.receivedItemCount);
				gallery.receivedItemCount = gallery.options.maxItemCount;
			}
			
			intervalId = setInterval(function() {
				var artwork, data, model;
				
				if (index > artworks.length - 1) {
					clearInterval(intervalId);
					return;
				}
				
				data = artworks[index];
				
				if (data.url != '') {
					artwork = {
						model:null,
						data:null
					};
					
					// Crée le modèle HTML
					artwork = {
						model:gallery.createArtworkModel(),
						data:data
					}
					gallery.artworks.push(artwork);
					
					model = artwork.model;
					model.addClass('loading');
					//gallery.artworks.models.push(artwork);
					model.find('.actionopen > *:not(.state-loading)').addClass('hidden');
					gallery.options.gallery.append(model);
					model.find('.actionclose').addClass('hidden');
					
					// Download le thumbnail
					setTimeout(function() {
						var thumbnail, url;
						thumbnail = $(new Image());
						thumbnail.error(function() {
							gallery.loadArtwork(model, data);
						});
						thumbnail.load(function() {
							gallery.loadArtwork(model, data);
						});
						
						url = 'get-image.php?url=' + data.url + '&width=180&height=120&mode=crop';
						if (gallery.options.language !== 'en') {
							url = '../get-image.php?url=' + data.url + '&width=180&height=120&mode=crop';
						}
						thumbnail.attr('src', url);
					}, 300);
				} else {
					try {
						console.log(data);
					} catch (e) {
					}
				}
				index++;
			}, 300);
			
		},
		
		initArtwork: function() {
		},
		
		loadArtwork: function(model, data) {
			var controls, loading, open, close, gallery = this, thumbnail, image, dimensions, url, gaze, gallery = this;
			
			open = model.find('.actionopen');
			close = model.find('.panel .actionclose');
			controls = model.find('.actionopen > *:not(.state-loading)');
			loading = model.find('.actionopen > .state-loading');
			
			gaze = model.find('.state-hover');
			if (!$.support.opacity) {
				gaze.css({opacity:0.8});
			}
			
			
			url = 'get-image.php?url=' + data.url + '&width=180&height=120&mode=crop';
			if (gallery.options.language !== 'en') {
				url = '../get-image.php?url=' + data.url + '&width=180&height=120&mode=crop';
			}
			
			thumbnail = model.find('.artist-thumbnail');
			image = $('<img>').attr('src', url);
			
			thumbnail.append(image);
			
			model.removeClass('loading');
			controls.removeClass('hidden');
			loading.addClass('hidden');
			
			// Gestion des événements
			open.hover(function() {
				var hover = $(this).find('.state-hover');
				hover.stop().animateToClass(".state-gallery_thumbnail_hover", 250);
			}, function() {
				var hover = $(this).find('.state-hover');
				hover.stop().animateToClass(".state-gallery_thumbnail_default", 800);
			});
			
			open.click(function() {
				gallery.artworkExpand($(this), model, data);
			});
			
			close.click(function() {
				gallery.artworkCollapse($(this), model, data);
			});
		},
		
		createArtworkModel: function() {
			return this.options.artwork.model.clone();
		},
		
		setArtworkDataModel: function(model, data) {
		},
		
		getArtworks: function(options) {
			var gallery = this;
			var defaults = {
				limit:10,
				offset:0
			};
			var options = $.extend(defaults, options), url, processResponse;
			
			if (this.options.dataProvider) {
				if (this.options.dataProvider.url) {
					url = this.options.dataProvider.url;
				}
				if (this.options.dataProvider.processResponse && typeof this.options.dataProvider.processResponse === 'function') {
					processResponse = this.options.dataProvider.processResponse;
				}
			}
			
			$.ajax({
				type:'GET',
				url:url,
				data:{
					limit:options.limit,
					offset:options.offset,
					data_type:'JSON'
				},
				dataType:'json',
				error:function(xhr, errmsg) {
					var e = new Error(errmsg);
					e.name = 'Ajax Error';
					e.xhr = xhr;
					gallery.triggerError(e);
				},
				success:function(data) {
					if (processResponse) {
						data = processResponse(gallery, data);
					}
					gallery.processArtworksResponse(data);
					//self.triggerArtworksLoaded(data);
				}
			});
		},
		processArtworksResponse: function(data) {
			var limit, offset, totalCount, event, gallery = this;
			
			gallery.initArtworks(data.response);
			
			limit = parseInt(data.request.limit);
			offset = parseInt(data.request.offset);
			totalCount = parseInt(data.request.totalCount);
			
			if ( (gallery.options.maxItemCount && gallery.receivedItemCount < gallery.options.maxItemCount) && offset + limit < totalCount) {
				this.getArtworks({
					limit:10,
					offset:parseInt(data.request.offset)+10
				});
			} else if (offset + limit >= totalCount && gallery.options.itemCount && gallery.receivedItemCount < gallery.options.itemCount) {
				// Le loading est terminé, mais le nombre total d'items est différent de celui attendu.
				// Il y a donc eu des erreurs. On reload.
				window.location.reload(true);
			}
		},
		
		triggerError: function(error) {
			var event;
			event = new $.Event('error');
			this.notifyListeners(event, error);
			
			if (!event.isDefaultPrevented()) {
				throw error;
			}
		},
		
		triggerArtworksLoaded: function(data) {
			var event;
			event = new $.Event('artworksLoaded');
			this.notifyListeners(event, data);
		},
		
		artworkExpand: function(element, model, data) {
			var open, image, loading, frame, hover, gallery = this;
			
			
			if (this.currentPanel) {
				this.artworkCollapse(this.currentPanel.find('.actionclose'), this.currentPanel.parent('.artwork'));
			}
			this.currentPanel = element.parent().find('.panel');
			
			frame = model.find('.frame');
			hover = model.find('.state-hover');
			loading = model.find('.state-loading');
			
			element.animateToClass(".state-gallery_thumbnail_minimized", function() {
				element.addClass('hidden');
			});
			
			// Animer le paneau
			element.parent().find('.panel').animateToClass(".state-gallery_panel_maximized", function() {
				gallery.artworkInitDetails(model, data);
			});
			
		},
		
		artworkCollapse: function(element, model, data) {
			var open, panel, image, close;
			
			open = element.parent().parent().find('.actionopen'); 
			panel = element.parent();
			image = model.find('.artwork-image');
			close = model.find('.actionclose');
			
			open.removeClass('hidden');
			close.addClass('hidden');
			
			panel.animateToClass(".state-gallery_panel_minimized", function() {
				image.html('');
			});
			open.animateToClass(".state-gallery_thumbnail_maximized", function() {
				$(this).css('opacity', '')
			});
		},
		
		artworkInitDetails: function(model, data) {
			var image, gallery = this, close, image, url, language;
			
			close = model.find('.actionclose');
			close.removeClass('hidden');
			
			gallery.artworkLoadDetails(model, data);
			
			language = gallery.options.language;
			
			image = model.find('.artwork-image');
			url = "_images/loading.gif";
			if (language !== 'en') {
				url = '../' + url;
			}
			image.html($(new Image()).attr('src', url));
			
			
			image = $(new Image());
			image.error(function() {
				gallery.artworkLoadImage(model, data);
			});
			image.load(function() {
				gallery.artworkLoadImage(model, data);
			});
			url = 'get-image.php?url=' + data.url + '&width=640&height=422&mode=scale';
			if (language !== 'en') {
				url = '../' + url;
			}
			image.attr('src', url);
		},
		
		trim: function(str) {
			if (str === null) {
				return '';
			}
			if (typeof str !== 'string') {
				str = '' + str;
			}
			
			return str.replace(/^\s+/g,'').replace(/\s+$/g,'');
			
		},
		
		artworkLoadDetails: function(model, data) {
			var title, medium, size, description, cv, statement, mailto, url, artist, keys, language, mailtoURL, k, downloadGroup;
			
			language = this.options.language;
			
			artist = model.find('.artist-name');
			title = model.find('.artwork-title');
			medium = model.find('.artwork-medium');
			size = model.find('.artwork-size');
			description = model.find('.artist-description');
			cv = model.find('.artist-curriculum-vitae');
			statement = model.find('.artist-statement');
			mailto = model.find('.artist-mailto');
			url = model.find('.artist-url');
			downloadGroup = model.find('.download-group');
			
			keys = {
				title:'title',
				medium:'medium',
				size:'size',
				description:'description'
			};
			
			mailtoURL = 'mailto:quote@arteria.com?subject=Quote Request&body=' + escape('Artist : ' + data.artist.firstName + ' ' + data.artist.lastName + '\nArtwork : ' + data[keys.title]);
			if (language === 'fr') {
				mailtoURL = 'mailto:quote@arteria.com?subject=Demande de devis&body=' + escape('Artiste : ' + data.artist.firstName + ' ' + data.artist.lastName + '\nOeuvre : ' + data[keys.title]);
			}
			
			if (language !== 'en') {
				for (k in keys) {
					keys[k] = keys[k] + language.substr(0, 1).toUpperCase() + language.substr(1);
				}
			}
			
			artist.html(data.artist.firstName + ' ' + data.artist.lastName);
			
			title.html(data[keys.title]);
			
			if (this.trim(data[keys.medium]) !== '') {
				medium.parent().removeClass('hidden');
				medium.html(data[keys.medium]);
			} else {
				medium.parent().addClass('hidden');
			}
			
			if (this.trim(data[keys.size]) !== '') {
				size.parent().removeClass('hidden');
				size.html(data[keys.size]);
			} else {
				size.parent().addClass('hidden');
			}
			
			if (this.trim(data[keys.description]) !== '') {
				description.parent().removeClass('hidden');
				description.html(data[keys.description]);
			} else {
				description.parent().addClass('hidden');
			}
			
			if (language == 'fr') {
				if (data.artist.urlCurriculumVitaeDocFr) {
					cv.removeClass('hidden');
					cv.wrapInner($('<a>').attr('href', '../'+data.artist.urlCurriculumVitaeDocFr));
				} else {
					cv.addClass('hidden');
				}
				if (data.artist.urlStatementDocFr) {
					statement.removeClass('hidden');
					statement.wrapInner($('<a>').attr('href', '../'+data.artist.urlStatementDocFr));
				} else {
					statement.addClass('hidden');
				}
				
				if (!data.artist.urlStatementDocFr && !data.artist.urlCurriculumVitaeDocFr) {
					downloadGroup.addClass('hidden');
				} else {
					downloadGroup.removeClass('hidden');
				}
			} else {
				if (data.artist.urlCurriculumVitaeDoc) {
					cv.removeClass('hidden');
					cv.wrapInner($('<a>').attr('href', data.artist.urlCurriculumVitaeDoc));
				} else {
					cv.addClass('hidden');
				}
				if (data.artist.urlStatementDoc) {
					statement.removeClass('hidden');
					statement.wrapInner($('<a>').attr('href', data.artist.urlStatementDoc));
				} else {
					statement.addClass('hidden');
				}
				
				if (!data.artist.urlStatementDoc && !data.artist.urlCurriculumVitaeDoc) {
					downloadGroup.addClass('hidden');
				} else {
					downloadGroup.removeClass('hidden');
				}
			}
			
			mailto.attr('href', mailtoURL);
			url.attr('href', 'artist.php?artist_id='+data.artist.id);
		},
		
		artworkLoadImage: function(model, data) {
			var image, imageElem, dim, url, language, gallery = this;
			
			language = gallery.options.language;
			
			image = model.find('.artwork-image');
					
			url = 'get-image.php?url=' + data.url + '&width=640&height=422&mode=scale';
			if (language !== 'en') {	
				url = '../' + url;
			}
			
			imageElem = $(new Image()).attr('src', url);
			
			//dim = this.calcResizedImageDimensions(data, 640, 422, 'SCALE_TO_FIT');
			//imageElem.width(dim.width);
			//imageElem.height(dim.height);
			
			image.html(imageElem);
			
		},
		
		updateArtistInfo: function(model, data) {
			var cv, statement, artist, separator, keys, k, language;
			
			language = this.options.language;
			
			artist = model.find('.name');
			statement = model.find('.statement');
			cv = model.find('.curriculum-vitae');
			separator = model.find('.separator');
			
			artist.html(data.firstName + ' ' + data.lastName);
			
			if (language == 'fr') {
				if (data.urlCurriculumVitaeDocFr) {
					cv.removeClass('hidden');
					cv.attr('href', '../'+data.urlCurriculumVitaeDocFr);
				} else {
					cv.addClass('hidden');
				}
			
				if (data.urlStatementDocFr) {
					statement.removeClass('hidden');
					statement.attr('href', '../'+data.urlStatementDocFr);
				} else {
					statement.addClass('hidden');
				}
				
				if (data.urlStatementDocFr && data.urlCurriculumVitaeDocFr) {
					separator.removeClass('hidden');
				} else {
					separator.addClass('hidden');
				}
			} else {
				if (data.urlCurriculumVitaeDoc) {
					cv.removeClass('hidden');
					cv.attr('href', data.urlCurriculumVitaeDoc);
				} else {
					cv.addClass('hidden');
				}
				
				if (data.urlStatementDoc) {
					statement.removeClass('hidden');
					statement.attr('href', data.urlStatementDoc);
				} else {
					statement.addClass('hidden');
				}
				
				if (data.urlStatementDoc && data.urlCurriculumVitaeDoc) {
					separator.removeClass('hidden');
				} else {
					separator.addClass('hidden');
				}
			}
		}
	};
})(jQuery);

