
///////////////////////// MEMLIB /////////////////////////
// JS Form functions
//////////////////////////////////////////////////////////



////////// FORMS //////////


// Create a form HTML object
function Form (task, className) {

	this.timeout 				= function () {};
	this.success 				= function () {};
	this.failure 				= function () { this.markerrors(); msg('error', 'Oops! There were some errors with your submission.', 1); };
	this.J						= {};
	this.disabled				= false;
	this.passed					= null;
	this.ajax					= newReq(this);
	this.ajax.todo				= parseFormJ;
	this.html					= document.createElement('form');
	this.html.id				= 'form-' + task;
	this.html.action			= APIURL;
	this.html.onsubmit			= submitForm;
	this.html.parent			= this;
	this.table					= div(this.html, (className ? className : 'inform'));
	this.table.id				= 'ftable-' + task;
	this.addhidden				('task', task);
	this.addhidden				('sesid', C.sesid);

}




// Add a text input HTML object to a form
Form.prototype.addtext = function (key, value, name, help, size, pwdflag) {
	
	// Create row <DIV>
	var row 		= div(this.table, 'row input');
	row.id 			= this.html.id + '-row-' + key;	
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create input field
	var field 			= document.createElement('input');
	field.type			= pwdflag ? 'password' : 'text';
	field.name			= key;
	field.size			= size ? size : 35;
	field.id			= this.html.id + '-' + key;
	field.onfocus		= function () { addclass(row.id, 'focus'); };
	field.onblur		= function () { dropclass(row.id, 'focus'); };
	if (value)			field.value = value;
	
	// Create cell <DIV>s and insert content
	div(row, 'name', name);
	div(row, 'field').appendChild(field);
	div(row, 'help', help);
}





// Add a textarea input HTML object to a form
Form.prototype.addarea = function (key, value, name, help, cols, rows) {

	// Create row <DIV>
	var row			= div(this.table, 'row area');
	row.id			= this.html.id + '-row-' + key;
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create textarea
	var field 			= document.createElement('textarea');
	field.name			= key;
	field.cols			= cols ? cols : 80;
	field.rows			= rows ? rows : 5;
	field.id			= this.html.id + '-' + key;
	field.onfocus		= function () { addclass(row.id, 'focus'); };
	field.onblur		= function () { dropclass(row.id, 'focus'); };
	if (value)			field.value = value;
	
	// Create cell <DIV>s and insert content
	div(row, 'name', name);
	div(row, 'field').appendChild(field);
	
	if (help) div(row, 'help', help);
}




// Add checkbox to a form
Form.prototype.addcheck = function (key, help, checked) {
	
	// Create row <DIV>	
	var row			= div(this.table, 'row check');
	row.id			= this.html.id + '-row-' + key;
	var id			= this.html.id + '-' + key;
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create empty name cell <DIV>
	var cell			= div(row, 'name', '&nbsp;');
	
	// Create field cell <DIV>
	var cell2			= div(row, 'field');
	var field 			= document.createElement('input'); // Must be 2 steps so IE7 recognizes ".type"
	field.type			= 'checkbox';
	field.name			= key;
	field.id			= id;
	field.value			= 1;
	if (checked==1)		field.checked = true;
	cell2.appendChild	(field);

	var text			= span(cell2, '', ' ' + help);
	text.onclick		= function () { gid(id).click(); };
	
}




// Add select field
Form.prototype.addselect = function (key, name, help) {
	
	// Create row <DIV>
	var row 		= div(this.table, 'row input');
	row.id 			= this.html.id + '-row-' + key;	
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create input field
	var field 			= document.createElement('select');
	field.id 			= this.html.id + '-' + key;
	field.name 			= key;
	field.onfocus		= function () { addclass(row.id, 'focus'); };
	field.onblur		= function () { dropclass(row.id, 'focus'); };
	
	// Create cell <DIV>s and insert content
	div(row, 'name', name);
	div(row, 'field').appendChild(field);
	div(row, 'help', help);
	
	return field;
}


// Add select field option
function addOption (field, value, name, selected) {

	var option			= document.createElement('option');
	option.value		= value;
	option.text 		= name;
	
	if (value==selected) {
		option.defaultSelected = true;
		option.selected = true;
	}
	field.add(option, null);
}




