Modal = Class.create({
	initialize : function(options){
		this.options = {
			id:			'modal',
			overlayID:	'overlay',
			className:	'modal',
			overlay:  	true,
			width:		'auto',
		  	height: 	'auto',
		  	title:		'',
		  	overlayColor: '#000000',
		  	overlayOpacity: 0.8,
		  	effect: 'appear',
		  	effectDuration: 0.5,
		  	closeOnOverlay: true,
		  	hasCloseButton: false,
		  	vertical: 'center'
		};
		Object.extend(this.options, options);
		this.showing = false;
		var obj = this;
		Event.observe(document, "keydown", function(e){
			if(e.keyCode == Event.KEY_ESC) obj.hide();
			return obj;
		});
		Event.observe(window, "resize", function(){if($(obj.options.id)) obj.center(obj.options.vertical);});
		if(this.options.overlay){
			document.body.insert("<div id=\""+this.options.overlayID+"\" class=\"overlay\"></div>");
			$(this.options.overlayID).setStyle({
				display: 'none',
				backgroundColor: this.options.overlayColor,
				opacity: this.options.overlayOpacity
			});
			obj = this;
			if(this.options.closeOnOverlay){
				Event.observe(this.options.overlayID, "click", function(e){
					obj.hide();
					return obj;
				});
			}
		}
		document.body.insert("<div id=\""+this.options.id+"\" class=\""+this.options.className+"\"></div>",{position: 'top'});
		$(this.options.id).setStyle({
			width: this.options.width,
			height: this.options.height,
			display: 'none'
		});
		if(this.options.hasCloseButton){
			$(this.options.id).insert("<div class=\"close_modal\"><img src=\"images/close_modal.png\" alt=\"close\" id=\"close_"+this.options.id+"\"/></div>");
			$('close_'+this.options.id).observe('click', function(){obj.hide();});
		}
		delete obj;
		if(this.options.title != "") $(this.options.id).insert("<h1>"+this.options.title+"</h1>");
		$(this.options.id).insert("<div class=\"modal_contents\"></div>");
		document.fire("modal:created", {modalID: this.options.id});
		return this.center(this.options.vertical);
	},
	center : function(alignment, animated){
		if(typeof animated == undefined) animated = false;
		if(typeof alignment != undefined) this.options.vertical = alignment;
		var left_offset = document.viewport.getWidth() / 2 - $(this.options.id).getWidth() / 2;
		switch(this.options.vertical){
			case "top":
				var top_offset = 0;
			break;
			case "bottom":
				var top_offset = document.viewport.getHeight() - $(this.options.id).getHeight();
			break;
			case "center":
			default:
				var top_offset = document.viewport.getHeight() / 2 - $(this.options.id).getHeight() / 2;
			break;
		}
		document.fire("modal:centered", {modalID: this.options.id});
		if(animated){
			new Effect.Move(this.options.id,{
				mode: 'absolute',
				x: left_offset,
				y: top_offset,
				duration: this.options.effectDuration
			});
		}
		else{
			$(this.options.id).setStyle({
				left: left_offset+"px",
				top: top_offset+"px"
			});
		}
		return this;
	},
	show : function(){
		if(this.showing) return this;
		if(this.options.overlay){ 
			if(this.options.effect != "none"){
				var obj = this;
				$(this.options.overlayID).appear({duration: obj.options.effectDuration, from: 0, to: this.options.overlayOpacity, afterFinish:
					function(){	Effect.toggle(obj.options.id, obj.options.effect, {duration: obj.options.effectDuration});}
				});
			}
			else{
				$(this.options.overlayID).show();	
				$(this.options.id).show();
			}
		}
		else if(this.options.effect != "none"){
			var element_id = this.options.id;
			Effect.toggle($(this.options.id), this.options.effect, {
				asynchronous: false, 
				duration: this.options.effectDuration, 
				afterFinish: function(){
					if($$("#"+element_id+" input")[0]){
						$$("#"+element_id+" input")[0].focus();
					}
				}
			});
		}
		else{
			var element_id = this.options.id;
			 $(element_id).show();
			 if($$("#"+element_id+" input")[0]){
				$$("#"+element_id+" input")[0].focus();
			}
		}
		this.showing = true;
		document.fire("modal:showing", {modalID: this.options.id});
		return this;
	},
	hide : function(){
		if(!this.showing) return this;
		if($$("#"+this.options.id+" input")[0])
			$$("#"+this.options.id+" input")[0].blur();
		
		if(this.options.overlay){
			if(this.options.effect != "none"){
				var obj = this;
				Effect.toggle($(this.options.id), this.options.effect, {duration: obj.options.effectDuration, afterFinish: function(){
					$(obj.options.overlayID).fade({duration: obj.options.effectDuration, from: obj.options.overlayOpacity, to: 0});
				}});
			}
			else{
				$(this.options.overlayID).hide();	
				$(this.options.id).hide();
			}
		}
		else if(this.options.effect != "none") Effect.toggle($(this.options.id), this.options.effect, {duration: this.options.effectDuration});
		else $(this.options.id).hide();
		this.showing = false;
		document.fire("modal:hidden", {modalID: this.options.id});
		return this;
	},
	hideIn : function(seconds){
		var s = setTimeout("alert(this)", seconds * 1000);
		function hide_me(){
			this.hide();
		}
		document.observe("modal:hidden", function(){clearTimeout(s);});
		return this;
	},
	isShowing : function(){
		return this.showing;
	},
	toggle : function(){
		return this.showing ? this.hide() : this.show();
	},
	update : function(contents){
		var obj = this;
		$$("#"+this.options.id+" div.modal_contents")[0].update(contents);
		document.fire("modal:updated", {modalID: this.options.id});
		return this.center();
	},
	ajaxUpdate : function(url, options){
		var text = "asd";
		var ajaxOptions = {
			asynchronous: false,
			parameters: "",
			onComplete: function(t){text = t.responseText;}
		};
		Object.extend(ajaxOptions, options);
		var ajaxCall = new Ajax.Request(url,ajaxOptions);
		return this.update(text);
	},
	setTitle : function(title){
		this.options.title = title;
		if($$("#"+this.options.id+" h1").length > 0) $$("#"+this.options.id+" h1")[0].update(title);
		return this;
	},
	kill : function(){
		document.fire("modal:killed", {modalID: this.options.id});
		if(this.options.closeOnOverlay) $(this.options.overlayID).stopObserving();
		$(this.options.id).remove();
		$(this.options.overlayID).remove();
		document.stopObserving("modal:hidden");
		document.stopObserving("modal:showing");
		document.stopObserving("modal:updated");
		document.stopObserving("modal:centered");
		delete this;
	}
});

