
// mapping from names to items - autoloading if not defined
var item_dict = {};
function get_item(i) {
	if (typeof i == "string") {
		if (i in item_dict) {
			return item_dict[i]; 
		} else {
			var req = loadURL('http://'+window.location.host+'/nltg/js/items/'+i+'.js'); 
			if (req && req.status == 200) {
  				eval(req.responseText);
				if (i in item_dict)
					return item_dict[i];
			}		
			return null;
		}		
	} else { 
		return i;
	}	
}	

function loadURL(url, handler) {
	var req, async = (handler?true:false);
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
		if (async) req.onreadystatechange = handler;
        req.open("GET", url, async);
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
			if (async) req.onreadystatechange = handler;
            req.open("GET", url, async);
            req.send();
        }
    }
	return req;
}	

function get_views(n) {
	// no checking for null item!
	return(get_item(n).views);
}

// -- views object -----------------------------------------------------------

function basic_views(parent) {
	this.addstyle = function(s,val) {
		return(s?"<span class='"+s+"'>"+val+"</span>":val);	
	}
	
	this.val = function(view, a, b) {
		if (view in this) {
			return(this[view](a, b));
		} else {
			// no view method - just access parent field directly
			var s = (b?b:a);  // style is always final defined argument
			return(this.addstyle(s, this.parent[view]));
		}
	}
	
	this.show = function(view, a, b)  {
		document.write(this.val(view, a, b));
	}
	
	this.parent = parent;
	this.href = function(u, s) {
		var url = this.parent.url || '#'+this.parent.label;
		var urlname = (u?this.parent[u]:(this.parent.urlname || url));
		var t = this.parent.urltitle || this.parent.brief;
		var title = (t?' title="'+t+'"':"");
		var style = (s?' class="'+s+'"':"");
		return("<a href='"+url+"'"+style+title+">"+urlname+"</a>")
	};
	this.indexitem = function(s) {return(this.href(s));};
	this.folditem = function(id, s) {
		// create a unique namespace for folditems, by prefixing with _fi_
		// otherwise IE gets confused (but mozilla doesn't....)
		id = "_fi_"+id;
		this.parent.fold_id = id;
		var folded =  "<div class='folditem folded'><span class='foldbutton'><a href='javascript:void(folditems[\""+id+"\"].unfold())'>[more]</a></span>" + this.val("brief",s) + "</div>";
		var unfolded = "<div class='folditem unfolded'><span class='foldbutton'><a href='javascript:void(folditems[\""+id+"\"].fold())'>[less]</a></span>" + this.val("full",s) + "</div>";
		void(new folditem(id, folded, unfolded, "no"));
		return("<div id='"+id+"'>"+folded+"</div>");
	}
	this.unfold_href = function(u, s) {
		var url = "javascript:void(window.location.hash=\""+this.parent.label+"\"); "+ (this.parent.fold_id?("folditems[\""+this.parent.fold_id+"\"].unfold();"):"");
		var urlname = (u?this.parent[u]:(this.parent.urlname || url));
		var t = this.parent.urltitle || this.parent.brief;
		var title = (t?' title="'+t+'"':"");
		var style = (s?' class="'+s+'"':"");
		return("<a href='"+url+"'"+style+title+">"+urlname+"</a>")
	};
}

// -- links objects ----------------------------------------------------------

// specific views object for a links object
function links_views(parent) {
	this.parent = parent;
	this.links = function(linkname, s) {
		var res = "<b>"+linkname+"</b>: ";
		var links = this.parent[linkname];
		var l = links.length;
		for (i = 0; i< l; i++) {
			res = res + item_dict[links[l]].views.href(s);
		}
		return(res);
	}
	
	this.full = function(s) {
		res = "";
		for (i in ["people", "events", "news", "projects", "topics"]) {
			if (this.parent[i].length > 0) res = res + this.links(i,s) + "<br>";
		}
		return(res);
	}
}
links_views.prototype = new basic_views(null);

// basic links object 
function basic_links(parent) {
	this.parent = parent;
	this.views = new links_views(this);
	this.people = {};
	this.events = {};
	this.news = {};
	this.projects = {};
	this.topics = {};
}

// -- lists of items -----------------------------------------------------------