// Add radio button field
Form.prototype.addradios = function (key, name) {
	
	// Create row <DIV>
	var row 		= div(this.table, 'row radio');
	
	// Create cell <DIV>s and insert content
	div(row, 'name', '&nbsp;');
	var cell = div(row, 'field', '');
	span(cell, 'title', name);
	
	return cell;
}


// Add radio buttom
function addRadio (cell, key, value, name, selected) {

	// Create input field
	var field 			= document.createElement('input');
	field.type			= 'radio';
	field.name			= key;
	field.value			= value;
	field.id			= 'radio-'+key+'-'+value;
	
	
	if (value==selected) field.checked=true;
	
	var sp = span(cell, 'radio');
	sp.onclick=function () { gid('radio-'+key+'-'+value).checked=true; };
	sp.onmouseover=function () { gid('radio-'+key+'-'+value).focus();};
	sp.onmouseout=function () { gid('radio-'+key+'-'+value).blur(); };
	sp.appendChild(field);
	sp.innerHTML+=' '+name;
	cell.appendChild(sp);
}






// Add date/time row
Form.prototype.adddate = function (key, value, name, help, detail) {
	
	var date	= new Date();
	var yf		= date.getFullYear()+5; // This is for the year countdown, not the default value
	
	// Pre-select values
	if ((value!==false) && (value!=='0')) {
		// from timestamp
		if (detail==2) {
			if (value) date.setTime(parseInt(value)*1000);
			var y		= date.getFullYear();
			var m		= date.getMonth()+1;
			var d		= date.getDate();
			var h		= date.getHours(); 
			var min		= date.getMinutes();
		}
		
		// from yyyymmdd
		else {
			var y = value ? parseInt(value.substring(0,4)) : date.getFullYear();
			var m = value ? parseInt(value.substring(4,6)) : date.getMonth()+1;
			var d = value ? parseInt(value.substring(6,8)) : date.getDate();
		}
	}
	
	// Create row <DIV>
	var row 		= div(this.table, 'row input');
	row.id 			= this.html.id + '-row-' + key;
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create name cell
	div				(row, 'name', name);
	var fieldCell 	= div(row, 'field');
	var field;
	
	
	// Create day select
	if (detail>=1) {
	field 						= document.createElement('select');
	field.id 					= this.html.id + '-' + key+'_day';
	field.name 					= key+'_day';
							addOption (field, 0, 'DY', d);
	for (var i=1; i<=31; i++) 	addOption (field, i, i, d);	
	fieldCell.appendChild		(field);
	}
	
	// Create month select
	field 			= document.createElement('select');
	field.id 		= this.html.id + '-' + key+'_month';
	field.name 		= key+'_month';
					addOption (field, 0, 'MO', m);
	for (i in Months) addOption (field, i, Months[i], m);	
	fieldCell.appendChild(field);
	
	// Create year select
	field 						= document.createElement('select');
	field.id 					= this.html.id + '-' + key+'_year';
	field.name 					= key+'_year';
								addOption (field, 0, 'YEAR', y);
	for (var i=1900; i<=yf; i++) addOption (field, i, i, y);
	fieldCell.appendChild		(field);
	
	
	// TIME
	if (detail>=2) {
	
	// am/pm
	var ampm=0;
	if (h>11) {
		h-=12;
		ampm=1;
	}
	
	if (h==0)	h=12;
		
	// Create hour select
	fieldCell.innerHTML+=' at ';
	field 						= document.createElement('select');
	field.id 					= this.html.id + '-' + key+'_hour';
	field.name 					= key+'_hour';
	for (var i=1; i<=12; i++) 	addOption (field, i, i, h);	
	fieldCell.appendChild		(field);
	fieldCell.innerHTML+=':';

	// Create min select
	field 						= document.createElement('select');
	field.id 					= this.html.id + '-' + key+'_minute';
	field.name 					= key+'_minute';
	for (var i=0; i<60; i++) 	addOption (field, i, zz(i), min);	
	fieldCell.appendChild		(field);

	// Create am/pm select
	var field 		= document.createElement('select');
	field.id 		= tthis.html.id + '-' + key+'_ampm';
	field.name 		= key+'_ampm';
	addOption 		(field, 0, 'am', ampm);	
	addOption 		(field, 1, 'pm', ampm);	
	fieldCell.appendChild(field);

	}

	// Create cell <DIV>s and insert content
	div(row, 'help', help);
	
	return field;
}