Modal.Confirm = Class.create(Modal, {
	initialize: function($super, options){
		this.options = {
			'confirmText' : '',
			'yesTitle': 'yes',
			'noTitle': 'no',
			'onYes' : function(){},
			'onNo' : function(){}
		};
		Object.extend(this.options, options);
		$super(options);
		this.update("<p id=\""+this.options.id+"_confirm_text\">"+this.options.confirmText+"</p>");
		this.center();
		return this;
	},
	update: function(content){
		if($(this.options.id+'_yes')) $(this.options.id+'_yes').stopObserving();
		if($(this.options.id+'_no')) $(this.options.id+'_no').stopObserving();
		$(this.options.id).update((this.options.title == "" ? "" : "<h1>"+this.options.title+"</h1>") + "<p id=\""+this.options.id+"_confirm_text\">"+content+"</p><div class=\"modal_controls\"> \
		<button id=\""+this.options.id+"_yes\" class=\"default\">"+this.options.yesTitle+"</button> \
		<button id=\""+this.options.id+"_no\">"+this.options.noTitle+"</button> \
		</div>");
		var obj = this;
		$(this.options.id+"_yes").observe("click", function(){
			obj.options.onYes();
			document.fire("modal:yes",{modalID: obj.options.id});
		});
		$(this.options.id+"_no").observe("click", function(){
			obj.options.onNo();
			document.fire("modal:no", {modalID: obj.options.id});
		});
		delete obj;
		return this;
	},
	setYesCallback: function(yescallback){
		this.options.onYes = yescallback;
		return this;
	},
	setNoCallback: function(nocallback){
		this.options.onNo = nocallback;
		return this;
	},
	setYesTitle: function(text){
		this.options.yesTitle = text;
		$(this.options.id+"_yes").update(text);
		return this;
	},
	setNoTitle: function(text){
		this.options.noTitle = text;
		$(this.options.id+"_no").update(text);
		return this;
	}
});

