// Dependências: util.js.
//
// Funções para formulários.

var dispatching, submitOk

// Versão protegida de 'unpro_dispatch'.
function dispatch (frm, optNoOnSubmit, optNoClearParams, optAction) {
	try {	return unpro_dispatch (frm, optNoOnSubmit, optNoClearParams, optAction)	} finally {	return dispatching = false	}
}

// Despacha o formulário 'frm', executando antes a rotinas de validação respectiva.
function unpro_dispatch (frm, optNoOnSubmit, optOnBeforeSubmit, optOnAfterSubmit) {
	dispatching = true

	frm.substr && (frm = elmnx (frm))
	if (wnd.runHook && runHook (wnd.formDispatchHook, frm) == false) return false
	if (!optNoOnSubmit) {
		submitOk = true
		if (isIE)					// Os eventos do IE são executados da rotina mais recente para a mais antiga!
			fireOnSubmit (frm)	// Em contra-partida, o seu 'fireOnSubmit' é sincrono.
		else {
			listen (frm, "submit", go)
			fireOnSubmit (frm)
			return submitOk
		}
	}
	go ()

	function go () {
		optOnBeforeSubmit && optOnBeforeSubmit (frm)
		frm.submit ()
		optOnAfterSubmit && optOnAfterSubmit (frm)
		dispatching = false
	}
	return true
}

// Retorna 'true' se 'frm' referir ficheiros a carregar.
function hasFilesToUpl (frm) {
	if (!frm) return false
	var els = frm.getElementsByTagName ("input")
	for (var i = 0; i < els.length; ++i) {
		var el = els [i]
		if (el.type && el.type.toLowerCase () == "file" && el.value && !el.noFile)
			if (el.value != "") return true
	}
	return false
}

// Quando chamada em resposta a um evento, retorna 'true' se se tiver premido "enter".
function checkForEnter (ev) {	return ev.keyCode == 13 && !ev.shiftKey && !ev.ctrlKey && !ev.altKey	}

// Quando chamada em resposta a um evento, retorna 'true' se se tiver premido "escape".
function checkForEsc (ev) {	return ev.keyCode == 27 && !ev.shiftKey && !ev.ctrlKey && !ev.altKey	}

// Des/activa 'frm'.
function disableForm (frm, optB) {
	var b = optB == null ? true : (optB ? true : false)
	enumFields (frm, function (el) {
		if (el.disabled == null) return
		// Conservar estado de controlos já desactivados. Assim a inversão desta operação também não os afectará.
		if (b) {
			if (el.disabled) {
				el._dis = true
				return
			}
		}
		else if (el._dis) return
		el._dis = null

		el.setDisabled ? el.setDisabled (b) : el.disabled = b
	})
}

// Limpa os campos do formulário 'frm' ou coloca os valores por defeito.
function resetForm (frm) {
	enumFields (frm,
		function (el) {
			if (!el.tagName) return
			var t = el.type
			if (el.reset)
				el.reset ()
			else if (t == "file") {
				if (!el.value) return
				el.parentNode.replaceChild (el.cloneNode (false), el)
				return
			}
			else if (el.tagName == "SELECT") {
				// Tratamento especial para "combos".
				var o = el.options, l = o.length
				if (l < 1) return
				if (el._ds == null) {
					for (var i = 0; i < o.length; ++i) {
						if (o [i].defaultSelected) {
							el._ds = o [i].value
							break
						}
					}
					if (el._ds == null && o.length > 0) el._ds = el.value == null ? o [0].value : el.value
				}
				el.value = el._ds || null
			}
			else if (t == "radio" || t == "checkbox")
				el.checked = el.defaultChecked || false
			else if (t != "button" && t != "submit" && t != "reset")
				el.value = ""
		})
}

// Foca o primeiro controlo de 'sec'.
function focus1stCtrl (sec) {
	for (var i = 0; i < sec.childNodes.length; ++i) {
		var el = sec.childNodes [i]
		if (el.focus && el.value != null && !el.style.display && !el.style.visibility && !el.disabled && !el.isDisabled && el.type != "hidden" && setFocus (el))
			return true
		if (el.contentWindow) {
			el = el.contentWindow.document.body
			if (el && focus1stCtrl (el)) return true
		}
		else if (el.childNodes) {
			// Verificar dependentes.
			if (focus1stCtrl (el))
			return true
		}
	}
	return false
}

// Tenta focar 'c'. Retorna 'false' se não conseguir.
function setFocus (c) {
	c.substr && (c = elmx (c))
	try {	c.focus ()	} catch (e) {	return false	}
	return true
}

// Destina-se a tratar os "enters" nos forms! Colocando "return hijackSubmit(this)" no 'onsubmit' garante-se que o código no botão "submit" do form é sempre executado.
var _hijackingSubmit
function hijackSubmit (a, b) {	try {	return hijackSubmit_unpro (a, b)	} finally {	_hijackingSubmit = false	}}
function hijackSubmit_unpro (frm, optValdFunc) {
	if (dispatching) {
		if (_hijackingSubmit != 2) {
			_hijackingSubmit = 2
			optValdFunc && optValdFunc (frm)
		}
		return _hijackingSubmit = false
	}
	if (_hijackingSubmit) return false
	_hijackingSubmit = true
	// Encontrar o "submit".
	var ips = frm.getElementsByTagName ("input"), i, l = ips.length, submit = frm._submit, img
	if (!submit) {
		for (i = 0; i < l; ++i) {
			submit = ips [i]
			if (submit.type == "submit") break
			if (submit.type == "image") img = submit
		}
		frm._submit = submit || (submit = img)
	}
	// Executar o "click".
	if (submit) {
		listen (submit, "click", function () {	_hijackingSubmit = false	})
		submit && submit.click ()
	}

	return false
}