// Add a text input HTML object to a form
Form.prototype.addupload = function (key, name, help) {
	
	this.html.encoding 	= 'multipart/form-data';
	
	// Create row <DIV>
	var row 		= div(this.table, 'row input');
	row.id 			= this.html.id + '-row-' + key;
	row.onmouseover	= function () { addclass(row.id, 'hover'); };	
	row.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create input field
	var field 			= document.createElement('input');
	field.type			= 'file';
	field.name			= key;
	field.onfocus		= function () { addclass(row.id, 'focus'); };
	field.onblur		= function () { dropclass(row.id, 'focus'); };	
	field.onmouseover	= function () { addclass(row.id, 'hover'); };	
	field.onmouseout	= function () { dropclass(row.id, 'hover'); };
	
	// Create cell <DIV>s and insert content
	div(row, 'name', name);
	div(row, 'field').appendChild(field);
	div(row, 'help', help);
}







// Add a submit button HTML object to a form
Form.prototype.addsubmit = function (name) {
	this.buttonValue	= name;
	 
	var row				= div(this.table, 'row submit');
	row.id				= this.html.id + '-row-submit';
	
	var field 			= document.createElement('input'); // Must be 2 steps so IE7 recognizes ".type"
	field.type			= 'submit';
	field.name			= 'submit';
	field.value			= name;
	field.id			= this.html.id + '-submit';	
	
	div(row, 'name', '&nbsp;');
	this.submitCell = div(row, 'field');
	this.submitCell.appendChild(field);
}







// Add a cancel button HTML object to a form
Form.prototype.addbutton = function (name) {
	 
	var row				= this.submitCell;
	
	var field 			= document.createElement('input'); // Must be 2 steps so IE7 recognizes ".type"
	field.type			= 'button';
	field.value			= name;
	field.id			= this.html.id + '-button';	
	
	row.appendChild(field);
	
	return field;
}





// Add title bar HTML
Form.prototype.addtitle = function (title) {
	this.title=div(this.table, 'title');
	h1(this.title, title);
}

// Add title bar HTML
Form.prototype.addtitlelink = function (name,url) {
	href(this.title, name, url, 'edit');
}

// Add subtitle bar HTML
Form.prototype.addsubtitle = function (title) {
	div(this.table, 'subtitle', title);
}

// Add subtitle bar HTML
Form.prototype.addinfo = function (info) {
	div(this.table, 'info', info);
}


// Add multirow to form
Form.prototype.addmultirow = function () {
	this.table2	= this.table;
	var row		= div(this.table, 'multirow');
	this.table	= row;
}


// End multirow
Form.prototype.endmultirow = function () {
	this.table=this.table2;
	delete this.table2;
}








// Add a hidden input HTML object to a form
Form.prototype.addhidden = function (key, value) {
	var field 		= document.createElement('input'); // Must be 2 steps so IE7 recognizes ".type"
	field.type		= 'hidden';
	field.name		= key;
	field.value		= value;
	field.id		= this.html.id + '-' + key;
	this.html.appendChild(field);
}






// Add a submit button HTML object to a form
Form.prototype.addhtml = function (name, html, height) { 
	var row				= div(this.table, 'row html');
	row.style.height	= height + 'px';
	var cell			= div(row, 'name', name);
	var cell2			= div(row, 'field', html);
	if (height)			cell2.style.height	= height;
	
};






// Disable the submit button once form is submitted
Form.prototype.disable = function () {
	this.disabled			= true;
	var button				= gid(this.html.id + '-submit');
	if (button) {
		button.disabled		= true;
		button.value		= 'Submitting...';
	}	
};



// Enable submit button if form returns errors
Form.prototype.enable = function () {
	this.disabled			= false;
	var button				= gid(this.html.id + '-submit');
	if (button) {
		button.value		= this.buttonValue;
		button.disabled		= false;
	}
};






// Highlight fields with errors
Form.prototype.markerrors = function () {		 	
	for (key in this.J.values) {
		if (this.J.errors[key])		this.markwrong		(key, this.J.errors[key]);
		else						this.markright		(key);
	}	
	this.errorfocus();
};




