if(!Nibynic) {
	var Nibynic = {};
}

Nibynic.ImageSelectorInput = Class.create({
	defaultOptions: {
		moreText: "Więcej &gt;",
		lessText: "Mniej &lt;",
		extendedRows: 5,
		filterBy: false,
		filters: [],
		multiple: false
	},
	
	defaultUploaderOptions: {
		file_post_name: 'file',
		file_types: '*.jpg;*.jpeg;*.gif;*.png',
		file_types_description: 'Foty na stronę',
		upload_url: '/images/new/class:custom/flash:1',
		flash_url: '/swfupload.swf',
		file_size_limit: '20 MB',
		file_queue_limit: 0,
		button_width: 61,
		button_height: 22,
		button_text: 'Dodaj'
	},
	
	more: false,
	
	initialize: function(element, options) {
		this.element = $(element);
		
		this.options = Object.extend(Object.extend({ },this.defaultOptions), options || { });
		
		this.preview = this.element.down('.preview');
		this.imagesContainer = this.element.down('.images');
		this.imagesContainerOriginalHeight = this.imagesContainer.getHeight();
		this.imagesList = new Element('ul');
		this.imagesContainer.insert(this.imagesList);
		this.input = this.element.down('input[type="checkbox"]');
		if(this.options.multiple) {
			this.uploaderContainer = this.element.down('.uploader');
			this.initUploader();
		} else {
			this.fileInput = this.element.down('input[type="file"]');
			this.fileInput.observe('change', this.selectInput.bind(this));
		}
		this.filtersContainer = this.element.down('.filters');
		
		this.originalId = this.input.value;
		
		this.setupControls();
		this.loadImages();
		
		this.filters = [ { name: false, caption: 'Wszystkie' } ].concat(this.options.filters);
		this.renderFilters();
	},
	
	startUpload: function(event) {
		var stats = this.uploader.getStats();
		if(stats.files_queued > 0) {
			try {
				this.uploader.startUpload();
			} catch(e) {}
			event.stop();
		}
	},
	
	initUploader: function() {
		this.bindedStartUpload = this.startUpload.bind(this);
		this.element.up('form').observe('submit', this.bindedStartUpload);
		
		this.options.uploader = Object.extend(Object.extend({}, this.defaultUploaderOptions), this.options.uploader);

		this.uploaderHandlers = {
			upload_complete_handler: function(file) {
				if(this.getStats().files_queued == 0) {
					this.progressBarContainer.hide();
				} else {
					this.startUpload();
				}
			},
			upload_success_handler: function(file, data, response) {
				this.selector.input.value += this.selector.input.value ? ',' : '';
				this.selector.input.value += data;
				
				if(this.getStats().files_queued == 0) {
					this.selector.element.up('form').submit();
				}
			},
			file_dialog_start_handler: function() {
				this.selector.uploaderContainer.down('.list').update('');
				this.cancelUpload();
			},
			file_queue_error_handler: function(file, errorCode, message) {
				try {
					// Handle this error separately because we don't want to create a FileProgress element for it.
					switch (errorCode) {
						case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
							alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
							return;
						case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
							alert("The file you selected is too big.");
							this.debug("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
							return;
						case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
							alert("The file you selected is empty.  Please select another file.");
							this.debug("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
							return;
						case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
							alert("The file you choose is not an allowed file type.");
							this.debug("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
							return;
						default:
							alert("An error occurred in the upload. Try again later.");
							this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
							return;
					}
				} catch (e) {
				}
			},
			upload_error_handler: function(file, errorCode, message) {
				try {

					if (errorCode === SWFUpload.UPLOAD_ERROR.FILE_CANCELLED) {
						// Don't show cancelled error boxes
						return;
					}

					this.selector.uploaderContainer.down('.list').update('');

					switch (errorCode) {
					case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
						alert("There was a configuration error.  You will not be able to upload a resume at this time.");
						this.debug("Error Code: No backend file, File name: " + file.name + ", Message: " + message);
						return;
					case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
						alert("You may only upload 1 file.");
						this.debug("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						return;
					case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
					case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
						break;
					default:
						alert("An error occurred in the upload. Try again later.");
						this.debug("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						return;
					}

					switch (errorCode) {
					case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
						progress.setStatus("Upload Error");
						this.debug("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
						progress.setStatus("Upload Failed.");
						this.debug("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
						break;
					case SWFUpload.UPLOAD_ERROR.IO_ERROR:
						progress.setStatus("Server (IO) Error");
						this.debug("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
						progress.setStatus("Security Error");
						this.debug("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
						progress.setStatus("Upload Cancelled");
						this.debug("Error Code: Upload Cancelled, File name: " + file.name + ", Message: " + message);
						break;
					case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
						progress.setStatus("Upload Stopped");
						this.debug("Error Code: Upload Stopped, File name: " + file.name + ", Message: " + message);
						break;
					}
				} catch (ex) {
				}
			},
			file_queued_handler: function(file) {
				var li = new Element('li');
				li.update(file.name);
				this.selector.uploaderContainer.down('.list').insert(li);
			},
			upload_start_handler: function() {
				this.progressBarContainer.show();
				this.progressBar.reset();
			},
			upload_progress_handler: function(file, bytesLoaded, bytesTotal) {
				var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);

				this.progressBar.step(percent - this.progressBar.progress);
			},
			swfupload_loaded_handler: function() {
				if(!this.progressBar) {
					this.progressBarContainer = this.selector.element.down('.progressBarContainer');
					this.progressBar = new Control.ProgressBar(this.selector.element.down('.progressBar'));
				}
			}
		}
		
		this.options.uploader.button_placeholder_id = this.uploaderContainer.down('.placeholder').id;
		this.uploader = new SWFUpload(Object.extend(this.options.uploader, this.uploaderHandlers));
		this.uploader.selector = this;
	},
	
	setupControls: function() {
		this.controls = this.element.down('.controls');
		this.resetButton = this.controls.down('.reset');
		this.moreButton = this.controls.down('.more');

		this.resetButton.observe('click', this.onResetButtonClick.bind(this));
		this.moreButton.observe('click', this.onMoreButtonClick.bind(this));
	},
	
	loadImages: function() {
		new Ajax.Request(this.options.imagesUrl, {
			onSuccess: this.saveJSON.bind(this)
		});
	},
	
	saveJSON: function(transport) {
		this.images = transport.responseText.evalJSON();
		
		this.renderImages();
	},
	
	renderImages: function() {
		this.imagesList.innerHTML = '';
		
		for(i=0; i<this.images.length; i++) {
			var li = new Element('li');
			var image = new Element('img', {
				src: this.images[i].thumbnailUrl,
				id: this.element.id + '_image_' + this.images[i].id
			});
			
			li.observe('click', function(event) {
				this.select(event.findElement('img'));
			}.bind(this));
			
			this.images[i].element = li;
			this.imagesList.insert(li.insert(image));
		}
		
		if(this.input.checked) {
			this.select(this.input.value);
		}
		
		this.imagesConteinerExtendedHeight = this.getImagesContainerExtendedHeight();
	},
	
	renderFilters: function() {

		if(!this.options.filterBy || !this.filtersContainer) {
			return;
		}
		
		this.filtersContainer.update('filtr: ');
		
		for(var i=0; i<this.filters.length; i++) {
			var a = new Element('a', {
				href: '#',
				id: this.element.id + '_filter_'+this.filters[i].name
			});
			a.update(this.filters[i].caption);
			a.observe('click', function(event) {
				event.stop();
				var a = event.findElement('a')
				var filter = a.id.match(/_([a-zA-Z]+$)/)[1];

				this.filter(filter);
			}.bind(this));
			
			this.filtersContainer.insert(a);
			
			if(i < this.filters.length-1) {
				var space = new Element('span');
				space.update('&nbsp;|&nbsp;');
			
				this.filtersContainer.insert(space);
			}
		}
	},
	
	filter: function(filter) {
		if(!this.options.filterBy) {
			return;
		}

		for(var i=0; i<this.images.length; i++) {
			if((filter == 'false') || (this.images[i][this.options.filterBy] == filter)) {
				this.images[i].element.show();
			} else {
				this.images[i].element.hide();
			}
		}
	},
	
	imagesPerRow: function() {
		return Math.floor(this.imagesContainer.getWidth() / this.imagesContainer.down('li').getWidth());
	},
	
	getImagesContainerExtendedHeight: function() {
		var cols = Math.ceil(this.images.length / this.imagesPerRow());
		if(this.options.extendedRows < cols) {
			cols = this.options.extendedRows;
		}
		
		return cols * this.imagesContainer.down('li').getHeight() + 1;
	},
	
	select: function(element) {
		var id;
		var elementId;
		
		if($(element)) {
			elementId = $(element).id;
			parts = elementId.split('_');

			if(parts.length > 0) {
				id = parts[parts.length-1];
			}
		} else {
			id = element;
			elementId = this.element.id + '_image_' + id;
			
			if(!$(elementId)) {
				return false;
			}
		}
		
		if(id) {
			if(!this.options.multiple) {
				this.imagesList.select('li').invoke('removeClassName', 'selected');
			}
			
			var li = this.imagesList.down('#' + elementId).up('li');
			
			if(li.hasClassName('selected')) {
				li.removeClassName('selected');
				this.input.value = this.input.value.replace(id, '').replace(',,', ',');
			} else {
				li.addClassName('selected');
				
				if(!this.options.multiple) {
					this.selectInput('selection');
					this.input.value = id;
				} else {
					this.input.value += this.input.value ? ',' : '';
					this.input.value += id;
				}
				
				this.loadPreview();
			}
		}
	},
	
	findImage: function(id) {
		for(var i=0; i<this.images.length; i++) {
			if(this.images[i].id == id) {
				return this.images[i];
			}
		}
		
		return false;
	},
	
	loadPreview: function() {
		var ids = this.input.value.split(',');
		var style = {
			backgroundImage: [],
			backgroundPosition: [],
			backgroundRepeat: []
		}

		var width = Math.ceil(this.preview.getWidth() / ids.length / this.preview.getWidth() * 100);

		for(var i=0; i<ids.length; i++) {
			var image = this.findImage(ids[i]);
			
			if(!image) {
				continue;
			}

			left = width * i;
			
			style.backgroundImage[style.backgroundImage.length] = 'url(' + image.previewUrl + ')';
			style.backgroundPosition[style.backgroundPosition.length] = left + '% 0';
			style.backgroundRepeat[style.backgroundRepeat.length] = 'no-repeat';
		}

		style.backgroundImage = style.backgroundImage.join(',');
		style.backgroundPosition = style.backgroundPosition.join(',');
		style.backgroundRepeat = style.backgroundRepeat.join(',');
	
		this.preview.setStyle(style);
	},
	
	clearPreview: function() {
		this.preview.setStyle({ backgroundImage: 'none' });
	},
	
	onResetButtonClick: function() {
		if(this.originalId) {
			this.select(this.originalId);
			this.selectInput('selection');
		} else {
			this.clearPreview();
			this.imagesList.getElementsBySelector('li').invoke('removeClassName', 'selected');
		}
	},
	
	onMoreButtonClick: function() {
		if(this.more) {
			this.moreButton.update(this.options.moreText);
			this.imagesContainer.morph({height: this.imagesContainerOriginalHeight + 'px'});
		} else {
			this.moreButton.update(this.options.lessText);
			this.imagesContainer.morph({height: this.imagesConteinerExtendedHeight + 'px'});
		}
		
		this.more = !this.more
	},
	
	selectInput: function(type) {
		if('selection' == type) {
			this.fileInput.value = '';
			this.input.checked = 'checked';
		} else {
			this.input.checked = '';
		}
	}
});
