/**
 * ##########################
 * Form-related functionality
 * ##########################
 */


// Instantiates each form on page
function initAllForms()
{
	var allForms = document.forms;
	for( var i=0; i<allForms.length; i++ )
		new Form(allForms[i]);
}



/**
 * Validating form
 * All formelements will be instantiated as Form_Element, and will determine whether this form is valid or not
 * @constructor
 * @param	elem {object}
 */
var Form = function( elem, opts )
{
	var opts = opts || {};
	this.form = dojo.byId(elem);
	this.formElems = [];
	this.doSubmit = (opts.doSubmit===false) ? false : true;// When true it will programmaticly submit the form when valid onSubmit, when false there's no handler attached to submit-event - you can do that manually (and for instance use AJAX to request)
	this.programCheck = opts.programCheck;// programmatic check which returns boolean and determines whether the form may be submitted or not (even when it is valid). Executed after formvalidation and before the actual submittance. If set, the form will first be submitted when it returns true, else the submit-handler will be called again (recursively)
	this.recursionPause = 1000;
	this.valid = true;
	this.message = '';
	this.messageTextHandler = new Text('html');
	this.dialog = null;
	this.processingImg = '/images/loading.gif';
	this.init();
};


// Satic member, container for form-id's, who should be instantiated
Form.instances = [];

// Static method, adds id of a form that should be instantiated
Form.add = function( formId, opts )
{
	var opts = opts || {};
	Form.instances.push({formId:formId,opts:opts});
};

// Static method, should first be called after entire document is loaded, instantiates given instances
Form.prepare = function()
{
	for( var i=0; i<Form.instances.length; i++ )
		new Form( Form.instances[i].formId , Form.instances[i].opts );
};
dojo.addOnLoad(Form.prepare);


// Instantiates an instance
Form.prototype.init = function()
{
	// Exit when elemnt not available on this page
	if(!this.form) return;
	
	// Initiate each form element
	for(var i=0; i<this.form.length; i++)
		this.formElems.push( new Form_Element(this.form[i],this.form) );
	
	// Set onSubmit
	if( this.doSubmit )
	{
		var obj = this;
		dojo.connect(this.form , 'onsubmit' , function(e)
		{
			// Prevent the form from really submitting
			e.preventDefault();
			// Let user know we're processing
			obj.showProcess();
			
			// Try to delay the submission, to be sure the processing image is shown (for large data submissions)
//			dojo.connect(obj.dialog,"onFocus", function()
//			dojo.connect(dojo.byId('processing'),"onLoad", function()
//			{
				// Validate this form
				obj.validate();
				// Submit it when valid
				if( obj.valid )
				{
					// Disable submit-button(s)
					//dojo.query('[type=submit]').attr('disabled', obj.valid);
					
					
					if( obj.programCheck ) // Perform a programattic check
					{
						if( obj.programCheck() ) // It's ok, let's submit this form
						{
							// Submit
							console.log('submit form');//
							obj.form.submit();
						}else{					
							var recursive = arguments.callee;
							setTimeout(function(){ recursive(e); },obj.recursionPause);
						}
					}else{ // 
						// Submit
						console.log('submit form');//
						obj.form.submit();
					}
				}
//			});
			
		
		});
	}
	
	this.preloadProcessingImg();
};

// Validates form
Form.prototype.validate = function()
{
	// Reset
	this.valid = true;
	this.message = '';
	
	var formElem;
	for( var i=0; i<this.formElems.length; i++ )
	{
		formElem = this.formElems[i];
		// Is this element filled out correctly?
		if( !formElem.validate() )
		{
			this.valid = false;
			this.addMessage( formElem.message );
			this.showMessage();
			break;
		}
	}
};

Form.prototype.addMessage = function( string )
{
	this.message += string;
	this.message += this.messageTextHandler.getLineBreak();
};

Form.prototype.showMessage = function()
{
	this.closeDialog();
	this.dialog = Dialog.alert(this.message);
};

Form.prototype.showProcess = function()
{
	this.closeDialog();
	this.dialog = Dialog.alert('<img id="processing" src="'+this.processingImg+'" />',Lang.transl('saving'));
};

Form.prototype.preloadProcessingImg = function()
{
	if (document.images && this.processingImg!='')
	{
		var preload_image = new Image(); 
		preload_image.src = this.processingImg; 
	}
};

Form.prototype.closeDialog = function()
{
	if( this.dialog && this.dialog.open )
		this.dialog.hide();
}



/**
 * Validating formelement
 * @constructor
 * @param	elem {object}/{string}
 * @param	form {object}/{string}
 */
var Form_Element = function( elem , form )
{
	this.elem = dojo.byId(elem);
	this.form =  dojo.byId(form);
	this.message = '';
	this.messageTextHandler = new Text('html');
	this.label = this.getLabel();
	this.required = false;
	this.date = false;
	this.numeric = false;
	this.email = false;
	this.cleanText = false;
	this.password = false;
	this.conf_password = false;
	
	this.setValidation();
};

// Find 'human'-name for this element
Form_Element.prototype.getLabel = function()
{
	if( !this.elem.id || !this.elem.name ) return 'Unknown element';
	var myLabelElemValue = '';
	var myLabelElem = dojo.query('label[for="' + this.elem.id + '"]',this.form);
	if( myLabelElem.length > 0 )
	{
		myLabelElemValue = dojo.trim( myLabelElem[0].firstChild.nodeValue );
		if( myLabelElemValue != '' )
			return myLabelElemValue;
	}
	return Lang.transl(this.elem.getAttribute('name'));
};