function item_list_views(parent){
	this.parent = parent;
	this.index = function(s) {
		var res;
		if (this.parent.items.length == 0) {
			res = "";
		} else {			
			res = '<ul>' +
			this.parent.applist(function(a,s) {
				return((s?'<li class="'+s+'">':'<li>') + a.views.indexitem(null));
			},s)
			+ '</ul>';
		}	
		return(res);
	}
	this.full = function(s) {
		return(this.parent.applist(function(a,s,i,l) {
			return('<a name="'+a.label+'"></a>'+a.views.full(s)+((i< --l)?'<hr>':''));
		},s));
	}
	this.foldindex = function(name, s) {
		return(this.parent.applist(function(a,s,i,l,u) {
			return('<a name="'+a.label+'"></a>'+a.views.folditem((u?u+'+'+a.name:a.name), s)+((i< --l)?'<hr>':''));
		},name, s));
	}
	this.brief = function(s) { return(this.index(s)); };
}
item_list_views.prototype = new basic_views(null);


function basic_item_list(v, list) {
	// system fields
	this.items = null;
	this.views = null;
	this.valid = null;
	// methods
	this.applist = function(f,s,u) {
		var a = this.items;
		var l = a.length;
		var res = "";
		var i;
		for (i=0; i<l; i++) {
			res += f(get_item(a[i]),s,i,l,u);
		}
		return(res);
	}
	this.add = function(i) { 
		if (!this.valid || this.valid(i)) {
			this.items.push(i);
		}
	}
	this.initialise = function(v,list) {
		this.items = [];
		this.views = new item_list_views(this);
		this.valid = v;
		if (list) {
			var a = list.items;
			var l = a.length;
			var i;
			for (i=0; i<l; i++) {
				this.add(a[i]);
			}
		}
	}
	this.initialise(v,list);	
}

var today = new Date().getTime();
var msPerDay = 24 * 60 * 60 * 1000;
today = Math.floor(today/msPerDay)*msPerDay;

function valid_current_item(i) {return(get_item(i).state == "current");}
function valid_past_item(i) {return(get_item(i).state == "past");}
function valid_future_item(i) {return(get_item(i).state == "future");}
function valid_archive_item(i) {return(get_item(i).state == "archive");}

// -- Basic item ---------------------------------------------------------

function basic_item(name) {
	// user fields
	this.full = null;
	this.brief = null;
	this.label = null;
	this.url = null;
	this.urlname = null;
	this.urltitle = null;
	this.creation_date = null;
	this.valid_from = null;
	this.valid_to = null;
	this.state = null;
	this.fold_id = null;
	// system fields
	this.name = name;
	this.views = new basic_views(this);
	this.links = new basic_links(this);
	// methods
	this.register = function(l) { l.add(this); }
	this.initialise = function() {
		if (this.full === null) this.full = "";
		if (this.brief === null) this.brief = (this.full.length<50?this.full:this.full.substr(0,49)+" ...");
		if (this.label === null) this.label = this.name;
		if (this.url === null) this.url = '#' + this.label;
		if (this.urlname === null) this.urlname = this.url;
		if (this.urltitle === null) this.urltitle = this.brief;
		if (this.creation_date === null) this.creation_date = "";
		if (this.valid_from === null) this.valid_from = this.creation_date;
		if (this.valid_to === null) this.valid_to = "";
		if (this.state === null) {
			var f = this.valid_from; 
			var t = this.valid_to;
			this.state = "current";
			if (t !== "" && Date.parse(t) < today) {
				this.state = "past";
			} else if (f !== "" && Date.parse(f) > today+msPerDay) {
				this.state = "future";
			}
		}
		if (this.fold_id === null) this.fold_id = "";
	}
	// initialisation
	item_dict[name] = this;
}


// -- News objects ---------------------------------------------------------

function news_list(v,l) {
	this.initialise(v,l);

}
news_list.prototype = new basic_item_list();

var news_items = new news_list();

function news_views(parent) {
	this.parent = parent;
	this.dateline = function(s) {
		var a = this.parent.author; 
		var res = this.parent.creation_date + " "+ (a?(typeof(a) == "string"?a:a.views.href("initials")):"");
		return(this.addstyle(s,res));
	}
	this.full = function(s) {
		var res = '<h3>'+this.parent.headline+'</h3>'
			+ this.dateline(s+" dateline") + "<br>"
			+ this.addstyle(s,this.parent.full);
		return(res);
	};
	this.indexitem = function(s) {return(this.dateline(s+" dateline") + "<br>" + this.unfold_href(s))};
}
news_views.prototype = new basic_views(null);

