var AjaxForm = Class.create({
	initialize: function(form, options)
	{
		options = options || {};
		form = $(form);
		if (form)
		{
			this.form = form;
			this.form.observe("submit", this.submit.bindAsEventListener(this));
		}
		
		if (options.success && Object.isFunction(options.success))
		{
			this.onSuccess = options.success;
		}
	},
	
	submit: function(e)
	{
		if (e)
		{
			e.stop();
			if (e.element().tagName.toLowerCase() != "form")
			{
				return;
			}
		}
		this.form.disable();
		LoadingImage.open({type: "M"});
		this.parameters = { };
		var url = this.form.getAttribute("action");
		var formElements = this.form.getElements();
		
		for (var i = 0; i < formElements.size(); i++)
		{
			if (formElements[i].getAttribute('name'))
			{
				var param = new Hash();
				param.set(formElements[i].getAttribute('name'), $F(formElements[i]));
				this.parameters = Object.extend(this.parameters, param.toObject());
			}
		}
		
		new Ajax.Request(url, { method: "post", parameters: this.parameters, onSuccess: this.success.bind(this), onFailed: this.failed.bind(this), onComplete: this.complete.bind(this) } );
	},
	
	complete: function()
	{
		this.form.enable();
		LoadingImage.close();
	},
	
	success: function(transport)
	{
		updater(transport);
		var data = transport.responseJSON;
		if (data)
		{
			if (Object.isFunction(this.onSuccess) && !data.error)
			{
				this.onSuccess(data);
			}
		}
	},
	
	failed: function()
	{
		
	}
});

var updater = function(transport) 
{
	var data = transport.responseJSON;
	if (data)
	{
		var message = "";
		if (data.elements)
		{
			for (var i = 0; i < data.elements.length; i++)
			{
				if (data.elements[i].id)
				{
					/* There is an id...*/
					el = $(data.elements[i].id);
					if (!el)
					{
						/* The id does not link to an element... */
						if (data.elements[i].tag && data.elements[i].parent)
						{
							try
							{
								parent = $(data.elements[i].parent);
								el = new Element(data.elements[i].tag, {"id": data.elements[i].id});
							
								if (parent && el)
								{
									Element.insert(parent, el);
								}
							}
							catch (e)
							{
								window.location = window.location;
							}
						}
					}
					
					if (el)
					{
						if (data.elements[i].attributes)
						{
							for (var j = 0; j < data.elements[i].attributes.length; j++)
							{
								for (var attr in data.elements[i].attributes[j])
								{
									el.setAttribute(attr, data.elements[i].attributes[j][attr]);
								}
							}
						}
						if (data.elements[i].classes)
						{
							for (var j = 0; j < data.elements[i].classes.length; j++)
							{
								el.addClassName(data.elements[i].classes[j]);
							}
						}
						if (data.elements[i].rclasses)
						{
							for (var j = 0; j < data.elements[i].rclasses.length; j++)
							{
								el.removeClassName(data.elements[i].classes[j]);
							}
						}
						if (data.elements[i].style)
						{
							el.setStyle(data.elements[i].style);
						}
						if (data.elements[i].content)
						{
							el.update(data.elements[i].content);
						}
					}
				}
			}
		}
		if (data.script)
		{
			eval(data.script);
		}
		if (data.message)
		{
			alert(data.message);
		}
		if (!data.error)
		{
			if (data.location)
			{
				window.location = data.location;
			}
		}
	}
};

