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

define(
    [
	"aconf/dom",
	"aconf/widget/abstract/node",
	"jquery",
	"underscore",
	"aconf/widget/audio",
	"aconf/widget/checkbox",
	"aconf/widget/checkboxes",
	"aconf/widget/combobox",
	"aconf/widget/date",
	"aconf/widget/field",
	"aconf/widget/inline",
	"aconf/widget/reference"
    ],
    function(dom, Base, $, _) {
	return Base.extend({
	    render: function(data, meta) {
		Base.render.call(this, data, meta);

		this.reqData = data;
		var self = this;

		if (meta.type == "model") {
		    _.each(meta.actions, function(action) {
			self.addActionButton(action["ui-name"], function() {
			    data.invoke(action.name)
				.done(function() { alert("Done"); })
				.fail(function() { alert("Failed"); });
			});
		    });

		    this.createModelWidgets(
			_.filter(meta.fields, function(field) {
			    return field.visible;
			}),
			true
		    );

		    var labels = _.object(_.map(meta.fields, function(field) {
			return [field.name, field["ui-name"]];
		    }));

		    _.each(this.widgets, function(f1, name) {
			self.setupWidget(f1, labels[name]);

			f1.on("validated", function(event) {
			    event.stopPropagation();
			});

			_.each(self.widgets, function(f2) {
			    if (f1 != f2)
				f1.on("validated", function(event) {
				    f2.trigger("updated", [name]);
				});
			});
		    });

		    _.each(this.widgets, function(widget) {
			widget.trigger("start");
		    });
		}

		else _.each(data.data, function(value, name) {
		    if (meta.type == "set") name = data.data[name];
		    else if (_.isArray(data.data)) name++;
		    self.renderCollectionMember(name, meta);
		});
	    },

	    createModelWidgets: function(fields, editable) {
		this.widgets = {};
		var self = this;
		_.each(fields, function(field) {
		    var widget = self.createWidget(
			field.name, field, editable, false
		    );
		    if (widget) self.widgets[field.name] = widget;
		});
	    },

	    createWidget: function(name, meta, editable, removable) {
		var widget = this.widget(meta);
		if (widget)
		    return widget.new(
			this.reqData,
			name,
			meta,
			this.level,
			editable,
			removable
		    );
	    },

	    setupWidget: function(widget, label) {
		var container = this.appendWidget(widget, label);
		widget.on("setVisible", function(event, visible) {
		    dom.setVisible(container, visible);
		    event.stopPropagation();
		});
	    },

	    renderCollectionMember: function(name, meta) {
		var set = meta.type == "set";
		var widget = this.createWidget(
		    name,
		    meta.members,
		    !set,
		    _.contains(meta.removable, name)
		);
		this.setupWidget(
		    widget, set ? null : meta["ui-member"] + " " + name
		);
		widget.trigger("start");
		return widget;
	    },

	    widget: function(meta) {
		return require("aconf/widget/" + meta.widget);
	    },

	    validate: function(data) {
		Base.validate.call(this, data);

		if (this.widgets)
		    _.each(this.widgets, function(widget) {
			widget.trigger("updated");
		    });
	    }
	});
    }
);