function news_item(name) {
	// user fields	
	this.headline = null;
	this.author = null;
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new news_views(this);
	// methods
	this.basicinit = news_item.prototype.initialise;
	this.initialise = function () {
		if (this.headline === null) this.headline = "News item";
		if (this.author === null) this.author = "";
		if (this.urlname === null) this.urlname = this.headline;
		this.basicinit();
		this.register(news_items);
	}
	// initialisation
	item_dict[name] = this;
}
news_item.prototype = new basic_item(null);

// -- Email address objects -----------------------------------------------

function email_views(parent) {
	this.parent = parent;
	this.href = function(u, s) {
		var url = this.emailaddr(null);
		var urlname = (u?this.parent[u]:(this.parent.emailbody || url));
		var t = "Send email to "+urlname;
		var title = (t?' title="'+t+'"':"");
		var style = (s?' class="'+s+'"':"");
		return("<a href='mailto:"+url+"'"+style+title+">"+urlname+"</a>")
	};
	this.emailaddr = function(s) {
		return(this.addstyle(s,this.parent.emailname + "@" + this.parent.emaildomain));
	}
}
email_views.prototype = new basic_views();

function email_item(name) {
	// user fields	
	this.emailname = null;
	this.emaildomain = null;
	this.emailbody = null;
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new email_views(this);
	// methods
	this.basicinit = email_item.prototype.initialise;
	this.initialise = function() {
		if (this.emailname === null) this.emailname = "user";
		if (this.emaildomain === null) this.emaildomain = "brighton.ac.uk";
		if (this.emailbody === null) this.emailbody = "";
		this.basicinit();
	}
	// initialisation
	item_dict[name] = this;

}
email_item.prototype = new basic_item(null);


// -- Person objects ------------------------------------------------------

function person_list(v,l) {
	this.initialise(v,l);
}
person_list.prototype = new basic_item_list();

var person_items = new person_list();


function person_views(parent) {
	this.parent = parent;
	this.full = function(s) {
		var res, i, j;
		res = "<h2>"+this.parent.formal;
		if (j=this.parent["role"]) res += " (<em>"+j+"</em>)"
		res += "</h2>";
		res += "<table>";
		var td = (s?"<td class='"+s+"'>":"<td>");
		i="position"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="address"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="phone"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="fax"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="email"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j.views.href()+"</td></tr>";
		i="homepage"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		res += "</table>";
		if (j=this.parent.interests) {
			res += "<h3>Research interests</h3>" + this.addstyle(s,j);
		}
		return(res);
	};
	this.contact = function(s) {
		var res, i, j;
		res = "<b>"+this.parent.formal+"</b><br>";
		res += this.parent.address+"<br>";
		res += "<table>";
		var td = (s?"<td class='"+s+"'>":"<td>");
		i="phone"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="fax"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="email"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j.views.href()+"</td></tr>";
		res += "</table>";
		return(res);
	};
}	
person_views.prototype = new basic_views(null);

function person_item(name) {
	// user fields	
	this.firstname = null;
	this.surname = null;
	this.title = null;
	this.fullname = null;
	this.formal = null;
	this.informal = null;
	this.citationname = null;
	this.initials = null;
	this.address = null;
	this.phone = null;
	this.fax = null;
	this.email = new email_item(name+"_email")
	this.position = null;
	this.role = null;
	this.interests = null;
	this.homepage = null;
	
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new person_views(this);
	// methods
	this.basicinit = person_item.prototype.initialise;
	this.initialise = function() {
		if (this.firstname === null) this.firstname = "Firstname";
		if (this.surname === null) this.surname = "Surname";
		if (this.title === null) this.title = "";
		if (this.fullname === null) this.fullname = this.firstname + " " + this.surname;
		if (this.formal === null) this.formal = (this.title?this.title + " " +this.fullname: this.fullname);
		if (this.informal === null) this.informal = this.firstname;
		if (this.citationname === null) this.citationname = this.fullname;
		if (this.initials === null) this.initials = this.firstname.slice(0,1)+this.surname.slice(0,1);
		if (this.address === null) this.address = "NLTG, Watts Building, University of Brighton, <br>Brighton, BN2 4GJ, UK";
		if (this.phone === null) this.phone = "+44 1273 642 900";
		if (this.fax === null) this.fax = "+44 1273 642 908";
		if (this.email) {
			if (this.email.emailname === null) this.email.emailname = this.firstname+"."+this.surname;
			this.email.initialise();
		}
		if (this.role === null) this.role = "";
		if (this.interests === null) this.interests = "";
		// set some basic properties too
		if (this.label === null) this.label = this.name;
		if (this.url === null) this.url = "/nltg/people.html#"+this.label;
		if (this.urlname === null) this.urlname = this.fullname;
		this.basicinit();
		this.register(person_items);
	}
	// initialisation
	item_dict[name] = this;
}
person_item.prototype = new basic_item(null);