// Remove error marks
Form.prototype.unmarkerrors = function () {		 	
	for (key in this.J.values) this.markright(key);
	this.errorfocus();
};






// Mark error field
Form.prototype.markwrong = function (key, error) {
	var row	= gid(this.html.id + '-row-' + key);
	
	if (row) {
		addclass						(row, 'error');				
		var errorSpan					= document.createElement('div');
		errorSpan.innerHTML				= 'Error: ' + error;
		errorSpan.className				= 'help';
		
		var children					= row.childNodes;
		if (children[3])				row.replaceChild(errorSpan, children[2]);
		else if (children[2])			row.insertBefore(errorSpan, children[2]);
		else 							row.appendChild(errorSpan);
		
		if (children[3]) children[3].style.display		= 'none';
	}
};




// Unmark correct fields
Form.prototype.markright = function (key) {
	var row = gid(this.html.id + '-row-' + key); 	
	if (row) {		
		dropclass					(row, 'error');	
		addclass					(row, 'correct');	
		var children				= row.childNodes;
		if (children[3])			row.removeChild(children[2]);
		if (children[2])			children[2].style.display = '';
	}
};



// Clear a field
Form.prototype.clear = function (key) {
	var field = gid(this.html.id + '-' + key); 	
	if (field) field.value='';
};


// Focus on the first field with an error
Form.prototype.errorfocus = function () {
	var rows = getchildren('div', this.html);
	for (var i=0; i<rows.length; i++) {
		if (rows[i].className.indexOf('error')>-1) {
			var field = getchild('input', rows[i]) || getchild('textarea', rows[i]);
			if (field) {
				field.focus();
				break;
			}
		}
	}
};





// Write the form to the document
Form.prototype.write = function (parent) {
	if (!parent) 	MAIN.appendChild(this.html);
	else			gid(parent).appendChild(this.html);
	this.focus();
};




// Auto-focus the first field in the form
Form.prototype.focus = function () {
	setTimeout("allfocus('"+this.table.id+"');", 100);
};

function allfocus (id) {
	var rows = getchildren('div', gid(id));	
	for (var i=0; i<rows.length; i++) {
		var field = getchild('input', rows[i]) || getchild('textarea', rows[i]);
		if (field) {
			field.focus();
			break;
		}
	}
};







// Submit form via AJAX
function submitForm () {

	// if existing request
	if (this.parent.disabled) {
	 	alert("Slow down, your previous request has not finished yet.");
		this.parent.focus();
	}
	
	// No file uploads, submit via AJAX
	else if (this.encoding!='multipart/form-data') {
	
		// build post data sting
		var postarr = new Array();
		for (var i=0; i<this.elements.length; i++) {
			if (
					(this.elements[i].name) && 
					(this.elements[i].value) &&
					(
						(this.elements[i].type!='checkbox') || 
						(this.elements[i].checked)
					)
				)
				postarr.push(encodeURIComponent(this.elements[i].name)+'='+encodeURIComponent(this.elements[i].value));
		}
		var poststr = postarr.join('&');
		
		// if string is empty
		if (!poststr.length) {
			alert('Ooops! You did not enter any information.');
			this.parent.focus();
		}
		
		// all is good, POST info via AJAX
		else {
			this.parent.disable			();
			this.parent.ajax.post		(poststr);
			gid('loading').className	= 'loadon';
			
		}
	}


	// File upload, submit via iframe
	else {
		
		// Ready <IFRAME>
		var iframe				= gid('uploadframe');
		iframe.parent			= this.parent;
		iframe.onload			= function () { this.parent.success(); }

		iframe.onreadystatechange = function () { if (this.readyState=='complete') this.parent.success(); }
		
		this.target		= 'uploadframe';
		this.enctype	= "multipart/form-data";
		this.method		= 'POST';
	

		gid('loading').className	= 'loadon';
		this.parent.disable			();
		return 						true;
	
	}
	return false;	
}




// Process return XML from AJAX form submit
function parseFormJ () {
	 // server error
	if (this.J) {
		// parse data
		this.parent.J 		= this.J;
	
		// success and failure functions
		if (this.J.success == true)	this.parent.success();
		else 						this.parent.failure();
	}
	this.parent.enable();
}









