/*
 * Copyright (c) 2012-2015 Kaarle Ritvanen
 * See LICENSE file for license details
 */

define(
    [
	"aconf/dom",
	"aconf/statusbar",
	"aconf/type",
	"aconf/widget/abstract/fields",
	"jquery",
	"underscore",
	"jquery-ui/sortable"
    ],
    function(dom, statusBar, type, Base, $, _) {
	return Base.extend({
	    wrap: function() { return $("<div>").html(this.el); },
	    
	    render: function(data, meta) {
		this.div = $("<div>");

		Base.render.call(this, data, meta);

		this.el.append(this.div);	

		if (meta.editable && type.isCollection(meta)) {
		    if (!this.table) this.makeSortable(this.div);

		    var self = this;

		    var button = dom.button("Insert", function() {
			
			var getter, row;

			function insert() {
			    var name = getter();
			    var set = meta.type == "set";

			    if (set ? _.contains(data.data, name) :
				name in data.data) {

				statusBar.setError(
				    "Already exists: " + name, "txn"
				);
				return;
			    }

			    function render(txnValid) {
				statusBar.validationReady(txnValid);
				if (row) row.remove();
				return self.renderCollectionMember(name, meta);
			    }

			    var task;
			    if (type.isTreeNode(meta.members))
				task = data.set(name, {});
			    else if (set) task = data.add(name);

			    if (task)
				task.done(function(txnValid) {
				    render(txnValid);
				    button.show();
				}).fail(function(xhr) {
				    statusBar.setError(
					self.formatValidationError(xhr), "txn"
				    );
				    data.delete(name);
				});

			    else data.set(name, null).always(function() {
				var widget = render(false);
				function handler(event) {
				    button.show();
				    widget.off("validated", handler);
				}
				widget.on("validated", handler);
			    });
			}

			button.hide();
			
			if (meta.type == "list") {
			    getter = function() {
				return data.data.length + 1;
			    };
			    insert();
			}
			else {
			    var field = $("<input>").attr({type: "text"})
				.change(insert);
			    row = $("<tr>").html($("<td>").html(field));
			    getter = function() { return field.val(); }
			    self.appendRow(row);
			    field.focus();
			}
		    });
		    this.el.append($("<p>").html(button));
		}
	    },

	    addActionButton: function(label, action) {
		this.div.append(dom.button(label, action));
	    },

	    appendWidget: function(el, label) {
		var self = this;
		var description = el.data("description");

		var labelTd = label ? $("<td>").text(label) : null;
		if (labelTd)
		    el.on("hasDetails", function(event, path) {
			labelTd.html(dom.objectRef(path).text(label));
			el.on("statusChanged", function(event, status) {
			    dom.setStatus(labelTd, status);
			    event.stopPropagation();			
			});
			event.stopPropagation();
		    });
		function prependLabel(el) { if (labelTd) el.prepend(labelTd); }

		el = dom.makeRow(el);

		if (el.is("tr")) {
		    prependLabel(el);
		    if (description) el.append($("<td>").text(description));
		    this.appendRow(el);
		}
		else {
		    if (el.is("table")) {
			this.makeSortable(el.find("tbody"));
			var tr;
			el.find("tr").each(function(index, row) {
			    tr = $(row);
			    tr.prepend($("<td>"));
			});
			tr.children().first().remove();
			prependLabel(tr);
			this.table = el;
		    }
		    else this.table = null;
		    this.div.append(el);
		}

		return el;
	    },

	    appendRow: function(row) {
		if (!this.table) {
		    this.table = this.makeSortable($("<tbody>"));
		    this.div.append($("<table>").html(this.table));
		}
		this.table.append(row);
	    },

	    makeSortable: function(el) {
		var data = this.reqData;

		if (data.meta.type == "list" && data.meta.editable)
		    el.sortable({
			start: function(event, ui) {
			    $(":focus").change();
			    ui.item.data("index", ui.item.index());
			},
			stop: function(event, ui) {
			    if (!data.isSubtreeValid()) {
				el.sortable("cancel");
				return;
			    }

			    var oldIndex = ui.item.data("index") + 1;
			    var newIndex = ui.item.index() + 1;
			    if (newIndex != oldIndex)
				data.move(oldIndex, newIndex)
				.done(function(txnValid) {
				    $("#content").trigger("reload", [txnValid]);
				});
			}
		    });
		return el;
	    }
	});
    }
);
