if(!dojo._hasResource["bepixeld.binding.Binder"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["bepixeld.binding.Binder"] = true;
dojo.provide("bepixeld.binding.Binder");
dojo.declare("bepixeld.binding.Binder", null, {
	constructor: function(args){
		dojo.mixin(this, args);
		this.originalData = this.data;
		if(this.cloned && this.data.clone){			
			this.data = this.data.clone();
		}
	},
	
	connections: {global: []},
	cloned: false,
	store: null,
	id: null,
	scope: "global",
	data: null,
	originalData: null,
	pushType: null,
	pushConverter: null,
	pullType: null,
	pullConverter: null,
	
	bind:function(propertySpec, scope){	
		this.disconnect(scope);
		for(var i=0; i < propertySpec.length; i++) {
			this.bindProperty(propertySpec[i]);
		}		
	},
	
	unbind:function(propertySpec, scope){	
		this.disconnect(scope);
		for(var i=0; i < propertySpec.length; i++) {
			var property = propertySpec[i].property;
			if(!propertySpec[i].noReset) {
				var obj = dijit.byId(property.replace(/\./g,"_"));
				if((!obj) || ((obj.declaredClass != "bepixeld.FilteringSelect") && (obj.declaredClass != "dijit.form.FilteringSelect") && (obj.declaredClass != "dijit.form.ComboBox") && (obj.declaredClass != "dijit.form.DateTextBox") && (obj.declaredClass != "dijit.form.CheckBox"))) {
					obj = dojo.byId(property.replace(/\./g,"_"));
				}
				this.transfer(
				{object: {value: ''}, property: 'value'},
				{object: obj, property: "value"});
			}		
		}		
	},	
	
	transfer: function(/*Wire||Object*/source, /*Wire||Object*/target, /*Object?*/defaultObject, /*Object?*/defaultTargetObject){
		if(!source || !target){
			return; //undefined
		}
		if(!dojox.wire.isWire(source)){
			source = dojox.wire.create(source);
		}
		if(!dojox.wire.isWire(target)){
			target = dojox.wire.create(target);
		}
		var value = source.getValue(defaultObject);
		if (dojo.isArray(value)) {
			value = value[0];
		}			
		if(!value) {
			value = (defaultTargetObject || defaultObject);
			if(!value) {
				if(target.object.declaredClass == "dijit.form.CheckBox")
					value = false;
				else
					value = "";
			}
		}		
		target.setValue(value, (defaultTargetObject || defaultObject));
	},
	
	bindProperty: function(args){
		var data = args.data || this.data;						
		var property = args.property;
		var element = args.element || property;
		var scope = args.scope || this.scope || "global";
		var store = args.store || this.store || this.data.store;
		var id = args.id || this.id || this.data.id;
		var pushType = args.pushType || this.pushType;
		var pushConverter = args.pushConverter || this.pushConverter;
		var pullType = args.pullType || this.pullType;
		var pullConverter = args.pullConverter || this.pullConverter;
		 
		var con = this.getConnections(scope);
		var obj = dijit.byId(element.replace(/\./g,"_"));
		if((!obj) || ((obj.declaredClass != "bepixeld.FilteringSelect") && (obj.declaredClass != "dijit.form.FilteringSelect") && (obj.declaredClass != "dijit.form.ComboBox") && (obj.declaredClass != "dijit.form.DateTextBox") && (obj.declaredClass != "dijit.form.CheckBox"))) {
			obj = dojo.byId(element.replace(/\./g,"_"));
		}
		var self = this;
		this.transfer(
			{object: data, property: property, type: pushType, converter: pushConverter},
			{object: obj, property: "value"});
		if((obj.declaredClass == "dijit.form.CheckBox") && !pullConverter) {
			pullConverter = {convert: function(value){
				if (value){
					return true;
				}
				return false;
			}};
		}
		obj.customData = { data:data, property:property, element:element, scope:scope, store:store, id:id, pushType:pushType, pullType:pullType, pushConverter:pushConverter, pullConverter:pullConverter };
		if(obj.onChange) {		
			if(store) {		
				con.push(dojo.connect(obj, "onBlur", function(evt){
					var v = this.customData;
					self.transfer(
					{object: this, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
				con.push(dojo.connect(obj, "onChange", function(evt){
					var v = this.customData;
					self.transfer(
					{object: this, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
			}
			else {			
				con.push(dojo.connect(obj, "onBlur", function(evt){
					var v = this.customData;
					self.transfer(
					{object: this, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
				con.push(dojo.connect(obj, "onChange", function(evt){
					var v = this.customData;
					self.transfer(
					{object: this, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
			}
		}  else {
			if(store) {		
				con.push(dojo.connect(obj, "onblur", function(evt){				
					var v = evt.target.customData;
					self.transfer(
					{object: evt.target, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
				con.push(dojo.connect(obj, "onchange", function(evt){				
					var v = evt.target.customData;
					self.transfer(
					{object: evt.target, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
			}
			else {			
				con.push(dojo.connect(obj, "onblur", function(evt){
					var v = evt.target.customData;
					self.transfer(
					{object: evt.target, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
				con.push(dojo.connect(obj, "onchange", function(evt){
					var v = evt.target.customData;
					self.transfer(
					{object: evt.target, property: "value", type: v.pullType, converter: v.pullConverter},
					{object: v.data, property: v.property});
					self.setProperty(v.data, "modified", true);
				}));
			}
		}
	},
	
	transferToStore: function(){
		var store = this.originalData.store || this.data.store;
		if(store) {
			var attr = store.getAttributes(this.originalData.getStoreItem());
			for(var i = 0; i < attr.length; i++){
				var property = attr[i];
				if(typeof this.data.get(property) != "undefined") {
					store.setValue(this.originalData.getStoreItem(), property, this.data.get(property));
				}
			}
		}
	},
	
	setProperty: function(obj, property, value) {
		if (typeof value.length === "undefined") {
			value = [value];
		}
		if(obj.setPropertyValue){
			obj.setPropertyValue(property, value);
		} else if(obj["set" + property.charAt(0).toUpperCase() + property.substring(1)]) {
			obj["set" + property.charAt(0).toUpperCase() + property.substring(1)](value);
		} else if (obj[property] !== undefined){
			obj[property] = value;
		}
	},
	
	getProperty: function(obj, property, value) {
		if(obj.getPropertyValue){
			return obj.getPropertyValue(property);
		} else if(obj["get" + property.charAt(0).toUpperCase() + property.substring(1)]) {
			return obj["get" + property.charAt(0).toUpperCase() + property.substring(1)]();
		} else if (obj[property] !== undefined){
			return obj[property];
		}
	},		

	disconnect: function(scope){
		var con = this.getConnections(scope);
		for(var i = 0; i < con.length; i++){
			dojox.wire.disconnect(con[i]);
		}
		this.clearConnections(scope);
	},
	
	getConnections: function(scope){
		if(!scope) {
			scope = "global";
		}
		var con = this.connections[scope];
		if(!con) {
			con = [];
			this.connections[scope] = con;
		}		
		return con;
	},
	
	clearConnections: function(scope){
		if(!scope) {
			scope = "global";
		}
		if(this.connections[scope]) {
			this.connections[scope] = [];
		}		
	}		
});

}
