// Dependências: compat.js, util.js;
//
// Classe para saltar para uma página/script e ao mesmo tempo passar-lhe parâmetros.
//

// Constructor.
derive (WebMsg, Object)
function WebMsg (optForm, optDoc) {
	this.doc = optDoc || document
	optForm && optForm.substr && (optForm = elmx (optForm))
	// Criar o formulário.
	if (!optForm || (optForm.encoding == "multipart/form-data" && !hasFilesToUpl (optForm)) ) {	// O form não funciona como mensagem, tendo a codificação "multipart/form-data" e não tendo ficheiros seleccionados para carregar!
		with (this.frm = this.doc.createElement ("form")) {
			method = "post"
			style.display = "none"
		}
		if (optForm) this.load (optForm)
	}
	else this.frm = optForm

	this.frm._wmObj = this
	this.itemCount = 0
	this.found = false
}

// Carrega os campos de 'frm' para este objecto. Veja a descrição de 'optForce' em 'newItem'.
proto.load = function (frm, optForce) {
	frm.substr && (frm = elmnx (frm))
	var rdbs = new Array
	// Carregar campos. 'Radio's e 'CheckBox'es ficam para depois.
	var els = frm.elements, i = 0
	do {
		for (var i = 0; i < els.length; ++i) {
			var el = els [i]
			if (!el.name && !(el.name = el.id)) continue
			if (!el.value || el.value == 0) continue
	
			var t = el.type ? el.type.toLowerCase () : ""
			switch (t) {
			case "":
				break;
			case "radio":
			case "checkbox":
				rdbs.push (el)
				break
			case "file":
				break
			default:
				this.newItem (el.name, el.value, optForce)
			}
		}
		if (++i == 1 && !isIE) els = frm.childNodes; else break
	} while (true)
	// Carregar e 'Radio's e 'CheckBox'es. Estes têm um tratamento diferente devido à propriedade 'checked' e porque os 'Radio's de um
	// o nome de um grupo deles é o mesmo mas só interessa
	// mesmo grupo tem todos o mesmo nome.
	if (rdbs.length) {
		for (var i = 0; i < rdbs.length; ++i) {
			var rb = rdbs [i]
			if (rb.checked)
				this.newItem (rb.name, rb.value, optForce)
		}
	}
	return this
}

// Cria um novo item na mensagem. Esse chamar-se-á 'nm' e terá o valor 'vl'. 'optForce' controla se se pode ignorar quando 'vl' é nulo.
proto.newItem = function (nm, vl, optForce) {
	if (!optForce && !vl) return this

//	this.frm.innerHTML += "<input type='hidden' name='" + nm + "'>"
//	var els = isIE ? this.frm.elements : this.frm.childNodes
//	els [els.length - 1].value = vl
	var h = this.doc.createElement ("input")
	h.type = "hidden"
	h.name = nm
	h.value = vl
	this.frm.appendChild (h)

	++this.itemCount

	return this
}

// Substítui o valor do item 'nm' por 'vl', ou então cria esse item. O uso dste método só é aconselhável quando há a probabilidade de 
// 'nm' já existir, pois é mais lento do que 'newItem'. Veja a descrição de 'optForce' em 'newItem'.
proto.setItem = function (nm, vl, optForce) {
	var el
	if (el = this.getItem (nm)) {
		if (!optForce && (vl == "" || vl == null || vl == undefined))
			return this.removeItem (nm)
		el.value != undefined ? el.value = vl : el.innerHTML = vl
		return this
	}
	return this.newItem (nm, vl, optForce)
}

// Remove __todos__ os itens chamados 'nm'.
proto.removeItem = function (nm) {
	var el
	if (el = this.getItem (nm)) {
		removeNode (el)
		this.found = true
	}
	return this
}

// Retorna o item 'nm'.
proto.getItem = function (nm) {	
	var res
	if ((res = f (this.frm.elements)) || isIE) return res
	return res = f (this.frm.childNodes)
	
	function f (children) {
		for (var i = 0; i < children.length; ++i) {
			var el = children [i]
			if (el.name == nm)
				return el
		}
		return null
	}
}

// Enviar a mensagem. Essa poderá seguir para a página/script 'optTargetScript' e os seus resultados colocados em 'optTarget'.
proto.send = function (optTargetScript, optTarget) {
	// "Script" destino.
	if (!optTargetScript) {
		if (this.frm.action == "")
			this.frm.action = this.doc.location.href
	}
	else this.frm.action = optTargetScript
	// Objecto destino.
	if (optTarget) {
		if (!optTarget.substr) optTarget = optTarget.name
		this.frm.target = optTarget
	}
	(isIE ? this.frm.parentElement : this.frm.parentNode) || this.doc.body.appendChild (this.frm)
	this.frm.submit ()
}
