//===========================================FormBuffer ===========================================
//	copy each field of a form of a dFrame in formBuffer
//	one 'element' is created for each field
//	if updateElements one element is created for each field name
//	if addElements one element is added for each field name, with asession id
//	can create elements for all fields of a form or for one element
//	reverse operation possible: Copy value of elements to a form is field with the same name than elements's is found
function FormBuffer (dFrame, nameOrNumber) {
	if (arguments.length == 2 && dFrame.title) dFrameTitle = dFrame.title; else dFrameTitle = '(no title)'
	this.sessionId = 0
	if (dFrame && dFrame.iDoc.forms[nameOrNumber]) {
		formObj.dFrame.iDoc.forms[nameOrNumber]
		this.dFrameTitle = dFrameTitle
		this.name = formObj.name
		this.action = formObj.action
		this.method = formObj.method
		this.elements = []
		this.sessions = []		
		return this.createElementsFromForm(formObj)
	} else {
		this.dFrameTitle = dFrameTitle
		this.name = null
		this.action = null
		this.method = null
		this.elements = []
		this.sessions = []		
		//this.elements[this.elements.length] = new FormBufferElement()
	}
}
FormBuffer.prototype.setDebugMessagesOn = function (b) {
	this.debugMessages = b
}

FormBuffer.prototype.resetElements = function (){
	this.elements = new Array()
	this.sessions = new Array()		
}
FormBuffer.prototype.updateElements = function (){
	//remove olds having the same name as new (no error if don't exist) and create new elements in FormBuffer
	//1 argument: FormBufferElement
	//2 (+1) arguments: dFrame, nameOrNumber
	//3 (+1) arguments: dFrame, nameOrNumber, fieldName
	//check the last arg
	var n = arguments.length - 1
	isLastArgSessionId = arguments[n] == null || (typeof(arguments[n]) == 'string' && arguments[n].indexOf('#') == 0)
	localSessionId = isLastArgSessionId == false ? null : arguments[n]

	if ((arguments.length == 1  || (arguments.length == 2 && isLastArgSessionId)) && arguments[0].isFormBufferElement) {
		this.removeElements(arguments[0])
		this.elements[this.elements.length] = arguments[0]
		if (localSessionId == null ) {
			//no sessionId as argument or sessionId arg. is null
			this.sessionId += 1
			localSessionId = '#' + this.sessionId
		} 
		this.sessions[localSessionId] = new Array()			
	} else if (arguments.length == 2 || (arguments.length == 3 && isLastArgSessionId)) {
		//2 args or (3 and (3rd is null or 1st char of the 3rd id '#'))
		if (arguments[0] && arguments[0].iDoc && arguments[0].iDoc.forms[arguments[1]] ) {
			this.removeElements(arguments[0], arguments[1])
			return this.createElementsFromForm(arguments[0].iDoc.forms[arguments[1]], localSessionId)
		} else {
			if (this.debugMessages) alert('UpdateElement: element ' + arguments[2] + ' was not found in formBuffer ' + this.dFrameTitle + ' for form ' + arguments[1] + '.')
		}
	} else if (arguments.length == 3 || (arguments.length == 4 && isLastArgSessionId)) {
		//3 args or (4 and (4th is null or 1st char of the 4th id '#'))
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]] && arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]]) {
			this.removeElements(arguments[0], arguments[1], arguments[2])
			return this.createElementsFromField(arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]], localSessionId)
		} else {
			if (this.debugMessages) alert('UpdateElement: element ' + arguments[2] + ' was not found in formBuffer ' + this.dFrameTitle + ' for form ' + arguments[1] + '.')
		}
	} else {
		alert('UpdateElement: Wrong number of parameters. You can pass 1 argument (FormBufferElement) or 3 (dFrame, name or number of form, field name)\nand you sent ' + arguments.length + '.')
	}
}