// Set validation-proprties (eg required & numeric)
Form_Element.prototype.setValidation = function()
{
	// Required
	if( dojo.hasClass(this.elem,'required') )
		this.required = true;
	// Date
	if( dojo.hasClass(this.elem,'date') )
		this.date = true;
	// Numeric
	if( dojo.hasClass(this.elem,'numeric') )
		this.numeric = true;
	// Email
	if( dojo.hasClass(this.elem,'email') )
		this.email = true;
	// Clean Text
	if( dojo.hasClass(this.elem,'cleantxt') )
		this.cleanText = true;
	// Password
	if( dojo.hasClass(this.elem,'psw') )
		this.password = true;
	// Confirm password
	if( dojo.hasClass(this.elem,'conf_psw') )
		this.conf_password = true;
};

// Rreturns whether element is valid or not
Form_Element.prototype.validate = function()
{
	var invalid = 0;
	this.message = '';
	// Required
	if( this.required && !this.is_Required() )
		invalid++;
	// Date
	if( this.date && this.is_Set() && !this.is_Date() )
		invalid++;
	// Numeric
	if( this.numeric && this.is_Set() && !this.is_Numeric() )
		invalid++;
	// Email
	if( this.email && this.is_Set() && !this.is_Email() )
		invalid++;
	// Clean Text
	if( this.cleanText && this.is_Set() && !this.is_CleanText() )
		invalid++;
	// Password
	if( this.password && this.is_Set() && !this.is_Password() )
		invalid++;
	// Confirm password
	if( this.conf_password && this.is_Set() && !this.is_ConfPassword() )
		invalid++;

	if( invalid == 0 )
		return true;
	else
		return false;
};

// Returns element value
Form_Element.prototype.getValue = function()
{
	switch( this.elem.getAttribute('type') )
	{
		default:
			return this.elem.value;
			break;
		case 'checkbox':
			return this.elem.checked;
			break;
	}
};

// Set element value
Form_Element.prototype.setValue = function(value)
{
	this.elem.value = value;
};

// Returns whether element is filled out
Form_Element.prototype.is_Set = function()
{
	if( this.getValue() == '' || this.getValue() === false )
		return false;
	else
		return true;
};

Form_Element.prototype.is_Required = function()
{
	if( this.getValue() == '' || this.getValue() === false )
	{
		this.message += Lang.transl('elementRequired');
		this.message += this.messageTextHandler.getLineBreak();
		this.message += this.label;
		return false;
	}
	return true;
};

Form_Element.prototype.is_Date = function() { return true; }


Form_Element.prototype.is_Numeric = function()
{
	return !isNaN( this.getValue() );
};

Form_Element.prototype.is_Email = function()
{
	var re = /^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+$/;
	if( !re.test( this.getValue() ) ) {
		this.message += Lang.transl('invalidEmail');
		this.message += this.messageTextHandler.getLineBreak();
		this.message += this.label;
		return false;
	}
	return true;
};

Form_Element.prototype.is_CleanText = function()
{
	// Force to lowercase
	this.setValue( this.getValue().toLowerCase() );
	// Test ...
	var re = /^[\w\d\_\.]{4,}$/;	
	if( !re.test( this.getValue() ) ) {
		this.message += Lang.transl('invalidCleanText');
		this.message += this.messageTextHandler.getLineBreak();
		this.message += this.label;
		return false;
	}
	return true;
};

Form_Element.prototype.is_Password = function()
{
	//var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/; //Strict
	var re = /^[\w\d\_\.]{6,}$/; //Weak
	if( !re.test( this.getValue() ) ) {
		this.message += Lang.transl('invalidPassword');
		this.message += this.messageTextHandler.getLineBreak();
		this.message += this.label;
		return false;
	}
	return true;
}

Form_Element.prototype.is_ConfPassword = function()
{
	var relatedElem = dojo.byId( this.elem.id.replace(/confirm_/i,'') );
	if( this.getValue() != relatedElem.value )
	{
		this.message += Lang.transl('invalidConfPassword');
		this.message += this.messageTextHandler.getLineBreak();
		this.message += this.label;
		return false;
	}
	return true;
}





/**
 *
 *
var Form = {
	
	
	// Checks whether form is filled out correctly
	is_valid : function(dojoForm)
	{
		if( dojoForm.isValid() )
			return true
		else
		{
			var fe = dojoForm.getDescendants();
			for( var i = 0; i < fe.length; i++ )
			{
				var fElem = fe[i];
				if( fElem.isValid && !fElem.isValid() )
				{
					Dialog.alert( fElem.getErrorMessage() );
					break;
				}
			}
		}
		return false;
	},
	
	//
	checkAndSubmit : function(){},
	
	//
	checkAndPost : function(){}
	
};
 */
 
 
 
 /**
  *
  *
  */
 function usernameMustBeUnique( elem )
 {
	dojo.addOnLoad(function()
	{
		dojo.connect(dojo.byId(elem),'onchange',function(e)
		{
			dojo.xhrGet({
				url: '/ajax/username-avail.php?q=' + escape(e.target.value),
				handleAs: "json",
				load: function(data,args) {
					if(!data.response)// Username in use
						Dialog.alert( Lang.transl('userNameInUse') );
				},
				// if any error occurs, it goes here:
				error: function(error,args){
					console.warn("error!",error);
				}
			});
		});
	});
 }
