﻿(function ($) {
	$.widget("ui.propertybuilder", {
		options: {},

		_increment: 0,
		_table: null,
		_indexes: null,

		_create: function () {
			var self = this;

			self.key = self.options.key;

			self.definitions = [];
			for (var i in self.options.definitions) {
				var def = self.options.definitions[i];

				if (typeof def == "string") {
					self.definitions.push({ key: def, title: def, build: null });

				} else if (typeof def == "object") {
					if (def.constructor == Array) {
						if (def.length != 2) self._throw_error("definition of type Array must have 2 items");
						self.definitions.push({ key: def[0], title: def[0], build: def[1] });
					} else {
						if (!def.key) self._throw_error("key missing from definition");
						if (!def.title) def.title = def.key;
						self.definitions.push(def);
					}
				}
			}

			var html = [];
			html.push("<table class='pb-table'>");
			html.push("<tr>");

			for (var i in self.definitions) {
				html.push("<th>");
				html.push(self.definitions[i].title);
				html.push("</th>");
			}

			// Delete column
			html.push("<th></th>");
			// Add column
			html.push("<th></th>");

			html.push("</tr>");
			html.push("</table>");

			self._table = $(html.join(''));
			self._indexes = $("<input type='hidden' name='" + self.key + "_indexes' />");
			self.element.append(self._table);
			self.element.append(self._indexes);

			self._create_row();

			if (self.options.values) {
				self.values(self.options.values);
			}
		},

		_throw_error: function (msg) {
			throw "PropertyBuilder '" + this.key + "': " + msg;
		},

		_create_row: function (values) {
			var self = this;
			var html = [];
			html.push("<tr style='display:none' class='pb-properties'>");

			var c = 0;
			var custom = {};
			var index = self._increment++;

			for (var i in self.definitions) {
				html.push("<td>");

				var def = self.definitions[i];
				var name = self.key + "." + def.key.replace(/'/g, "\'") + "." + index;
				var value;

				if (!values) {
					value = null;
				} else if (values.constructor == Array) {
					value = values.length > c - 1 && values[c] ? values[c].replace(/'/g, "\'") : null;
				} else {
					value = eval("values." + def.key.replace(/'/g, "\'"));
				}

				if (def.build && def.build.constructor == Array) {
					var list = def.build;
					html.push("<select name='");
					html.push(name);
					html.push("'>");

					for (var j in list) {
						html.push("<option");
						if (list[j] == value) html.push(" selected='true' ");
						html.push(">");
						html.push(list[j]);
						html.push("</option>");
					}

					html.push("</select>");

				} else if (typeof def.build == "function") {
					custom[c] = def.build(name, value);

				} else {
					html.push("<input type='text' name='");
					html.push(name);
					html.push("' value='");
					html.push(value);
					html.push("' />");
				}

				html.push("</td>");
				c++;
			}

			html.push("<td><button type='button' class='pb-button pb-remove'>Remove</button></td>");
			html.push("<td><button type='button' class='pb-button pb-add'>Add</button></td>");
			html.push("</tr>");

			var $tr = $(html.join(''));

			for (var i in custom) {
				$tr.children(":eq(" + i + ")").append(custom[i]);
			}

			$tr.find("button.pb-remove").click(function () {
				self._forget(index);

				$tr.fadeOut(200, function () {
					$tr.remove();

					if (self._table.find("tr.pb-properties").length == 0) {
						self._create_row();
					} else {
						self._table.find("button.pb-add:last").show();
					}
					self._table.find("tr:last td:first").children().select();
				});
			});

			self._table.find("button.pb-add").hide();

			var $new = $tr.find("button.pb-add");
			$new.click(function () {
				self._create_row();
				self._table.find("tr:last td:first").children().focus();
			});

			self._table.append($tr);
			$tr.fadeIn(300);

			self._record(index);
		},

		_record: function (index) {
			var temp = this._indexes.val().split(',');
			temp.push(index);
			this._indexes.val(temp.join(','));
		},

		_forget: function (index) {
			var temp = this._indexes.val().split(',');
			var indexes = [];
			for (var i in temp) {
				if (temp[i] != index) indexes.push(temp[i]);
			}
			this._indexes.val(indexes.join(','));
		},

		values: function (values) {
			if (!values.length) return;

			var self = this;
			self._table.find("tr.pb-properties").remove();
			self._indexes.val("");

			for (var i in values) {
				self._create_row(values[i]);
			}
		}
	});
})(jQuery);