var MultiAdd = Class.create({
	initialize: function (form, parent, name, values)
	{
		form = $(form);
		parent = $(parent);
		if (form && parent)
		{
			this.form = form;
			this.parent = parent;
			
			this.text = new Element("input", {"type": "text", "id": name + "_text"});
			this.button = new Element("input", {"type": "button", "id": name + "_add"});
			this.button.setAttribute("value", "Add");
			this.list = new Element("ul", {"id": name + "_list"});
			
			this.parent.insert(this.text);
			this.parent.insert(this.button);
			this.parent.insert(this.list);
			
			this.name = name;
			this.input = new Element("input", {"type": "hidden", "name": this.name});
			this.form.insert(this.input);
		}
		else
		{
			return;
		}
		this.handlers = {click: this.add.bindAsEventListener(this),
				keyup: this.keyup.bindAsEventListener(this),
				keydown: this.keydown.bindAsEventListener(this),
				keypress: this.keypress.bindAsEventListener(this)};
		this.button.observe("click", this.handlers.click);
		this.text.observe("keyup", this.handlers.keyup);
		this.text.observe("keydown", this.handlers.keydown);
		this.text.observe("keypress", this.handlers.keypress);
		this.values = [];
		if (values)
		{
			this.addValue(values);
			this.update();
		}
	},
	
	add: function (e)
	{
		e.stop();
		var value = new String($F(this.text));
		if (value.blank())
		{
			alert("You must enter something.");
			this.text.focus();
		}
		else
		{
			if (!this.values.find(function(v) { return (v.toLowerCase() == value.toLowerCase()); }))
			{
				this.addValue(value);
				this.text.clear();
				this.update();
			}
			else
			{
				alert("You already entered that value.");
			}
		}
	},
	
	addValue: function(values)
	{
		var arr = values.split(",");
		if (arr)
		{
			for (var i = 0; i < arr.length; i++)
			{
				var value = arr[i];
				if (value.blank())
					continue;
				if (!this.values.find(function(v) { return (v.toLowerCase() == value.toLowerCase()); }))
				{
					var count = this.values.length;
					this.values.push(value.toUpperCase());
					var li = new Element("li");
					li.update(value.toUpperCase() + " <img src=\"../images/x.jpg\" id=\"" + this.name + "_" + count + "\" />");
					this.list.insert(li);
					if (!this.handlers["click" + count])
						this.handlers["click" + count] = this.remove.bindAsEventListener(this, count);
					$(this.name + "_" + count).observe("click", this.handlers["click" + count]);
				}
			}
		}
	},
	
	setValue: function(values)
	{
		var arr = values.split(",");
		if (arr)
		{
			this.removeAll();
			for (var i = 0; i < arr.length; i++)
			{
				var value = arr[i];
				if (value.blank())
					continue;
				if (!this.values.find(function(v) { return (v.toLowerCase() == value.toLowerCase()); }))
				{
					var count = this.values.length;
					this.values.push(value.toUpperCase());
					var li = new Element("li");
					li.update(value.toUpperCase() + " <img src=\"../images/x.jpg\" id=\"" + this.name + "_" + count + "\" />");
					this.list.insert(li);
					if (!this.handlers["click" + count])
						this.handlers["click" + count] = this.remove.bindAsEventListener(this, count);
					$(this.name + "_" + count).observe("click", this.handlers["click" + count]);
				}
			}
			this.update();
		}
	},
	
	keydown: function(e)
	{
		if (e.keyCode == Event.KEY_RETURN)
		{
			e.stop();
			//this.add(e);
		}
	},
	
	keyup: function(e)
	{
		if (e.keyCode == Event.KEY_RETURN)
		{
			this.add(e);
		}
	},
	
	keypress: function(e)
	{
		if (e.keyCode == Event.KEY_RETURN)
		{
			e.stop();
		}
	},
	
	remove: function(e, count)
	{
		e.stop();
		if (e.element())
		{
			var parent = e.element().ancestors()[0];
			parent.remove();
			var value = this.values[count];
			this.values = this.values.reject(function(v) { return value == v; });
			
			var length = this.values.length;
			var j = 0;
			for (var i = 0; i < length; i++)
			{
				while (!$(this.name + "_" + j))
				{
					if (j > length)
						return;
					j++;
				}
				var el = $(this.name + "_" + j);
				el.setAttribute("id", this.name + "_" + i);
				el.stopObserving("click", this.handlers["click" + j]);
				el.observe("click", this.handlers["click" + i]);
				j++;
			}
			this.update();
		}
	},
	
	removeAll: function()
	{
		var length = this.values.length;
		for (var i = 0, j = 0; i < length; i++, j++)
		{
			var el = $(this.name + "_" + j);
			while (!el)
			{
				j++;
				el = $(this.name + "_" + j);
			}
			el.stopObserving("click", this.handlers["click" + j]);
			var parent = el.ancestors()[0];
			parent.remove();
		}
		this.values = [];
		this.update();
	},
	
	update: function()
	{
		if (this.input)
		{
			this.input.clear();
			var i = 0;
			for (i = 0; i < this.values.length; i++)
			{
				if (i > 0)
					this.input.value += ",";
				this.input.value += this.values[i];
			}
		}
	}
});

var AjaxImageUpload = Class.create({
	initialize: function(form, input, dest)
	{
		form = $(form);
		input = $(input);
		dest = $(dest);
		
		if (form && input && dest)
		{
			this.form = form;
			this.input = input;
			this.dest = dest;
			
			this.input.observe("change", this.change.bindAsEventListener(this));
		}
	},
	
	change: function(e)
	{
		e.stop();
		this.submit();
	},
	
	submit: function()
	{
		LoadingImage.open({type: "S", element: this.dest});
		if (!this.frame)
		{
			var iframe = new Element("iframe", {"id": this.form.id + "_frame", "name": this.form.id + "_frame"});
			iframe.hide();
			this.form.ancestors()[0].insert(iframe);
			//window.frames[this.form.id + "_frame"].name = this.form.id + "_frame";
			this.frame = iframe;
			this.frame.observe("load", this.success.bind(this));
		}
		this.form.setAttribute("target", this.form.id + "_frame");
		this.form.submit();
	},
	
	success: function()
	{
		var oDoc = this.frame.contentWindow || this.frame.contentDocument;
		if (oDoc.document)
		{
			oDoc = oDoc.document;
		}
		
		var data = oDoc.body.innerHTML.evalJSON();
		if (data.img)
		{
			var im = new Image();
			im.onload = function() { this.dest.setAttribute("src", data.img); }.bind(this);
			im.src = data.img;
			//this.dest.setAttribute("src", data.img);
		}
		if (data.message)
		{
			alert(data.message);
		}
		
		// Simulate an AJAX response.
		var transport = {responseJSON: data};
		updater(transport);
		
		LoadingImage.close();
	}
});

var AjaxButton = Class.create(
{
	initialize: function(btn, url, options)
	{
		this.options = options || {};
		btn = $(btn);
		if (btn)
		{
			this.url = url;
			this.button = btn;
			
			this.button.observe("click", this.click.bindAsEventListener(this));
		}
	},
	
	click: function(e)
	{
		if (e)
		{
			e.stop();
		}
		new Ajax.Request(this.url, {onSuccess: this.success.bind(this), onFailure: this.fail.bind(this)});
	},
	
	success: function(transport)
	{
		updater(transport);
		var data = transport.responseJSON;
		if (data)
		{
			if (Object.isFunction(this.options.success) && !data.error)
			{
				this.options.success(data);
			}
		}
	},
	
	fail: function()
	{
		alert("Unable to communicate with the server.");
	}
});
