{
	xtype: "container",

	layout: "fit",

	xpd: "",
	widgetConfig: null,
	propertyKey: "",
	dataParent: null,
	xpdField: null,
	value: "",
	padding: 20,
	parentRecord: null,
	parentField: null,

	onInitialize: function(i_widget, i_owner) {

		var o_config = i_owner._config;
		var i_dataParent = i_owner.dataParent;
		var s_propertyKey = o_config.propertyKey;

		// Find the parent field and record if present
		var i_parentField = i_dataParent.getForm().findField(s_propertyKey) || null;
		var i_parentRecord = i_dataParent.getRecord() || null;

		Ext.apply(i_widget, {
			xpd: o_config.xpd,
			widgetConfig: o_config,
			propertyKey: s_propertyKey,
			dataParent: i_dataParent,
			parentRecord: i_parentRecord,
			parentField: i_parentField,
			value: i_owner.value
		});

		i_widget.initValue();

		i_widget.initXpdField();

		// Get value and reset originalvalue for parentField
		var s_value = i_widget.xpdField.getValue();
		i_widget.parentField.suspendCheckChange++;
		i_widget.parentField.setValue(s_value);
		i_widget.parentField.resetOriginalValue();
		i_widget.parentField.suspendCheckChange--;

		i_widget.initEvents();
	},

	initValue: function () {

		var i_widget = this;
		var o_value = i_widget.value || i_widget.parentField.getValue();
		var s_key = i_widget.propertyKey;
		var s_value = ip2.JSON.stringify(o_value, true);

		// Are we creating a new
		if ( i_widget.dataParent.action == "new" || i_widget.dataParent.action == "create" ) {
			i_widget.parentField.suspendCheckChange++;
			i_widget.parentField.setValue(s_value);
			i_widget.parentField.resetOriginalValue();
			i_widget.parentField.suspendCheckChange--;
		}
		// We are not - look for data in dataParent
		else {

			var i_field = i_widget.parentField;
			var i_record = i_widget.parentRecord;

			var s_fieldValue = i_field ? i_field.getValue() : "";
			var s_recordValue = i_record ? i_record.get(s_key) : "";

			if ( s_fieldValue ) {
				s_value = s_fieldValue;
			}
			else if ( !s_fieldValue && s_recordValue ) {
				s_value = s_recordValue;
			}
		}

		i_widget.value = s_value;
	},
	initXpdField: function () {

		var i_widget = this;
		var o_config = i_widget.widgetConfig;
		var s_value = i_widget.value;

		i_widget.xpdField = i_widget.add({
			xtype: "xpdfield",
			name: i_widget.propertyKey + ip2.unique(),
			itemId: o_config.name,
			xpd: o_config.xpd,
			isFormField: false,
			dataParent: i_widget.dataParent,
			value: s_value,
			flex: 1
		});

		/*
			s_value = i_widget.xpdField.getValue();
			i_widget.setParentValue(s_value);
		*/
	},

	getXpdField: function () {

		var i_widget = this;

		return i_widget.xpdField;
	},

	initEvents: function () {

		var i_widget = this;

		i_widget.xpdField.on({
			change: {
				fn: function(i_field, s_value) {
					if (i_field.suspendCheckChange) {
						return false;
					}
					var i_parent = i_widget.parentField;

					if ( !i_field._preventSync ) {
						i_parent._preventSync = true;
						i_widget.setParentValue(s_value);
						i_parent._preventSync = false;
					}
				}
			},
			reset: {
				fn:  function(i_field) {
					var i_parent = i_widget.parentField;
					i_parent.resetOriginalValue();
					i_parent._preventSync = true;
					i_parent.fireEvent("change", i_parent);
					i_parent._preventSync = false;

				}
			}
		})

		// Update the xpdField on parentField
		i_widget.parentField.on("change", function (i_parent, s_parentValue) {

			var i_field = i_widget.xpdField;

			if ( !i_parent._preventSync ) {
				i_field._preventSync = true;
				i_field.setValue(s_parentValue);
				i_field._preventSync = false;
			}
		});

		i_widget.parentField.getErrors = (function(f_old) {
			return function(value) {
				var i_field = i_widget.xpdField;
				var f_validator = i_field.getErrors;
				value = i_field.getValue();
				var a_errors = f_old.apply(this, [value]) || [];

				var a_result = f_validator.call(i_field, value) || [];

				if (a_result.length > 0) {
					a_errors = a_errors.concat(a_result);
				}
				return a_errors;
			};
		})(i_widget.parentField.getErrors);
	},

	getParentValue: function () {

		var i_widget = this;
		var i_field = i_widget.parentField;
		var s_key = i_widget.propertyKey;
		var s_value = "";

		var s_fieldValue = i_field ? i_field.getValue() : "";

		// Get the value - field value is > record value
		return s_fieldValue;
	},
	setParentValue: function (s_value) {

		var i_widget = this;
		var i_parentField = i_widget.parentField;
		var s_key = i_widget.propertyKey;

		if ( i_parentField ) {
			i_parentField.setValue(s_value);
		}

		return i_widget;
	},

	isValid: function () {

		var i_field = this.xpdField;

		return i_field ? i_field.isValid() : true;
	},
	isDirty: function() {

		var i_field = this.xpdField;

		return i_field ? i_field.isDirty() : true;
	},

	doSave: function (f_callback) {

		var i_widget = this;
		var i_xpdField = i_widget.getXpdField();

		if (i_xpdField.doSave) {
			i_xpdField.doSave(function(){
				i_xpdField.resetOriginalValue();

				f_callback && f_callback();
			});
		}
		else {
			i_xpdField.resetOriginalValue();

			f_callback && f_callback();
		}


	}
}
