define([
    "dojo/_base/declare",
	"dojox/validate/web",
	"dijit/registry"
], function(declare,validateWeb,reg){
	return declare("chy._base._ValidateMixin", null, {
		
		scrollOnFocus:false,
		
		chyValidateStr: '',
		validateType: '',
		validateParts: [],
		formId: '',
		unique: false,
					
		//constructor
		constructor: function(args){
			declare.safeMixin(this,args);
			this.validateParts = this.chyValidateStr.split('|');
			this.validateType = this.validateParts[0];
			//init validator types
			switch(this.validateType){
				case 'regexp':
					var regexStr = this.chyValidateStr.substring(this.chyValidateStr.indexOf('|')+1,this.chyValidateStr.length);
					regexStr = regexStr.substring(0,regexStr.lastIndexOf('|'));
					regexStr = regexStr.replace(/#/g,'|');//unescape # to |
					this.validateErrorMsg = this.chyValidateStr.substring(this.chyValidateStr.lastIndexOf('|')+1,this.chyValidateStr.length);
					//strip ;require added by ?! to validate string
					this.validateErrorMsg = this.validateErrorMsg.split(';')[0];
					this.compiledRegexp = new RegExp(regexStr, '');
					break;
				case 'email':
					this.validator = validateWeb.isEmailAddress;
					break;
				case 'maxlength':
					this.set('maxLength',parseInt(this.validateParts[1]));
					break;
				case 'length':
					this.set('minLength',parseInt(this.validateParts[1]));
					this.set('maxLength',parseInt(this.validateParts[2]));
					break;
				case 'numrange':
					this.validator = validateWeb.isInRange;
					var rangeParts = this.validateParts[1].split('-');
					this.constriants = {
						min: parseInt(rangeParts[0]),
						max: parseInt(rangeParts[1])				
					}
					break;
			}
		},
		
		isValid: function(isFocused){
			//temp solution to not validate removed element from set horizontal until new processing is ready, formanager can not validate fields that are registerd but afterwards destroyed by the set horizontal submit.
			if(typeof this.textbox == 'undefined' && typeof this.focusNode == 'undefined'){
				console.warn('Chuthulu: isValid on removed form field, make sure widget.destroy() unsubscribes from formmanager.',this);
				return true;
			}
			var dojoAns = this.inherited(arguments);
			//for select required
			if(this.required && this.get('value') == ''){
				dojoAns = false;
			}
			
			if(this.unique &! this.get('value') == ''){
				var _this = this;
				var xhrArgs = {
					url: 'cheyenne?cddid=xam.json.isUnique&cmode=json&FIELDNAME='+this.name+'&VALUE='+this.get('value'), 
					handleAs:'json',
					sync:true,
					preventCache:true,
					headers:{'Content-encoding':'UTF-8'},
					load: function(data){
						return data.isUnique;
					},
					error: function(error){
						console.error("Cthulhu",error);
					}
				};
				var deferred = dojo.xhrGet(xhrArgs);
				if(!deferred.results[0]){
					dojoAns = false;
					if(typeof this.messages != 'undefined'){
						this.messages.invalidMessage = 'Ingevoerde waarde is niet uniek.';
					}
				}
			}
			
			//fvalidate compatebillety
			var value = this.get('value');
			switch(this.validateType){
				case 'regexp':
					this.messages.invalidMessage = this.validateErrorMsg;
					return this.compiledRegexp.exec(value) != null && dojoAns;
				case 'email':
					this.messages.invalidMessage = 'Ongeldig e-mail adres.';
					if(this.validateParts[1]=='bok' && !this.required && value == ''){
						return true;
					}
					return dojoAns;
				case 'equalto':
					this.messages.invalidMessage = 'Wachtwoorden komen niet overeen.';
					//get value with formmanager to comare
					return reg.byId(this.formId).formNodeValue(this.validateParts[1]) == value && dojoAns;
				default:
					return dojoAns;
			}
		},

		validate: function(isFocused){			
			//temp solution to not validate removed element from set horizontal until new processing is ready, formanager can not validate fields that are registerd but afterwards destroyed by the set horizontal submit.
			if(typeof this.textbox == 'undefined' && typeof this.focusNode == 'undefined'){
				console.warn('Chuthulu: isValid on removed form field, make sure widget.destroy() unsubscribes from formmanager.',this);
				return true;
			}
			return this.inherited(arguments);
		},
		
		destroy: function(preserveDom){
			var formManager = reg.byId(this.formId);
			//deregister with form manger so it knows not to validate removed fields anymore.
			//console.log("destroy",this,formManager,this.formId);
			if(typeof formManager != 'undefined'){
					formManager.unregisterWidgetDescendants(this);
					formManager.unregisterNodeDescendants(this.domNode);
					formManager.unregisterWidget(this);
					formManager.unregisterNode(this.domNode);
			}
			return this.inherited(arguments);
		}
	});
});
