function mlisten(event, elem_list, func) {
    map(elem_list, function(elem) { listen(event, elem, func) } );
}

function map(list, func) {
    var result = [];
    func = func || function(v) {return v};
    for (var i=0; i < list.length; i++) result[result.length] = func(list[i], i, list);
    return result;
}

function listen(event, elem, func) {
    elem = getElem(elem);
    if (elem.addEventListener)  // W3C DOM
        elem.addEventListener(event,func,false);
    else if (elem.attachEvent)  // IE DOM
        elem.attachEvent('on'+event, function(){ func(new W3CDOM_Event(elem)) } );
        // for IE we use a wrapper function that passes in a simplified faux Event object.
    else throw 'cannot add event listener';
}

function getElem(elem) {
    if (document.getElementById) {
        if (typeof elem == "string") {
			document.write(elem);
            elem = document.getElementById(elem);
            if (elem===null) throw 'cannot get element: element is null';
        } else if (typeof elem != "object") {
            throw 'cannot get element: invalid datatype';
        }
    } else throw 'cannot get element: unsupported DOM';
    return elem;
}

function W3CDOM_Event(currentTarget) {
    this.currentTarget  = currentTarget;
    this.preventDefault = function() { window.event.returnValue = false }
    return this;
}

function getElementsByClass(className, tagName, parentNode) {
    parentNode = parentNode? getElem(parentNode) : document;
    if (!tagName) tagName = '*';
    return filter(parentNode.getElementsByTagName(tagName),
        function(elem) { return hasClass(elem, className) });
}

function filter(list, func) {
    var result = [];
    func = func || function(v) {return v};
    map(list, function(v) { if (func(v)) result[result.length]=v } );
    return result;
}

arrayHas = function(array, value, start) {
    start = start || 0;
    for (var i=start; i<array.length; i++)
        if (array[i]==value)
            return 1;
    return 0;
}

function hasClass(elem, className) {
    return arrayHas(getElem(elem).className.split(' '), className);
}

var abstractFetcher = {
	myConn:		false,
	body:		false,
	control:	false,
	target:		false,
	bltarget:	false,
	loader:		false, //The loading image

	init: function(targetId) {
		if( !document.getElementById ||
		  !document.getElementsByTagName ||
		  !document.getElementById( targetId ) ) return false; //There's nowhere to put the result!
		this.myConn = new XHConn();
		if( !this.myConn ) return false;
		abstractFetcher.body    = document.getElementsByTagName( 'body' )[0];
		abstractFetcher.target  = document.getElementById( targetId );
		
		return true;
	},

	getAbstract:  function(id){
		abstractFetcher.buildLoader('moreinfo'+id);
		var fnWhenDone = function(oXML) {
			abstractFetcher.killLoader();
			abstractFetcher.target.innerHTML = oXML.responseText;
		};
		abstractFetcher.myConn.connect("/abstracts/get_abstract.php", "GET", "id="+id, fnWhenDone);
	},
	
	buildLoader: function(tgt){
		if( !document.getElementById( tgt ) ) return false; //There's nowhere to put the result!
		abstractFetcher.bltarget  = document.getElementById( tgt );
		abstractFetcher.bltarget.innerHTML = "<img src=\"/images/loading.gif\" /> Fetching Data, please wait\u2026";
	},
	killLoader:  function(){
		abstractFetcher.bltarget.innerHTML = "<a href=\"javascript:hide('"+abstractFetcher.target.id+"', '"+abstractFetcher.bltarget.id+"')\" class=\"ajax\">hide</a>";
	}
};

function hide(abstractID, linkID) {
	document.getElementById( abstractID).innerHTML = "";
	document.getElementById( linkID).innerHTML = "<a href=\"javascript:show('"+abstractID.substring(8,12)+"')\" class=\"ajax\">show abstract and bio</a>";	
}

function show(id) {
	abstractFetcher.init('abstract'+id);
	abstractFetcher.getAbstract(id);
}

function ajax_link() {
    // generates an event listener similar to event_popup, but allowing window features
    return function(e) {

		var reg = /\?.*$/; //Gets the query from the URL to be replaced.
		var query = reg.exec(e.currentTarget)[0];
		var reg2 = /id=(.*)$/ //Gets the ID, so we can figure out where the result goes.
		var id = reg2.exec(query)[1];
		if (abstractFetcher.init('abstract'+id)) {
			e.preventDefault();		
			abstractFetcher.getAbstract(id);
		}
		
	}
}

this.loader = new Image;
loader.src = "/images/loading.gif";