// Dependências: util.js.
//
// Implementação de "hooks".


// Retorna 'hook' com 'func' acoplado. Quando 'hook' for chamado será executado todo o seu código actual mais 'func'.
//
// NOTA: Se alguma função retornar 'false' cancela-se o 'hook'.
function mkHook (h, func) {
	var node = new Object
	if (!h || !h._hfirst) {
		var f = h
		h = function (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) {	return h._rhf (h, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)	}
		h._rhf = _runHook
		// Guardar a função em 'h'.
		if (f) {
			h._hfirst = h._hlast = new Object
			h._hfirst.f = h.f = f
		}
		else h._hfirst = node
	}
	// Adicionar 'func' ao final da lista.
	h._hlast && (h._hlast.hnext = node)
	h._hlast = node
	node.f = func

	return h
}

// Elimina a função 'f' do "hook" 'h'.
// RETORNO: 'h'.
function rmFromHook (h, f) {
	if (!h) return null
	var n = h._hfirst, prevn
	f.f && (f = f.f)
	while (n) {
		if (n.f == f) {
			var e = n.hnext
			e || (h._hlast = prevn)
			prevn ? prevn.hnext = e : h._hfirst = e
			return h._hfirst ? h : null
		}
		prevn = n
		n = n.hnext
	}
	return h
}

// Corre 'hook' e retorna o resultado da última função. Se for 'false', houve cancelamento.
function runHook (hook, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) {	return hook ? (hook._rhf || hook) (hook, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) : true	}

// Executa todas as funções do 'hook' de que é membro.
function _runHook (h, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10) {
	var res, n = h._hfirst

	while (n) {
		if ((res = n.f (p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)) == false)
			return false
		n = n.hnext
	}
	return res
}