// -- Topic objects -----------------------------------------------------------

function topic_list(v,l) {
	this.initialise(v,l);
}
topic_list.prototype = new basic_item_list();

var topic_items = new topic_list();

function topic_views(parent) {
	this.parent = parent;
	this.brief = function(s) {return('<b>'+this.parent.topic_name+':</b> '+this.addstyle(s,this.parent.brief))+"<br>"};
	this.full = function(s) {return('<h3>'+this.parent.topic_name+'</h3>'+this.addstyle(s,this.parent.full))};
}
topic_views.prototype = new basic_views(null);

function topic_item(name) {
	// user fields	
	this.topic_name = null;
	this.glossary = null;
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new topic_views(this);
	//methods
	this.basicinit = topic_item.prototype.initialise;
	this.initialise = function() {
		if (this.topic_name === null) this.topic_name = ""; 
		if (this.glossary === null) this.glossary = "";
		this.basicinit();
		this.register(topic_items);
	}
	// initialisation
	item_dict[name] = this;
}
topic_item.prototype = new basic_item(null);

function glossary_list(v,l) {
	this.get_item = function(i) {
		return(get_item(this.items[i].split(":")[1]));
	}
	this.initialise(v,l);
}
glossary_list.prototype = new topic_list();

var glossary_items = new glossary_list();


function glossary_item(name) {
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new topic_views(this);
	//methods
	this.topicinit = glossary_item.prototype.initialise;
	this.initialise = function() {
		this.topicinit();
		glossary_items.add(this.topic_name+":"+this.name);
		this.register(glossary_items);
	}
	// initialisation
	item_dict[name] = this;
}
glossary_item.prototype = new topic_item(null);

function project_list(v,l) {
	this.initialise(v,l);
}
project_list.prototype = new topic_list();

var project_items = new project_list();

function project_views(parent) {
	this.parent = parent;
	this.full = function(s) {
		var res, i, j;
		res = "<div>";
		if (j=this.parent["logo"])
			res += "<img src='"+j+"' style='float:right;'></img>";
		res += "<h2>";
		if (j=this.parent["acronym"]) res += j+" - ";
		res += this.parent.title + "</h2>";
		res += "<table>";
		var td = (s?"<td class='"+s+"'>":"<td>");
		i="investigators"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="participants"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="start"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		i="end"; if (j=this.parent[i]) res += "<tr valign=top>"+td+i+":</td>"+td+j+"</td></tr>";
		res += "</table>";
		if (j=this.parent["abstract"]) {
			res += "<h3>Abstract</h3>" + this.addstyle(s,j);
		}
		res += "</div>";
		return(res);
	};
}	
project_views.prototype = new topic_views(null);

function project_item(name) {
	// user fields
	this.title = null;
	this.acronym = null;
	this.type = null;
	this.logo = null;
	this.partners = null;
	this.funding = null;
	this.investigators = null;
	this.participants = null;
	this.start = null;
	this.end = null;
	// system fields
	this.name = name;
	this.links = new basic_links(this);
	this.views = new project_views(this);
	//methods
	this.topicinit = project_item.prototype.initialise;
	this.initialise = function() {
		if (this.acronym === null) this.acronym = this.name;
		if (this.title === null) this.title = this.acronym;
		if (this.type === null) this.type = "research project";
		if (this.partners === null) this.partners = "University of Brighton";
		if (this.participants === null) this.participants = this.investigators;
		if (this.topic_name === null) this.topic_name = this.acronym;
		if (this.brief === null) this.brief = this.title;
		if (this.urlname === null) this.urlname = this.acronym;
		if (this.valid_from === null) this.valid_from = this.start;
		if (this.valid_to === null) this.valid_to = this.end;
		if (this.glossary === null) {
			with (this.glossary = new glossary_item(this.name+"_glossary")) {
				brief = this.brief;
				full = this.full;
				topic_name = this.topic_name;
				initialise();
			}
		}
		this.topicinit();
		this.register(project_items);
	}
	// initialisation
	item_dict[name] = this;
}
project_item.prototype = new topic_item(null);