Modal.Notify = Class.create(Modal,{
	initialize: function($super, options){
		this.options = {
			notification: '',
			okText: 'OK',
			iconURL: '',
			width: '400px'
		};
		$super(options);
		Object.extend(this.options, options);
		var obj = this;
		this.update("<img src=\""+this.options.iconURL+"\" alt=\"notification_icon\" class=\"modalNotificationIcon\"/>"+
		"<p id=\'modalNotification\'>"+this.options.notification + "</p><div class=\"modal_controls\">\
		<button id=\"ok\">"+this.options.okText+"</button></div>");
		$('ok').observe('click', function(){
			obj.hide();
		});
		return this;
	},
	setIcon: function(iconSource){
		$$('#modal img.modalNotificationIcon')[0].setAttribute('src', iconSource);
		return this;
	},
	setNotification: function(notification){
		$('modalNotification').update(notification);
		return this;
	}
});

Modal.Image = Class.create(Modal, {
	initialize: function($super, options){
		this.options = {
			className: 'imageModal',
			wrapAround: false,
			imageList: $A($$('a[rel=modalImage]'))
		};
		this.imageIndex = 0;
		$super(options);
		Object.extend(this.options, options);
		this.options.imageList.each(function(n,i){
			n = n.firstChild;
		});
		if(this.options.imageList.length > 0){
			this.update("<h1>"+this.options.imageList[0].getAttribute('title')+"</h1>\
			<img src=\""+this.options.imageList[0].getAttribute('src')+"\" alt=\"\" />\
			<p>"+this.options.imageList[this.imageIndex].getAttribute('alt')+"<br />\
			Image "+(this.imageIndex+1)+"/"+this.options.imageList.length+"</p>").center();
		}
		var obj = this;
		Event.observe(document, "keydown", function(event){
			if(obj.showing){
				if(event.keyCode == Event.KEY_LEFT && obj.options.imageList.length > 0)
					return obj.prevImage();
				else if(event.keyCode == Event.KEY_RIGHT && obj.options.imageList.length > 0)
					return obj.nextImage();
			}
		});
		return this;
	},
	setImage: function(imgIndex){
		if(imgIndex < this.imageIndex){
			this.imageIndex = imgIndex;
			if(this.imageIndex < 0 && this.options.wrapAround) this.imageIndex = this.options.imageList.length-1;
			else if(this.imageIndex < 0 && !this.options.wrapAround) this.imageIndex = 0;
		}
		else if (imgIndex > this.imageIndex){
			this.imageIndex = imgIndex;
			if(this.imageIndex >= this.options.imageList.length && this.options.wrapAround) this.imageIndex = 0; 
			else if(this.imageIndex >= this.options.imageList.length && !this.options.wrapAround) this.imageIndex = this.options.imageList.length-1;
		}
		this.update("<h1>"+this.options.imageList[this.imageIndex].getAttribute('title')+"</h1>\
			<img src=\""+this.options.imageList[this.imageIndex].getAttribute('src')+"\" alt=\"\" />\
			<p>"+this.options.imageList[this.imageIndex].getAttribute('alt')+"<br />\
			Image "+(this.imageIndex+1)+"/"+this.options.imageList.length+"</p>");
		return this;
	},
	nextImage: function(){
		return this.setImage(this.imageIndex+1);
	},
	prevImage: function(){ return this.setImage(this.imageIndex-1); },
	previousImage: function(){return this.setImage(this.imageIndex-1);},
	addImage: function(img){
		this.options.imageList.push(img);
		return this;
	},
	removeImage: function(img){
		var imageListCopy = [];
		this.options.imageList.each(function(n){
			if(n.getAttribute('src') != img.getAttribute('src')) imageListCopy.push(n);
		});
		this.options.imageList = imageListCopy;
		return this;
	}
});