FormBuffer.prototype.addElements = function (){
	//DON'T remove olds and create new elements in FormBuffer
	//1 (+1) argument: FormBufferElement or Array of FormBufferElement (+ sessionId)
	//2 (+1) arguments: dFrame, nameOrNumber (+ sessionId)
	//3 (+1) arguments: dFrame, nameOrNumber, fieldName (+ sessionId)
	//check the last arg
	var n = arguments.length - 1
	isLastArgSessionId = arguments[n] == null || (typeof(arguments[n]) == 'string' && arguments[n].indexOf('#') == 0)
	var localSessionId = isLastArgSessionId == false ? null : arguments[n]
	if ((arguments.length == 1  || (arguments.length == 2 && isLastArgSessionId))  && (arguments[0].isFormBufferElement || arguments[0][0].isFormBufferElement) ) {
		if (localSessionId == null ) {
			//no sessionId as argument or sessionId arg. is null
			this.sessionId += 1
			localSessionId = '#' + this.sessionId
		} 		
		this.sessions[localSessionId] = new Array()
		this.sessions[localSessionId].sessionId = localSessionId
		if (arguments[0][0].isFormBufferElement) {
			//arguments[0] is an array of FormBufferElement	
			for (var i = 0 ; i<arguments[0].length ; i++) {
				this.elements[this.elements.length] = arguments[0][i]	
				arguments[0][i].sessionId = localSessionId
				this.sessions[localSessionId][arguments[0][i].name] = arguments[0][i]	
			}	
		} else {
			//arguments[0] is a single FormBufferElement	
			this.elements[this.elements.length] = arguments[0]
			arguments[0].sessionId = localSessionId
			this.sessions[localSessionId][arguments[0].name] = arguments[0]
		}
	} else if (arguments.length == 2 || (arguments.length == 3 && isLastArgSessionId)) {
		if (arguments[0] && arguments[0].iDoc && arguments[0].iDoc.forms[arguments[1]] ) {
			return this.createElementsFromForm(arguments[0].iDoc.forms[arguments[1]], localSessionId)
		} else {
			if (this.debugMessages) alert('UpdateElement: element ' + arguments[2] + ' was not found in formBuffer ' + this.dFrameTitle + ' for form ' + arguments[1] + '.')
		}
	} else if (arguments.length == 3 || (arguments.length == 4 && isLastArgSessionId)) {
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]] && arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]]) {
			return this.createElementsFromField(arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]], localSessionId)
		} else {
			if (this.debugMessages) alert('UpdateElement: element ' + arguments[2] + ' was not found in formBuffer ' + this.dFrameTitle + ' for form ' + arguments[1] + '.')
		}
	} else {
		alert('AddElement: Wrong number of parameters. You can pass 1 argument (FormBufferElement) or 3 (dFrame, name or number of form, field name)\nand you sent ' + arguments.length + '.')
	}
}
FormBuffer.prototype.removeElements = function (){
	//1 argument: FormBufferElement
	//2 (+1) arguments: dFrame, nameOrNumber (+ sessionId)
	//3 (+1) arguments: dFrame, nameOrNumber, fieldName (+ sessionId)
	var n = arguments.length - 1
	isLastArgSessionId = arguments[n] == null || (typeof(arguments[n]) == 'string' && arguments[n].indexOf('#') == 0)
	localSessionId = isLastArgSessionId == false ? null : arguments[n]
	
	if (arguments.length == 1 && arguments[0].isFormBufferElement) {
		for (var i = 0 ; i<this.elements.length ; i++) {
			if (this.elements[i].name == arguments[0].name) Methods.removeFromArray(this.elements,i);
		}
	} else if (arguments.length == 2 || (arguments.length == 3 && isLastArgSessionId)) {
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]] ) {
			formObj = arguments[0].iDoc.forms[arguments[1]]
			for (var f = 0 ; f<formObj.elements.length ; f++) {
				formObjElt = formObj.elements[f]
				for (var i = 0 ; i<this.elements.length ; i++) {
					if (this.elements[i].name == formObjElt.name && (localSessionId == null || this.elements[i].sessionId == localSessionId)) {
						if (localSessionId != null) this.sessions[this.elements[i].sessionId][this.elements[i].name] = null
						Methods.removeFromArray(this.elements,i);
						i--
						//don't break as it can happend the fieldName concerns many elements
					}
				}
			}
		} else {
			if (this.debugMessages) alert('RemoveElement: form ' + arguments[1] + ' was not found in formBuffer ' + this.dFrameTitle + '.')
		}
	} else if (arguments.length == 3 || (arguments.length == 4 && isLastArgSessionId)) {
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]] && dFrame.iDoc.forms[arguments[1]].elements[arguments[2]]) {
			formObjElt = arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]]
			for (var i = 0 ; i<this.elements.length ; i++) {
				if (this.elements[i].name == formObjElt.name && (localSessionId == null || this.elements[i].sessionId == localSessionId)) {
					this.sessions[this.elements[i].sessionId][this.elements[i].name] = null
					Methods.removeFromArray(this.elements,i);
					i--
					//don't break as it can happend the fieldName concerns many elements
				}
			}
		} else {
			if (this.debugMessages) alert('RemoveElement: element ' + arguments[2] + ' was not found in formBuffer ' + this.dFrameTitle + ' for form ' + arguments[1] + '.')
		}
	}
	//clean up sessions
	for (var i in this.sessions) {
		var nullSession = true
		for (var j in this.sessions[i]) {
			if (j != 'sessionId' && this.sessions[i][j] != null) {
				nullSession = false
				break;
			}
		}
		if (nullSession) this.sessions[i] = null
	}
}
FormBuffer.prototype.updateForm = function () {
	//dFrame.iDoc.forms <= FormBuffer
	//values from FormBuffer sent to ...
	//2 (+1) arguments: dFrame + nameOrNumber of form (+ sessionId)
	//3 (+1) arguments: dFrame, nameOrNumber, fieldName or FormBufferElement (+ sessionId)
	var n = arguments.length - 1
	isLastArgSessionId = arguments[n] == null || (typeof(arguments[n]) == 'string' && arguments[n].indexOf('#') == 0)
	localSessionId = isLastArgSessionId == false ? null : arguments[n]

	if (arguments.length == 2 || (arguments.length == 3 && isLastArgSessionId)) {
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]]) {
			formObj = arguments[0].iDoc.forms[arguments[1]]
			for (var i = 0 ; i<formObj.elements.length ; i++) {
				formObjElt = formObj.elements[i]
				this.updateFieldInForm(formObjElt, localSessionId)
			}
		} else {
			if (this.debugMessages) alert('UpdateForm: form ' + arguments[1] + ' was not found in dFrame ' + this.dFrameTitle + '.')
		}
	} else if (arguments.length == 3 || (arguments.length == 4 && isLastArgSessionId)) {
		var name = typeof(arguments[2]) == 'string' ? arguments[2] : arguments[2].name
		if (arguments[0] && arguments[0].iDoc && arguments[0].iDoc.forms[arguments[1]] && arguments[0].iDoc.forms[arguments[1]].elements[name]) {
			var formObjElt = arguments[0] && arguments[0].iDoc.forms[arguments[1]] && arguments[0].iDoc.forms[arguments[1]].elements[name]
			if (formObjElt) this.updateFieldInForm(formObjElt, localSessionId)
		} else {
			if (this.debugMessages) alert('UpdateForm: field ' + arguments[2] + ' in form ' + arguments[1] + ' was not found in dFrame ' + this.dFrameTitle + '.')
		}
	} else {
		alert('UpdateElement: Wrong number of parameters. You can pass 2 arguments (dFrame, nameOrNumber) or 3 (dFrame, name or number of form, field name)\nand you sent ' + arguments.length + '.')
	}
}
FormBuffer.prototype.updateFieldInForm = function (formObjElt, localSessionId){
	// private, used as a sub procedure for updateForm()
	// never public (use a reference to field of a form, not a FormBufferElement)
	var n = arguments.length - 1
	isLastArgSessionId = arguments[n] == null || (typeof(arguments[n]) == 'string' && arguments[n].indexOf('#') == 0)
	localSessionId = isLastArgSessionId == false ? null : arguments[n]
	var value = ''
	var checked = false
	var selectedIndex = -1
	for (var i = 0 ; i<this.elements.length ; i++) {
		if (localSessionId == null || (localSessionId != null && this.elements[i].sessionId == localSessionId)) {
			if (formObjElt.name == this.elements[i].name && ( (formObjElt.type != 'radio' && formObjElt.type != 'checkbox') || (formObjElt.value == this.elements[i].value) ) ) {
				var value = this.elements[i].value
				var checked = this.elements[i].checked
				var selectedIndex = this.elements[i].selectedIndex
				if (formObjElt.type =='select-one') {
					formObjElt.selectedIndex = selectedIndex;
					
				} else if (formObjElt.type =='select-multiple') {
					for (var j = 0 ; j<formObjElt.options.length ; j++) {
						formObjElt.options[j].selected = selectedIndex[j]
					}
				} else if (formObjElt.type == 'radio' || formObjElt.type == 'checkbox') {
					formObjElt.checked = checked
				} else {
					formObjElt.value = value
				}
				break
			}
		}
	}
}
FormBuffer.prototype.createElementsFromForm = function (formObj, localSessionId){
	//private method (formObj as parameter)
	if (localSessionId == null ) {
		//no sessionId as argument or sessionId arg. is null
		this.sessionId += 1
		localSessionId = '#' + this.sessionId
	} 
	this.sessions[localSessionId] = new Array()
	this.sessions[localSessionId].sessionId = localSessionId
	for (var i=0; i < formObj.elements.length; i++)  {
		formObjElt = formObj.elements[i]
		if (typeof(formObjElt)=='object' || typeof(formObjElt)=='textarea') {
			if (typeof(formObjElt.name) == 'string' && formObjElt.name != '') {
				var newElt = this.createElementsFromField(formObjElt, localSessionId)
				if (newElt != null) {
					this.sessions[localSessionId][newElt.name] = newElt
				}			
			}
		}
	}
	return this.sessions[localSessionId]
}
FormBuffer.prototype.createElementsFromField = function (formObjElt, localSessionId){
	//private
	var elt = null
	var newElt = new FormBufferElement(formObjElt)
	if (newElt.name != '__Click'){
		newElt.sessionId = localSessionId
		this.elements[this.elements.length] = newElt
		elt = newElt	
	}
	return elt	
}
FormBuffer.prototype.resetForm = function (){
	//set blank to all fields of form
	//1 argument: All forms of dFrame
	//2 arguments: dFrame, nameOrNumber
	if (arguments.length == 1 && arguments[0].iDoc) {
		for (var i = 0 ; i<arguments[0].iDoc.forms ; i++) {
			formObj = arguments[0].iDoc.forms[i]
			for (var j = 0 ; j<formObj.elements.length ; j++) {
				formObjElt = formObj.elements[j]
				this.resetField(formObjElt)
			}
		}
	} else if (arguments.length == 2 && arguments[0].iDoc) {
		//2 args dFrame and formNameOrNumber
		formObj = arguments[0].iDoc.forms[arguments[1]]
		for (var i = 0 ; i<formObj.elements.length ; i++) {
			formObjElt = formObj.elements[i]
			this.resetField(formObjElt)
		}
	} else {
		alert('ResetForm: Wrong number of parameters. You can pass 1 argument (FormBufferElement) or 2 (dFrame, name or number of form, field name)\nand you sent ' + arguments.length + '.')
	}
}
FormBuffer.prototype.resetField = function (formObjElt){
	if (formObjElt.name != '__Click'){
		if (formObjElt.type =='select-one') {
			formObjElt.selectedIndex = -1;
		} else if (formObjElt.type =='select-multiple') {
			for (var j = 0 ; j<formObjElt.options.length ; j++) {
				formObjElt.options[j].selected = -1
			}
		} else if (formObjElt.type == 'radio' || formObjElt.type == 'checkbox') {
			formObjElt.checked = false
		} else {
			formObjElt.value = ''
		}	
	}
}
FormBuffer.prototype.getSessionsAsFormattedString = function (sep1, sep2, sep3) {
	sep1 = typeof(sep1) != 'undefined' ? sep1 : '|#|'
	sep2 = typeof(sep2) != 'undefined' ? sep2 : '|##|'
	sep3 = typeof(sep3) != 'undefined' ? sep3 : '|###|'
	var str = ''

	for (var i in this.sessions) {
		var session = this.sessions[i]
		if (session != null && typeof(session) != 'undefined') {
			for (var j in session) {
				if (j != 'sessionId') {
					var elt = session[j]	
					if (elt != null  && typeof(elt) != 'undefined') {			
						str += (elt.name + sep1)	
						str += (elt.type + sep1)	
						str += (elt.value + sep1)
						str += (elt.checked + sep1)
						str += (elt.selectedIndex + sep2)
					}
				}
			}
			str = str.substring(0,str.length - sep2.length) + sep3	
		}
	}
	str = str.substring(0,str.length - sep3.length)
	return str
}
FormBuffer.prototype.loadSessionsFromFormattedString = function (str, sep1, sep2, sep3){
	sep1 = typeof(sep1) != 'undefined' ? sep1 : '|#|'
	sep2 = typeof(sep2) != 'undefined' ? sep2 : '|##|'
	sep3 = typeof(sep3) != 'undefined' ? sep3 : '|###|'

	var sessions = str.split(sep3)	
	for (var i = 0 ; i < sessions.length ; i++) {
		//each 'sessions[i]' = 1 form
		if (sessions[i] != '') {
			var elements = sessions[i].split(sep2)
			var eltsForOneSession = new Array()
			for (var j = 0 ; j < elements.length ; j++) {						
				//each 'elements[j]' = 1 field
				if (elements[j] != '') {
					elementDescr = elements[j].split(sep1)						
					var element = new FormBufferElement()
					element.name = elementDescr[0]
					element.type = elementDescr[1]
					element.value = elementDescr[2]
					element.checked = elementDescr[3]					
					element.selectedIndex = elementDescr[4]								
					eltsForOneSession[eltsForOneSession.length] = element							
				}
			}
			//don't add separate elements but all for one session
			this.addElements(eltsForOneSession)				
		}					
	}
}
//===========================================FormBufferElement ====================================
FormBufferElement = function() {
	//used by createElementsFromForm (private)
	//also by user to get an element (and its value) from a form without inserting it in formBuffer
	//1 argument: document.forms.element[i] (FormBuffer or user call)
	//3 arguments: dFrame, nameOrNumber, fieldName (userCall)

	//return: Either this or an array of this, is radio or checkBox fields of the same names
	formObjElt = null
	if (arguments.length == 3) {
		if (arguments[0] && arguments[0].iDoc.forms[arguments[1]] && arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]]) {
			formObjElt = arguments[0].iDoc.forms[arguments[1]].elements[arguments[2]]
		}
	} else formObjElt = arguments[0]
	
	if (formObjElt) {
		//formObjElt is an array of objects (a field is an object)
		if (typeof(formObjElt[0]) == 'object' && (formObjElt[0].type == 'radio' || formObjElt[0].type == 'checkbox')) {		
			var tmp = new Array()
			for (var i = 0 ; i<	formObjElt.length ; i++) {			
				tmp[tmp.length] = this.createElement(formObjElt[i])
			}
			return tmp
		} else {
			return this.createElement(formObjElt)
		}
	} else {
		this.isFormBufferElement = true
		this.name = null
		this.type = null
		this.value = null
		this.checked = null
		this.selectedIndex = null
		return this
	}
}
FormBufferElement.prototype.createElement = function (formObjElt){
	//1 argument = document.forms.element[i], unique
	//private, used in FormBufferElement function
	var elt = new Array()
	elt.isFormBufferElement = true
	elt.name = formObjElt.name
	elt.type = formObjElt.type
	elt.checked = null
	elt.selectedIndex = null
	var valueField = ''
	if (formObjElt.type =='select-one') {
		elt.selectedIndex = formObjElt.selectedIndex
		if (elt.selectedIndex != -1 ) {
			valueField = formObjElt.options[formObjElt.selectedIndex].value
			if (valueField == '' ) valueField = formObjElt.options[formObjElt.selectedIndex].text
		}
		
	} else if (formObjElt.type =='select-multiple') {
		elt.selectedIndex  = []
		for (var i = 0 ; i<formObjElt.options.length ; i++) {
			elt.selectedIndex[i] = formObjElt.options[i].selected ? true : false
		}
	} else if (formObjElt.type == 'radio' || formObjElt.type == 'checkbox') {		
		elt.checked = formObjElt.checked
		valueField = formObjElt.value
	} else {
		valueField = formObjElt.value
	}
	elt.value = valueField
	return elt
}

	