//findables:
//	BROWSERHACK for browser hacks

var elms = {}; //carea, fgbts, cbox, cbottom
var curpage = "";
var curpages = {"SecHome":"","SecProjects":"SecCategory","SecAbout":"SecAcademic"}; //section current pages
var lastheight = 0;
var ObjPrefs = {}; //"HonorCode"
ObjPrefs["HonorCode"] = "no";
var hman;	//history manager
var site_loaded = false;
var loadfunc = null;

//Body load call
window.addEvent("domready", function() {
	//BROWSERHACK: IE doesn't like the PNG fix.
	var sfx = "";
	if (window.ie6) {
		sfx = "ie6/"
		document.bgColor = "#E9EFEE";
	} else {
		document.bgColor = "#666666";
	}
	Progress.init();
	Progress.show();
	var reqimgs = 
	["BG","BotTop",
	"Home","Projects","About",
	sfx+"HomeOver",sfx+"ProjectsOver",sfx+"AboutOver"];
	reqimgs.each(function(el,i){reqimgs[i] = "img/" + el + ".png";});
	new Asset.images(reqimgs, {
		onProgress: function(i) {
			Progress.set(i/reqimgs.length);
		},
		onComplete: function() {
			Progress.hide(false);
			create();
		}
	});
	hman = new HistoryManager();
    hman.addEvent('onHistoryChange',historychange);
    var state = hman.getCurrentLocation();
    hman.fireEvent('onHistoryChange',state);
});
//set the base buttons to a given section
function setbasebtns(sec) {
	var snames = ["SecHome","SecProjects","SecAbout"];
	snames.remove(sec);
	snames.each(function(el,i) {
		$(el).fx.opacity.set(0.01);
	});
	$(sec).fx.opacity.set(0.99);
}
//for abbreviating sections in the browser history
var statedict = {
	"":"",
	"SecHome":"home",
	"SecProjects":"proj",
	"SecAbout":"about",
	"SecCategory":"category",
	"SecSearch":"search",
	"SecSelected":"sel",
	"SecPersonal":"personal",
	"SecAcademic":"academic",
	"SecContact":"contact"
};
function historychange(theid) {
	loadfunc = function() {
		var id = this.id;
		if (!id || id == "") {
			setpage("SecHome",false);
		} else {
			//break apart the id
			idarr = id.split("/");
			switch (idarr[0]) {
				case statedict["SecHome"]:
					setbasebtns("SecHome");
					setpage("SecHome",false); 
					break;
				case statedict["SecProjects"]:
					setbasebtns("SecProjects");
					setpage("SecProjects", false, function() {
						if (this.idarr.length > 1) {
							switch (this.idarr[1]) {
								case statedict["SecCategory"]:
									ObjProjects.setpage("SecCategory", false);
									break;
								case statedict["SecSearch"]:
									ObjProjects.setpage("SecSearch", false);
									break;
								case statedict["SecSelected"]:
									ObjProjects.setpage("SecSelected", false);
									if (this.idarr.length > 2) {
										ObjProjects.ObjSelected.setproj(this.idarr[2], function() {});
									}
									break;
							}
						}
					}.bind({"idarr":idarr}));
					break;
				case statedict["SecAbout"]:
					setbasebtns("SecAbout");
					setpage("SecAbout", false, function() {
						if (this.idarr.length > 1) {
							switch (this.idarr[1]) {
								case statedict["SecPersonal"]:
									ObjAbout.setpage("SecPersonal", false);
									break;
								case statedict["SecAcademic"]:
									ObjAbout.setpage("SecAcademic", false);
									break;
								case statedict["SecContact"]:
									ObjAbout.setpage("SecContact", false);
									break;
							}
						}
					}.bind({"idarr":idarr}));
			}
		}		
	}.bind({"id":theid});
	if (site_loaded) {
		loadfunc();
	}
}

function create() {
	//central content area
	var carea = new Element("div");
	carea.id = "carea";
	carea.injectInside(document.body);
	carea.fx = {};
	carea.fx.top = new Fx.Style(carea, "top").set(-100);
	carea.fx.height = new Fx.Style(carea, "height").set(0);
	carea.fx.left = new Fx.Style(carea, "left");
	elms.carea = carea;

	//bottom button area
	var cbottom = new Element("div");
	cbottom.id = "cbottom";
	var bgbts = [new Element("img"), new Element("img"), new Element("img")];
	var fgbts = [new Element("img"), new Element("img"), new Element("img")];
	var bottop = new Element("img").setStyles({
		"position":"absolute",
		"left":"0px","top":"0px"});
	bottop.src = "img/BotTop.png";
	bottop.injectInside(cbottom);
	bgbts.each(function(el,i) {
		el.src = "img/" + this.names[i] + ".png";
		//BROWSERHACK: ie6 transparency fix
		fgbts[i].src = "img/" + ((window.ie6) ? "ie6/" : "") + this.names[i] + "Over.png";
		fgbts[i].id = "Sec" + this.names[i];
		var btpos = {"position":"absolute","left":this.lefts[i],"top":"58px","cursor":"pointer"};
		el.setStyles(btpos); fgbts[i].setStyles(btpos);
		el.injectInside(cbottom); fgbts[i].injectInside(cbottom);
		fgbts[i].fx = {};
		fgbts[i].fx.opacity = new Fx.Style(fgbts[i], "opacity").set(0.01);
		fgbts[i].addEvent("mouseover", function() {
			this.fx.opacity.stop();
			this.fx.opacity.start(0.99);
		});
		fgbts[i].addEvent("mouseout", function() {
			if (curpage != this.id) {
				this.fx.opacity.stop();
				this.fx.opacity.start(0.01);
			}
		});
		fgbts[i].addEvent("mousedown", function() {
			if (curpage != this.id) {
				$(curpage).fx.opacity.stop();
				$(curpage).fx.opacity.start(0.01);
				hman.addState(statedict[this.id] + "/" + statedict[curpages[this.id]]);
				setpage(this.id,false, function() {
					if (curpageobj.setpage) {
						curpageobj.setpage(curpageobj.curpage);
					}
				});
			}
		});
	},{
		names:["Home", "Projects", "About"],
		lefts:[0,178,321]
	});
	elms.fgbts = fgbts;
	elms.cbottom = cbottom;
	cbottom.injectInside(carea);
	//home is the first section shown
	$("SecHome").fx.opacity.set(0.99);
	
	//content placement div
	var cbox = new Element("div");
	cbox.id = "cbox";
	cbox.fx = {};
	cbox.fx.height = new Fx.Style(cbox, "height");
	cbox.injectInside(carea);
	elms.cbox = cbox;
	
	mainlayout(0,true); //this is so things don't fly in from upper left
	doresize();
	loadfunc();
	site_loaded = true;
	carea.fx.top.start(0);
}
window.addEvent("resize", function() {doresize();});
contchain = [];
function doresize(continuation) {
	var doml = function() {
		var maxh = (curpageobj == null) ? 0 : curpageobj.getMaxH();
		var minh = (curpageobj == null) ? 0 : curpageobj.getMinH();
		var curh = window.getHeight() - 120;
		curh = Math.min(Math.max(minh,curh),maxh);
		mainlayout(curh,false);
	};
	if (continuation) {
		contchain.push(continuation);
	}
	setTimeout(doml,100);
}
function mainlayout(height,immediate) {
	lastheight = height;
	var fn = (immediate) ? "set" : "start";
	elms.carea.fx.height.stop();
	elms.carea.fx.left.stop();
	elms.carea.fx.height[fn](height);
	elms.carea.fx.left[fn]((window.getWidth() - 498)/2);
	
	var cont = function() {
		//Ugly hack x10000
		contchain.each(function(el,i) {el();});
		contchain = [];
		globallayout(immediate);
	};
	
	elms.cbox.fx.height.stop();
	//just set it if we're close.
	if (elms.cbox.fx.height && Math.abs(elms.cbox.fx.height.now - (height+10)) < 15) {
		elms.cbox.fx.height.set(height+10);
		cont();
	} else {
		elms.cbox.fx.height[fn](height+10).chain(cont);
	}
}
//callback to refresh screen layout for all components
function globallayout(immediate) {
	if (curpageobj != null) {
		curpageobj.layout(parseInt(elms.cbox.getStyle("height"),10),immediate);
	}
}
function setpage(name,immediate,continuation) {
	if (name == curpage) {
		if (continuation) {
			continuation();
		}
		return;
	}
	var cprev = curpageobj;
	curpageobj.hide(immediate, function() {
		elms.cbottom.removeChild(cprev.main);
	});
	
	switch (name) {
	case "SecHome":
		curpageobj = ObjHome;
		break;
	case "SecProjects":
		curpageobj = ObjProjects;
		break;
	case "SecAbout":
		curpageobj = ObjAbout;
		break;
	default:
		console.log("unknown section!");
	}
	
	curpageobj.getButtons(function(elm) {
		elm.injectInside(elms.cbottom);
		curpageobj.show(immediate);	
		if (this.continuation) {
			this.continuation();
		}
	}.bind({"continuation":continuation}));
	curpage = name;
}

var Styles = {
	title:{"font-size":"2em","margin-bottom":"4px","margin-top":"10px"},
	head:{"font-size":"1.25em","border-bottom":"2px dotted #CCCCCC",
	"margin-bottom":"3px", "margin-top":"10px","font-weight":"bold"},
	body:{"font-size":"1.2em"},
	list:{"margin":"0px","padding-left":"20px"},
	li:{"margin-left":"0px"}
};

var ObjHome = {
	loaded: false,
	main: null,
	featured: null,
	projover: false,
	dragging: false,
	ht: 350,
	loadRes: function(continuation) {
		if (!this.loaded) {
			this.loaded = true;
			Progress.show();
			
			//BROWSERHACK: ie6 transparency
			var sfx = ".png";
			var pfx = "";
			if (window.ie6) {
				sfx = ".gif"
				pfx = "ie6/";
			}
			var imgs = [pfx+"personal_expl"+sfx,pfx+"projects_expl"+sfx,pfx+"Credits"+sfx,
				pfx+"CreditsOver"+sfx,pfx+"FeaturedBG"+sfx,"LeftFadeOut.png","RightFadeOut.png",
				pfx+"TitleLogo"+sfx,"Close.png","CloseOver.png"];
			var reqimgs = [];
			imgs.each(function(el,i) {reqimgs.push("img/home/" + el);});
			var loader = new Asset.images(reqimgs, {
				onProgress: function(i) {
					Progress.set(i/reqimgs.length);
				},
				onComplete: function() {
					Progress.hide(false);
					var req = new Json.Remote("proj/homedex.js", {
						onComplete: function(jobj) {
							this.hobj.featured = jobj[0];
							this.hobj.snippets = jobj[1];
							this.hobj.newscont = jobj[2];
							this.hobj.credcont = jobj[3];
							this.continuation();
						}.bind({"hobj":this.hobj,"continuation":this.continuation})
					}).send();
				}.bind({"hobj":this,"continuation":continuation})
			});
		} else {
			continuation();
		}
	},
	getButtons: function(continuation) {
		if (!this.loaded) {
			this.loadRes(function() {
				this.main = new Element("div").setStyles({
					"position":"absolute","left":"5px","top":"0px","height":this.ht,"z-index":2
				}).injectInside(elms.carea);
				
				this.titleh = new Element("div").setStyles({
					"position":"absolute","left":"106px","width":"274px","height":"40px","top":"-50px"
				}).injectInside(this.main);
				this.titleh.fx = {};
				this.titleh.fx.top = new Fx.Style(this.titleh, "top");
				
				this.titleh.grad = new Element("div").setStyles({
					"position":"absolute","left":"9px","width":"256px","height":"38px","top":"1px"
				}).injectInside(this.titleh);
				this.titleh.grad.els = [];
				var subw = 2<<4;
				this.numgrads = 256/subw;
				for (var x = 0; x < this.numgrads; ++x) {
					var gel = new Element("div").setStyles({
						"position":"absolute","width":subw+"px","height":"38px","left":x*subw+"px","top":"1px"
					}).injectInside(this.titleh.grad);
					this.titleh.grad.els.push(gel);
				}
				var rndcolor = function() {
					col = [0,0,0];
					for (var x = 0; x < col.length; ++x) {
						col[x] = Math.floor(Math.random()*255);
					}
					return col;
				};
				this.curcolors = [];
				var rc = rndcolor();
				for (var x = 0; x < this.numgrads; ++x) {
					this.curcolors.push(rc);
				}
				this.nextcolor = rndcolor();
				var approachcolor = function(prev,next) {
					var fac = 0.95;
					return [
						Math.floor(prev[0]*fac + next[0]*(1-fac)),
						Math.floor(prev[1]*fac + next[1]*(1-fac)),
						Math.floor(prev[2]*fac + next[2]*(1-fac))
					];	
				};
				var closecolor = function(a,b) {
					var thresh = 32;
					return 	(Math.abs(a[0] - b[0]) < thresh) &&
							(Math.abs(a[1] - b[1]) < thresh) &&
							(Math.abs(a[2] - b[2]) < thresh);
				};
				(function() {
					if (curpage != "SecHome") {
						return;
					}
					var nxtcolors = [];
					for (var x = 1; x < this.curcolors.length; ++x) {
						nxtcolors.push(this.curcolors[x]);
					}
					nxtcolors.push(approachcolor(this.curcolors[this.curcolors.length-1], this.nextcolor));
					this.curcolors = nxtcolors;
					for (var x = 0; x < this.numgrads; ++x) {
						this.titleh.grad.els[x].setStyle("background-color",
							"rgb("+nxtcolors[x][0]+","+nxtcolors[x][1]+","+nxtcolors[x][2]+")");
					}
					if (closecolor(nxtcolors[0], this.nextcolor)) {
						this.nextcolor = rndcolor();
					}
				}.bind(this)).periodical(120);
				
				//BROWSERHACK: ie6 transparency
				this.titleh.fg = new Element("img").setStyles({
					"position":"absolute","left":"0px","top":"0px"
				}).setProperty("src",(window.ie6) ? "img/home/ie6/TitleLogo.gif" : "img/home/TitleLogo.png")
				.injectInside(this.titleh);
				
				this.titleq = new Element("div").setStyles({
					"position":"absolute","left":"12px","width":"463px","height":"15px",
					"top":"42px","text-align":"center"
				}).setHTML(this.snippets[0]).injectInside(this.main);
				this.titleq.fx = {};
				this.titleq.fx.opacity = new Fx.Style(this.titleq, "opacity", {duration:1000});
				(function() {
					if (curpage != "SecHome") {
						return;
					}
					//BROWSERHACK: for some reason, periodical sometimes executes things twice.
					if (!this.lastt) {
						this.lastt = (new Date()).getTime();
					} else {
						if (Math.abs((new Date()).getTime() - this.lastt) < 1000) {
							return;
						}
					}
					if (curpage == "SecHome") {
						this.titleq.fx.opacity.start(0.01).chain(function() {
							var idx = Math.floor(Math.random() * this.snippets.length);
							this.titleq.setHTML(this.snippets[idx]);
							this.titleq.fx.opacity.start(1.0);
						}.bind(this));
					}
				}.bind(this)).periodical(7000);
				
				this.news = new Element("div").setStyles({
					"position":"absolute","left":"20px","width":"448px","top":-(this.ht-240)+"px",
					"height":(this.ht-240)+"px","overflow-y":"scroll"
				}).injectInside(this.main);
				//this.news.setStyle("border","1px solid #DDDDDD");
				//BROWSERHACK for Safari 2 - doesn't support overflow-y
				if (window.webkit419) {
					this.news.setStyles({"overflow":"auto"});
				}
				this.news.fx = {};
				this.news.fx.top = new Fx.Style(this.news, "top");
				
				var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
				for (var x = 0; x < this.newscont.length; ++x) {
					var it = new Element("div").setStyles({
					}).injectInside(this.news);
					var nitem = this.newscont[x];
					var digits = nitem[0].split("/");
					var dh = 20;
					var datebox = new Element("div").setStyles({
						"position":"relative","width":(dh*4.7)+"px","float":"left"
					}).injectInside(it);
					var thedig = digits[1];
					if (thedig.length == 1) {
						thedig = "0" + thedig;
					}
					var dateday = new Element("div").setStyles({
						"position":"absolute","top":(-dh/4)+"px","width":(dh*2)+"px","left":(dh*2+1)+"px",
						"text-align":"left","font-size":(dh*2)+"px"
					}).setHTML(thedig).injectInside(datebox);
					var datemo = new Element("div").setStyles({
						"position":"absolute","top":"0px","width":(dh*2)+"px","left":"0px",
						"text-align":"right","font-size":(dh)+"px","font-weight":"bold"
					}).setHTML(months[parseInt(digits[0])-1].toUpperCase()).injectInside(datebox);
					var dateyear = new Element("div").setStyles({
						"position":"absolute","top":dh+"px","width":(dh*2)+"px","left":"0px",
						"text-align":"right","font-size":(dh*2/3)+"px","font-weight":"bold"
					}).setHTML(digits[2]).injectInside(datebox);
					var cont = new Element("div").setStyles({
						"position":"relative","font-size":"120%","padding-left":(dh*4.7)+"px",
						"padding-right":"2px"
					}).setHTML(nitem[1]).injectInside(it);
				}
				
				this.fproj = new Element("div").setStyles({
					"position":"absolute","left":"4px","top":"-190px"
				}).injectInside(this.main);
				this.fproj.fx = {};
				this.fproj.fx.top = new Fx.Style(this.fproj,"top");

				this.pindbox = new Element("div").setStyles({
					"position":"absolute","left":"26px","top":"155px","height":"24px","width":"428px","overflow":"hidden"
				}).injectInside(this.fproj);
				var makepind = function() {
					var pind = new Element("div").setStyles({
						"position":"absolute","left":"0px","top":"0px","width":"428px","height":"24px",
						"background-color":"#3399FF"
					});
					pind.scrolll = new Element("img").setStyles({
						"position":"absolute","opacity":"0.01","top":"0px","left":"0px"
					}).setProperty("src","img/home/FeatDragLeft.png").injectInside(pind);
					pind.scrolll.fx = new Fx.Style(pind.scrolll, "opacity");
					pind.scrollr = new Element("img").setStyles({
						"position":"absolute","opacity":"0.01","top":"0px","right":"0px"
					}).setProperty("src","img/home/FeatDragRight.png").injectInside(pind);
					pind.scrollr.fx = new Fx.Style(pind.scrollr, "opacity");
					pind.highlight = function() {
						[this.scrolll, this.scrollr].each(function(el,i) {
							el.fx.stop();
							el.fx.start(0.8);
						});
					}.bind(pind);
					pind.delight = function() {
						[this.scrolll, this.scrollr].each(function(el,i) {
							el.fx.stop();
							el.fx.start(0.01);
						});						
					}.bind(pind);
					return pind;
				};
				this.pind1 = makepind();
				this.pind1.injectInside(this.pindbox);
				this.pind2 = makepind();
				this.pind2.injectInside(this.pindbox);

				//BROWSERHACK: ie6 transparency
				this.fproj.bg = new Element("img").setStyles({
					"position":"absolute","left":"17px","top":"0px"
				}).setProperty("src",
				(window.ie6) ? "img/home/ie6/FeaturedBG.gif" : "img/home/FeaturedBG.png")
				.injectInside(this.fproj);

				this.pindover = new Element("div").setStyles({
					"position":"absolute","left":"26px","top":"155px","height":"24px","width":"428px"
				}).injectInside(this.fproj);
				//BROWSERHACK: make the thing draggable if we're in IE.
				if (window.ie) {
					this.pindover.setStyles({
						"background":"white","opacity":"0.01"
					});
				}
				this.pindover.makeDraggable({
					onStart: function() {
						this.dragging = true;
						this.dragstart = parseInt(this.pind1.getStyle("left"));
					}.bind(this),
					onDrag: function() {
						var left = parseInt(this.pindover.getStyle("left"))+this.dragstart;
						while (left < 0) {
							left = left + 428;
						}
						if (left > 428) {
							left = left - 428;
							this.pindover.setStyle("left",left);
						} 
						this.sc1.left = -(left/428)*this.sc1.width;
						this.sc2.left = -(left/428)*this.sc1.width+this.sc1.width+this.sc1.pad;
						this.tickfcn();
					}.bind(this),
					onComplete: function() {
						this.dragging = false;
						this.pindover.setStyles({
							"left":"26px",
							"top":"155px"
						});
					}.bind(this)
				});
				this.pindover.addEvent("mouseover", function() {
					this.pind1.highlight();
					this.pind2.highlight();
				}.bind(this));
				this.pindover.addEvent("mouseout", function() {
					this.pind1.delight();
					this.pind2.delight();
				}.bind(this));

				this.fproj.sarea = new Element("div").setStyles({
					"position":"absolute","left":"27px","top":"19px","width":"426px","height":"80px","overflow":"hidden"
				}).injectInside(this.fproj);
								
				var mkscroll = function() {
					var pad = 2;
					var sbw = (128+pad*2)*this.featured.length;
					var sbox = new Element("div").setStyles({
						"position":"absolute","width":sbw
					});
					sbox.subdivs = [];
					sbox.width = sbw;
					sbox.pad = pad;
					for (var x = 0; x < this.featured.length; ++x) {
						var tdil = (128+pad*2)*x;
						var tdi = new Element("div").setStyles({
							"position":"absolute","left":tdil+"px","top":(pad*2)+"px",
							"height":"76px","width":(128+pad*2)+"px","background-color":"white","opacity":"0.01"
						}).injectInside(sbox);
						tdi.fx = new Fx.Style(tdi,"opacity");
						sbox.subdivs.push(tdi);
						var timg = new Element("img").setStyles({
							"position":"absolute","left":tdil+"px","top":(pad)+"px","opacity":"1.0"
						}).setProperty("src","proj/" + this.featured[x][0] + "/thumb.png").injectInside(sbox);
						timg.tdi = tdi;
						timg.index = x;
						timg.hobj = this;
						timg.addEvent("mouseover", function() {
							this.hobj.projover = true;
							var proj = this.hobj.featured[this.index];
							var desc = "";
							proj[1].each(function(el,i) {
								if (el[0] == "desc") {
									desc = el[1];
								}
							});
							var descvisit = " <span style='color:#666666; font-style:italic'>(click to visit)</span>";
							this.hobj.fproj.cdiv.setHTML(desc + descvisit);
							this.tdi.fx.stop();
							this.tdi.fx.start(1.0);
						});
						timg.addEvent("mouseout", function() {
							this.hobj.projover = false;
							//set text back to default
							this.hobj.fproj.cdiv.setHTML(this.hobj.fproj.cdiv.def);
							this.tdi.fx.stop();
							this.tdi.fx.start(0.01);
						});
						timg.addEvent("mousedown", function() {
							var proj = this.hobj.featured[this.index][0];
							setbasebtns("SecProjects");
							setpage("SecProjects", false, function() {
								hman.addState(statedict["SecProjects"] + "/" + statedict["SecSelected"] + "/" + proj);
								ObjProjects.ObjSelected.setprojshow(proj);
							});							
						});
					}
					return sbox;
				}.bind(this);
				this.sc1 = mkscroll();
				this.sc1.injectInside(this.fproj.sarea);
				this.sc1.left = 0;
				this.sc2 = mkscroll();
				this.sc2.left = this.sc1.width+this.sc1.pad;
				this.sc2.injectInside(this.fproj.sarea);
				
				var pindw = 1/(this.sc1.width/428)*428;
				this.pind1.setStyles({"width":pindw+"px"});
				this.pind2.setStyles({"width":pindw+"px"});
				
				var setlefts = function() {
					this.sc1.setStyle("left",this.sc1.left);
					this.sc2.setStyle("left",this.sc2.left);
				}.bind(this);
				setlefts();
				this.tickfcn = function() {
					//only execute if we're on the home page
					if (curpage != "SecHome") {
						return;
					}
					var vel = 1;
					var fudge = 10;
					if (!this.projover && !this.dragging) {
						this.sc1.left -= vel;
						this.sc2.left -= vel;
					}
					this.pind1.setStyles({"left": -(this.sc1.left/this.sc1.width)*428});
					this.pind2.setStyles({"left": -(this.sc2.left/this.sc2.width)*428});
					if (this.sc1.left < -(this.sc1.width - fudge)) {
						this.sc1.left = this.sc2.left + this.sc2.width+this.sc2.pad;
					}
					if (this.sc2.left < -(this.sc2.width - fudge)) {
						this.sc2.left = this.sc1.left + this.sc1.width+this.sc1.pad;
					}
					setlefts();
				}.bind(this);
				this.tickfcn.periodical(30);

				this.fproj.fleft = new Element("img").setStyles({
					"position":"absolute","left":"0px","top":"0px"
				}).setProperty("src","img/home/LeftFadeOut.png").injectInside(this.fproj.sarea);
				this.fproj.fright = new Element("img").setStyles({
					"position":"absolute","right":"0px","top":"0px"
				}).setProperty("src","img/home/RightFadeOut.png").injectInside(this.fproj.sarea);
			
				this.fproj.cdiv = new Element("div").setStyles({
					"position":"absolute","left":"26px","top":"98px","width":"425px","height":"53px",
					"padding":"1px","padding-left":"4px","padding-right":"4px","font-size":"14px"
				}).injectInside(this.fproj);
				this.fproj.cdiv.def = "<br><div style='text-align:center;'>Hover over a project above or drag below to scroll</div>";
				this.fproj.cdiv.setHTML(this.fproj.cdiv.def);
				
				this.bmain = new Element("div").setStyles({
					"position":"absolute",
					"left":"0px","top":(this.ht+98)+"px"
				}).injectInside(this.main);
				
				//BROWSERHACK: ie6 transparency
				this.pers_expl = new Element("img")
					.setProperty("src",(window.ie6) ? "img/home/ie6/personal_expl.gif" : "img/home/personal_expl.png")
					.setStyles({"position":"absolute","left":"315px","bottom":"0px","opacity":"0.0"})
					.injectInside(this.bmain);
				this.pers_expl.fx = new Fx.Styles(this.pers_expl);

				//BROWSERHACK: ie6 transparency
				this.proj_expl = new Element("img")
					.setProperty("src",(window.ie6) ? "img/home/ie6/projects_expl.gif" : "img/home/projects_expl.png")
					.setStyles({"position":"absolute","left":"194px","bottom":"0px","opacity":"0.0"})
					.injectInside(this.bmain);
				this.proj_expl.fx = new Fx.Styles(this.proj_expl);

				this.credits = new Element("div")
					.setStyles({"position":"absolute","left":"50px","bottom":"0px","width":"121px","height":"36px",
					"display":"none"})
					.injectInside(this.bmain);
				//BROWSERHACK: ie6 transparency
				this.credits.bg = new Element("img")
					.setProperty("src",(window.ie6) ? "img/home/ie6/Credits.gif" : "img/home/Credits.png")
					.setStyles({"position":"absolute","left":"0px","top":"0px"})
					.injectInside(this.credits);
				this.credits.fg = new Element("img")
					.setProperty("src",(window.ie6) ? "img/home/ie6/CreditsOver.gif" : "img/home/CreditsOver.png")
					.setStyles({"position":"absolute","left":"0px","top":"0px","opacity":"0.01"})
					.injectInside(this.credits);
				this.credits.fx = {};
				this.credits.fx.bottom = new Fx.Style(this.credits, "bottom");
				this.credits.fg.fx = {};
				this.credits.fg.fx.opacity = new Fx.Style(this.credits.fg, "opacity");
				this.credits.fg.addEvent("mouseover", function() {
					this.fx.opacity.stop();
					this.fx.opacity.start(0.99);
				});
				this.credits.fg.addEvent("mouseout", function() {
					this.fx.opacity.stop();
					this.fx.opacity.start(0.01);
				});
				this.credits.fg.addEvent("mousedown", function() {
					Whitebox.requestsize(400,null);
					var main = new Element("div").setStyles({
						"position":"absolute",
						"left":"3px","top":"3px","bottom":"3px","right":"3px",
						"padding-left":"5px",
						"padding-right":"10px",
						"overflow":"auto"
					});
					new Element("div").setHTML("Site Credits")
						.setStyles(Styles.title).injectInside(main);
					for (var x = 0; x < this.credcont.length; ++x) {
						var sub = this.credcont[x];
						new Element("div").setStyles(Styles.head)
							.setHTML(sub[0]).injectInside(main);
						var mlist = new Element("ul").setStyles(Styles.list)
							.injectInside(main);
						for (var y = 0; y < sub[1].length; ++y) {
							var theli = new Element("li").setStyles(Styles.li)
								.setStyles(Styles.body).injectInside(mlist);
							for (var z = 0; z < sub[1][y].length; ++z) {
								var it = sub[1][y][z];
								if (it.length == 1) {
									new Element("span").setHTML(it[0]).injectInside(theli);
								} else {
									new Element("a")
										.setHTML(it[0])
										.setProperty("href",it[1])
										.setProperty("target","_blank")
										.injectInside(theli);
								}
							}
						}
					}
					Whitebox.setContent(main);
					Whitebox.show();
				}.bind(this));
				
				continuation(new Element("div"));
			}.bind(this));
		} else {
			continuation(new Element("div"));
		}
	},
	show: function(immediate) {
		if (this.loaded) {
			this.titleh.fx.top[(immediate) ? "set" : "start"](5)
				.chain(function() {;
					this.fproj.fx.top[(immediate) ? "set" : "start"](this.ht - 165);
					this.news.fx.top[(immediate) ? "set" : "start"](64);
					this.titleq.fx.opacity[(immediate) ? "set" : "start"](1.0);
					this.titleq.setStyle("display","block");
					this.credits.fx.bottom[(immediate) ? "set" : "start"](100,50);
					this.credits.setStyle("display","block");		
				}.bind(this));
			doresize(function() {
					this.pers_expl.fx.options.duration = 1500;
					this.pers_expl.fx[(immediate) ? "set" : "start"]({
						"bottom":[100,40],
						"opacity":[0.0,1.0]
					});
					this.proj_expl.fx.options.duration = 1500;
					this.proj_expl.fx[(immediate) ? "set" : "start"]({
						"bottom":[90,30],
						"opacity":[0.0,1.0]
					});		
			}.bind(this));
		}
	},
	hide: function(immediate, remover) {
		if (this.loaded) {
			this.fproj.fx.top[(immediate) ? "set" : "start"](-190);
			this.news.fx.top[(immediate) ? "set" : "start"](-(this.ht + 250));
			this.titleh.fx.top[(immediate) ? "set" : "start"](-40);
			this.titleq.fx.opacity.stop();
			this.titleq.fx.opacity[(immediate) ? "set" : "start"](0.0);
			this.titleq.setStyle("display","none");
			this.pers_expl.fx.stop();
			this.pers_expl.fx.options.duration = 300;
			this.pers_expl.fx[(immediate) ? "set" : "start"]({
				"bottom":[40,100],
				"opacity":[1.0,0.0]
			});
			this.proj_expl.fx.stop();
			this.proj_expl.fx.options.duration = 300;
			this.proj_expl.fx[(immediate) ? "set" : "start"]({
				"bottom":[30,90],
				"opacity":[1.0,0.0]
			});
			this.credits.fx.bottom[(immediate) ? "set" : "start"](50,100).chain(function() {
				this.credits.setStyle("display","none");	
			}.bind(this));
		}
	},
	getMaxH: function() {
		return this.ht;
	},
	getMinH: function() {
		return this.ht;
	},
	layout: function(height,immediate) {
		
	}
};

SCROLLWIDTH = 15;

//a sortable project list with the given:
//	w: element width
//	h: element height
function ProjList(w,h,lst,indices) {
	this.loaded = false;
	this.width = w;
	this.datewidth = 60;
	this.sizewidth = 20;
	this.height = h;
	this.wremain = this.width - 128 - this.sizewidth - this.datewidth - SCROLLWIDTH;
	this.refreshData(lst,indices);
	
	//BROWSERHACK: ie6 seems to not like the forward and reverse indicators
	if (window.ie6) {
		ProjList.FWDIND = "\\/";
		ProjList.REVIND = "/\\";
	}
}
ProjList.FWDIND = "&#9662;";
ProjList.REVIND = "&#9652;";
//	lst: the list of projects
//	indices: an optional list of indices to filter the list
ProjList.prototype.refreshData = function(lst,indices) {
	if (indices) {
		this.lst = [];
		indices.each(function(el,i) { this.lst.push(lst[el]); }.bind(this));
	} else {
		this.lst = lst;
	}
	
	if (!this.loaded) {
		this.loaded = true;
		this.mainbox = new Element("div").setStyles({
			"position":"absolute",
			"width":this.width+"px",
			"height":this.height+"px"
		});
		this.getHeader().injectInside(this.mainbox);
		this.scrollbox = new Element("div").setStyles({
			"position":"absolute",
			"width":this.width+"px",
			"height":Math.max(this.height-41,0)+"px",
			"left":"0px",
			"top":"41px",
			"overflow-y":"scroll",
			"overflow-x":"hidden"
		}).injectInside(this.mainbox);
		//BROWSERHACK for Safari 2 - doesn't support overflow-y
		if (window.webkit419) {
			this.scrollbox.setStyles({"overflow":"auto"});
		}
		this.scrollbox.fx = {};
		this.scrollbox.fx.height = new Fx.Style(this.scrollbox,"height");
	}
	
	this.scrollbox.setHTML("");
	this.currows = [];
	//inject the rows
	this.lst.each(function(el,i) {
		var row = this.getRow(i,el);
		this.currows.push(row);
		row.injectInside(this.scrollbox);
	}.bind(this));
	this.sort();
	doresize(function() {globallayout(false);});
};
ProjList.prototype.layout = function(height,immediate) {
	this.height = height;
	this.mainbox.setStyle("height",Math.max(this.height,0));
	this.scrollbox.fx.height[(immediate)?"set":"start"](Math.max(this.height-41,0));
};
ProjList.prototype.sort = function() {
	if (this.sel) {
		var alphacomp = function(a,b) {
			if (a == b) {
				return 0;
			} else {
				return (a.toLowerCase() < b.toLowerCase()) ? -1 : 1;
			}
		};
		var numstrcomp = function(a,b) {
			var an = parseInt(a,10); var bn = parseInt(b,10);
			return a - b;	
		};
		var datecomp = function(a,b) {
			var da = a.split("/"); var db = b.split("/");
			var cmpone = numstrcomp(da[1],db[1]);
			if (cmpone == 0) {
				return numstrcomp(da[0],db[0]);
			} else {
				return cmpone;
			}
		};
		var comp = function(a,b) {
			switch (this.sel.hname) {
			case "project":
				return alphacomp(a.info.loc,b.info.loc);
			case "title / description":
				return alphacomp(a.info.name,b.info.name);
			case "category":
				return alphacomp(
					a.info.dct.category.join(""),
					b.info.dct.category.join(""));
			case "size":
				return numstrcomp(a.info.dct.size,b.info.dct.size);
			case "start":
				return datecomp(a.info.dct.dstart,b.info.dct.dstart);
			case "end":
				return datecomp(a.info.dct.dend,b.info.dct.dend);
			}
		}.bind(this);
		var comptwo = function(a,b) {
			return ((this.updown)?1:-1) * comp(a,b);
		}.bind(this);
		this.currows.sort(comptwo);
	}
	this.refreshRowPos();
};
ProjList.prototype.refreshRowPos = function() {
	for (var i = 0; i < this.currows.length; ++i) {
		this.currows[i].dex = i;
		this.currows[i].setStyle("top",(i*72)+"px");
		this.currows[i].setStyle("background",
			"url(img/projects/"+(((i%2)==0)?"rowbg.png":"rowbg2.png")+")");
		var rowover = function() {
			this.setStyle("background",
				"url(img/projects/"+(((this.dex%2)==0)?"rowbgo.png":"rowbg2o.png")+")");	
		};
		var rowout = function() {
			this.setStyle("background",
				"url(img/projects/"+(((this.dex%2)==0)?"rowbg.png":"rowbg2.png")+")");				
		};
		this.currows[i].removeEvents();
		this.currows[i].addEvent("mouseover",rowover);
		this.currows[i].addEvent("mouseout",rowout);
		this.currows[i].addEvent("mousedown",function() {
			hman.addState(statedict["SecProjects"] + "/" + statedict["SecSelected"] + "/" + this.info.loc);
			ObjProjects.ObjSelected.setprojshow(this.info.loc);
		});
	}	
};
ProjList.prototype.getMain = function() {
	return this.mainbox;	
};
ProjList.prototype.getInfo = function(arr) {
	var dct = {"title":"","desc":"","category":[],"size":0,"dstart":"","dend":""};
	arr.each(function(el,i) {
		switch (el[0]) {
			case "category": dct.category = el[1]; break;
			case "desc": dct.desc = el[1]; break;
			case "date": dct.dstart = el[1][0]; dct.dend = el[1][1]; break;
			case "size": dct.size = el[1]; break;
		}
	});
	return dct;
};
//rownum: the position of the row
//arr: the project info array
ProjList.prototype.getRow = function(rownum,arr) {
	var dct = this.getInfo(arr[2]);
	var row = new Element("div").setStyles({
		"position":"absolute",
		"width":this.width+"px",
		"height":"72px",
		"left":"0px",
		"top":(rownum*72)+"px",
		"font-size":"14px"
	});
	var theimg = new Element("img").setStyles({
		"position":"absolute",
		"width":"128px",
		"height":"72px",
		"left":"0px",
		"top":"0px"
	}).setProperty("src","proj/" + arr[0] + "/thumb.png")
	.injectInside(row);
	var thename = new Element("div").setStyles({
		"position":"absolute",
		"width":(this.wremain-4)+"px",
		"height":(52-6)+"px",
		"left":"128px",
		"top":"0px",
		"padding":"2px",
		"overflow":"hidden"
	}).setHTML("<b>" + arr[1] + "<" + "/b>" + ((dct.desc == "") ? "" : "<br>") + 
		"<span style='font-size:10px;line-height:1'>" + dct.desc + "<" + "/span>")
	.injectInside(row);
	var category = new Element("div").setStyles({
		"position":"absolute",
		"width":(this.wremain-2)+"px",
		"height":"20px",
		"left":"128px",
		"top":"52px",
		"padding-left":"2px"
	}).setHTML(dct.category.join("&nbsp;>&nbsp;"))
	.injectInside(row);
	new Element("div").setStyles({
		"position":"absolute",
		"left":"1px","bottom":"1px",
		"width":(this.sizewidth-5)+"px",
		"height":Math.floor(64/5*dct.size)+"px",
		"background-color":"#999999"//"#B7DBFF"
	}).injectInside(
		new Element("div").setStyles({
			"position":"absolute",
			"left":"0px","top":"2px",
			"width":(this.sizewidth-3)+"px",
			"height":"66px",
			"border":"1px solid #999999"
		}).injectInside(
			new Element("div").setStyles({
				"position":"absolute",
				"width":(this.sizewidth-1)+"px",
				"height":"72px",
				"left":(this.wremain+128)+"px",
				"top":"0px"
			}).injectInside(row)));
	var datebegin = new Element("div").setStyles({
		"position":"absolute",
		"width":this.datewidth+"px",
		"height":"36px",
		"left":(this.wremain+128+this.sizewidth)+"px",
		"top":"0px",
		"text-align":"center"
	}).setHTML(dct.dstart).injectInside(row);
	var dateend = new Element("div").setStyles({
		"position":"absolute",
		"width":this.datewidth+"px",
		"height":"36px",
		"left":(this.wremain+128+this.sizewidth)+"px",
		"top":"36px",
		"text-align":"center"
	}).setHTML(dct.dend).injectInside(row);
	row.info = {"dct":dct,"loc":arr[0],"name":arr[1]};
	return row;
};
ProjList.prototype.getHeader = function() {
	var header = new Element("div").setStyles({
		"position":"absolute",
		"width":this.width+"px",
		"height":"41px",
		"left":"0px",
		"top":"0px"
	});
	var imghead = new Element("div").setProperties({
		"hname":"project",
		"box":[1,1,(128-4),39],
		"bg":"largebg.png","bgover":"largebgover.png"
	}).setStyles("text-align:center");
	var titlehead = new Element("div").setProperties({
		"hname":"title / description",
		"box":[128,1,(this.wremain-1),20],
		"bg":"smallbg.png","bgover":"smallbgover.png"
	});
	var cathead = new Element("div").setProperties({
		"hname":"category",
		"box":[128,20,(this.wremain-1),20],
		"bg":"smallbg.png","bgover":"smallbgover.png"
	});
	//BROWSERHACK: ie6 transparency
	var sizehead = new Element("div").setProperties({
		"hname":"size",
		"box":[(this.wremain+128-47+this.sizewidth-1),1,47-7,41],
		"bg":(window.ie6) ? "ie6/sizeswish.gif" : "sizeswish.png",
		"bgover":(window.ie6) ? "ie6/sizeswishover.gif" : "sizeswishover.png",
		"bghover":(window.ie6) ? "ie6/sizeswishhover.gif" : "sizeswishhover.png",
		"noborder":true
	}).setStyles({"z-index":"40","text-align":"right","padding-right":"4px"});
	var datestart = new Element("div").setProperties({
		"hname":"start",
		"box":[(this.wremain+this.sizewidth+128-2),1,this.datewidth,20],
		"bg":"smallbg.png","bgover":"smallbgover.png"
	}).setStyles({"text-align":"center"});
	var dateend = new Element("div").setProperties({
		"hname":"end",
		"box":[(this.wremain+this.sizewidth+128-2),20,this.datewidth,20],
		"bg":"smallbg.png","bgover":"smallbgover.png"
	}).setStyles({"text-align":"center"});
	this.heads = [imghead,titlehead,cathead,sizehead,datestart,dateend];
	this.heads.each(function(el,i) {
		el.plist = this;
		el.box = (el.getProperty("box")+"").split(",");
		el.noborder = ((el.getProperty("noborder")+"") == "true");
		el.bg = el.getProperty("bg"); el.bgover = el.getProperty("bgover");
		el.hname = el.getProperty("hname");
		el.setStyles({
			"position":"absolute",
			"left":el.box[0]+"px","top":el.box[1]+"px",
			"width":el.box[2]+"px","height":el.box[3]+"px",
			"border":(el.noborder)?"":"1px solid black",
			"background":"url(img/projects/" + el.bg + ")",
			"padding-left":"3px",
			"font-size":"13px",
			"color":"white"
		}).setHTML(el.hname).injectInside(header);
		//do sorting order visual cues
		el.sorder = function(on,updown,hover) {
			var txt = el.hname;
			if (on) {
				txt += "&nbsp";
				txt += "<span style='color:" + ((hover) ? "#CCC" : "white") + "'>";
				txt += ((updown) ? ProjList.FWDIND : ProjList.REVIND);
				txt += "<" + "/span>"; 	
			}
			el.setHTML(txt);
		};
		el.highlight = function() {
			this.setStyle("z-index","20");
			this.setStyle("cursor","pointer");
			if (!this.noborder) {
				this.setStyle("border","1px solid white");
			} else {
				this.setStyle("background",
					"url(img/projects/" + el.getProperty("bghover") + ")");
			}
			el.sorder(true,(this.plist.sel == this)?(!this.plist.updown):true,true);
		};
		el.addEvent("mouseover",function() {
			this.highlight();
		});
		el.delight = function() {
			this.setStyle("cursor","default");
			if (!this.noborder) {
				this.setStyle("z-index","1");
				this.setStyle("border","1px solid black");
			} else {
				this.setStyle("background",
					"url(img/projects/" + el.getProperty("bg") + ")");
			}
			el.sorder((this.plist.sel == this),this.plist.updown,false);
		};
		el.addEvent("mouseout",function() {
			this.delight();
		});
		el.addEvent("mousedown",function() {
			var prevsel = this.plist.sel;
			this.plist.updown = (this.plist.sel == this)?(!this.plist.updown):true;
			this.plist.sel = this;
			if (prevsel != null) {
				prevsel.setStyle("background",
					"url(img/projects/" + prevsel.bg + ")");
				prevsel.delight();	
			}
			el.setStyle("background","url(img/projects/" + el.bgover + ")");
			el.highlight();
			this.plist.sort();
		});
	}.bind(this));
	return header;
};

//functions for dealing with sections
var SecFuncs = {
	loadRes: function(continuation, obj, json, dir, imgs) {
		if (!obj.loaded) {
			obj.loaded = true;
			Progress.show();
			
			var reqimgs = [];
			imgs.each(function(el,i) {reqimgs.push("img/" + dir + "/" + el + ".png");});
			var loader = new Asset.images(reqimgs, {
				onProgress: function(i) {
					Progress.set(i/reqimgs.length);
				},
				onComplete: function() {
					Progress.hide(false);
					if (this.json == null) {
						this.continuation();
					} else {
						SecFuncs.loadjson(this.continuation, this.obj, this.json);
					}
				}.bind({"obj":obj,"json":json,"continuation":continuation})
			});			
		} else {
			continuation();
		}
	},
	loadjson: function(continuation, obj, json) {
		var req = new Json.Remote(json, {
			onComplete: function(jobj) {
				this.obj.jsondone(jobj);
				this.continuation();
			}.bind({"obj":obj,"continuation":continuation})
		}).send();
	},
	//for three buttons
	getButtons: function(continuation, obj, dir, pnames, json, imgs) {
		if (!obj.loaded) {
			SecFuncs.loadRes(function() {
				main = new Element("div").setStyles({"width":"498px","height":"58px"});
				var bgbts = [new Element("img"), new Element("img"), new Element("img")];
				var fgbts = [new Element("img"), new Element("img"), new Element("img")];
				obj.main = main; obj.bgbts = bgbts; obj.fgbts = fgbts;
				bgbts.each(function(el,i) {
					//BROWSERHACK: ie6 transparency
					var pfx = (window.ie6) ? "ie6/" : "";
					el.src = "img/" + dir + "/" + pfx + this.names[i] + ".png";
					fgbts[i].src = "img/" + dir + "/" + pfx + this.names[i] + "Over.png";
					fgbts[i].id = "Sec" + this.names[i];
					var btpos = {"position":"absolute","left":this.lefts[i],"top":"0px","cursor":"pointer"};
					el.setStyles(btpos); fgbts[i].setStyles(btpos);
					el.injectInside(main); fgbts[i].injectInside(main);
					bgbts[i].fx = {};
					bgbts[i].fx.opacity = new Fx.Style(bgbts[i], "opacity").set(0.01);
					fgbts[i].fx = {};
					fgbts[i].fx.opacity = new Fx.Style(fgbts[i], "opacity").set(0.01);
					fgbts[i].addEvent("mouseover", function() {
						this.fx.opacity.stop();
						this.fx.opacity.start(0.99);
					});
					fgbts[i].addEvent("mouseout", function() {
						if (obj.curpage != this.id) {
							this.fx.opacity.stop();
							this.fx.opacity.start(0.01);
						}
					});
					fgbts[i].addEvent("mousedown", function() {
						if (obj.curpage != this.id) {
							$(obj.curpage).fx.opacity.stop();
							$(obj.curpage).fx.opacity.start(0.01);
							hman.addState(statedict[obj.rootname] + "/" + statedict[this.id]);
							obj.setpage(this.id, false);
						}
					});
				},{
					names:pnames,
					lefts:[0,178,321]
				});
				obj.fgbts = fgbts;
				continuation(obj.main);
			}, obj, json, dir, imgs);
		}
		else {
			continuation(obj.main);
		}		
	},
	setpage: function(page, immediate, objin, pages, objs) {
		objin.curpageobj.hide(immediate, function() {
			//update the global current page index
			curpages[objin.rootname] = page;
			var obj = objin.curpageobj.getMain();
			if (obj != null && elms.cbox.hasChild(obj)) {
				elms.cbox.removeChild(obj);
			}
			
			var highlightify = function(on, off) {
				off.each(function(el,i) {
					this.fgbts[el].fx.opacity.stop();
					this.fgbts[el].fx.opacity.start(0.01);
				}.bind(this));
				on.each(function(el,i) {
					this.fgbts[el].fx.opacity.stop();
					this.fgbts[el].fx.opacity.start(0.99);
				}.bind(this));
			}.bind(this);
			
			var arr = [];
			for (var x = 0; x < pages.length; ++x) {
				arr.push(x);
			}
			
			for (var x = 0; x < pages.length; ++x) {
				if (page == "Sec" + pages[x]) {
					objin.curpageobj = objs[x];
					var tolight = [arr[x]];
					arr.splice(x,1);
					highlightify(tolight,arr);
				}
			}
			
			doresize(function() {		
			});
			//this can be moved inside the function call
			//	above to delay resize execution. It makes response slower.
			objin.curpageobj.show(false);
			objin.curpage = page;
		}.bind(objin));	
	},
	show: function(immediate, obj) {
		var fn = (immediate) ? "set" : "start";
		for (var x = 0; x < 3; ++x) {
			if (obj.fgbts[x].id == obj.curpage) {
				obj.fgbts[x].fx.opacity[fn](0.99);	
			}
			obj.bgbts[x].fx.opacity[fn](1);
		}
	},
	hide: function(immediate, remover, obj) {
		var fn = (immediate) ? "set" : "start";
		for (var x = 0; x < 3; ++x) {
			obj.fgbts[x].fx.opacity[fn](0.01);
			if (x == 2) {
				obj.bgbts[x].fx.opacity[fn](0.01).chain(remover);
			} else {
				obj.bgbts[x].fx.opacity[fn](0.01);
			}
		}
		obj.curpageobj.hide(immediate, function() {
			elms.cbox.removeChild(this.curpageobj.getMain());
		}.bind(obj));		
	},
	//Pythonesque inheritance
	bindobj: function(obj, dir, names, objs, json, imgs, rootname, startnamedx) {
		obj.getButtons = function(continuation) {
			SecFuncs.getButtons(continuation, this.obj, this.dir, this.names, this.json, this.imgs);
		}.bind({"dir":dir,"names":names,"obj":obj,"json":json,"imgs":imgs});
		obj.setpage = function(page, immediate) {
			SecFuncs.setpage(page, immediate, this.obj, this.names, this.objs);
		}.bind({"names":names,"objs":objs,"obj":obj});
		obj.show = function(immediate) {
			SecFuncs.show(immediate, this.obj);
		}.bind({"obj":obj});
		obj.hide = function(immediate, remover) {
			SecFuncs.hide(immediate, remover, this.obj);
		}.bind({"obj":obj});
		obj.getMaxH = function() {
			return (this.obj.curpageobj == null) ? 0 : this.obj.curpageobj.getMaxH();
		}.bind({"obj":obj});
		obj.getMinH = function() {
			return (this.obj.curpageobj == null) ? 0 : this.obj.curpageobj.getMinH();
		}.bind({"obj":obj});
		obj.layout = function(height,immediate) {
			if (this.obj.curpageobj != null) {
				this.obj.curpageobj.layout(height,immediate);
			}
		}.bind({"obj":obj});
		obj.curpage = "Sec" + names[startnamedx];
		obj.curpageobj = objs[0];
		obj.rootname = rootname;
	}
};

var ObjProjects = {
	main: null,
	index: null,
	categories: {},
	jsondone: function(obj) {
		ObjProjects.index = obj[0];
		//compile categories index.
		//	a tree with leaves containing lists of indices
		//	in the index list
		var crosslink = function(dct,lst,num) {
			if (!dct.keys) {
				dct.keys = [];
			}
			if (dct.keys.indexOf(lst[0]) < 0) {
				dct.keys.push(lst[0]);
			}
			
			if (!dct[lst[0]]) {
				dct[lst[0]] = {};
			}
			if (lst.length == 1) {
				if (dct[lst[0]].indices) {
					dct[lst[0]].indices.push(num);
				} else {
					dct[lst[0]].indices = [num];
				}
			} else {	
				crosslink(dct[lst[0]],lst.slice(1),num);
			}
		};
		for (var x = 0; x < ObjProjects.index.length; ++x) {
			var sec = ObjProjects.index[x][2];
			//find the categories tag
			for (var y = 0; y < sec.length; ++y) {
				if (sec[y][0] == "category") {
					crosslink(ObjProjects.categories,sec[y][1],x);
				}
			}
		}
		
		ObjProjects.cathints = obj[1];
		
		var getsortkey = function(it) {
			var id = ObjProjects.cathints[it];
			if (id) {
				return id[1];
			} else {
				return 10000; //place unindexed things last
			}
		};
		//recursively sort
		var recsort = function(dct) {			
			//make sure this isn't a leaf node
			if (dct.keys) {
				dct.keys.sort(function(a,b) {
					return getsortkey(a) - getsortkey(b);
				});
				for (var x = 0; x < dct.keys.length; ++x) {
					recsort(dct[dct.keys[x]]);
				}
			}
		};
		recsort(ObjProjects.categories);
		
		//ObjProjects.categories is now the tree.		
		//console.log(ObjProjects.categories);
	},
	recurseindices: function(category) {
		var stk = [category];
		var dexes = [];
		
		while (stk.length > 0) {
			var cur = stk.pop();
			if (cur.indices) {
				dexes = dexes.concat(cur.indices);
			}
			if (cur.keys) {
				cur.keys.each(function(el,i) {
					stk.push(cur[el]);
				});
			}
		}
		
		return dexes;
	},
	ObjCategory: {
		cdiv: null,
		plist: null,
		plistelm: null,
		CatBrowser: {
			height: 120,
			width: 450,
			loaded: false,
			container: null,
			innercont: null,
			cols: null,
			lsts: [],
			make: function(parent) {
				this.loaded = true;
				var main = new Element("div").setStyles({
					"height":this.height+"px",
					"width":this.width+"px",
					"overflow-x":"scroll",
					"overflow-y":"hidden",
					"padding-bottom":"15px"
				});
				//BROWSERHACK for Safari 2 - doesn't support overflow-y
				if (window.webkit419) {
					main.setStyles({"overflow":"auto"});
				}
				main.injectInside(parent);
				main.fx = {};
				main.fx.slide = new Fx.Slide(main);
				main.fx.slide.hide();
				this.container = main;
				
				//make the inner container
				var imain = new Element("div").setStyles({
					"height":this.height+"px",
					"width":1000+"px"
				});
				imain.injectInside(main);
				this.innercont = imain;
				
				this.lsts[0] = this.getList([],ObjProjects.categories).injectInside(imain);
				this.bigWidth();
				this.calcWidth();
			},
			//trail is an array, remain is a dict
			getList: function(trail, remain) {
				var lstbox = new Element("div").setStyles({
					"float":"left",
					"display":"block",
					"height":this.height+"px",
					"overflow-x":"hidden",
					"overflow-y":"scroll",
					"padding-right":"15px",
					"white-space":"nowrap"
				});
				//BROWSERHACK for Safari 2 - doesn't support overflow-y
				if (window.webkit419) {
					lstbox.setStyles({"overflow":"auto"});
				}
				var lst = new Element("ul");
				lst.selected = null;
				subels = [];
				remain.keys.each(function(el,i) {
					var subi = this.getItem(trail.concat([el]), remain[el]);
					subi.injectInside(lst);
					subels.push(subi);
				}.bind(this));
				lst.injectInside(lstbox);
				lstbox.subels = subels;
				
				//sub elements to add tooltips to
				var hintify = [];
				subels.each(function(el,i) {
					if (el.getProperty("title") != "") {
						hintify.push(el);
					}
				});
				var tps = new Tips(hintify, {className: "tip"});
				return lstbox;
			},
			bigWidth: function() {
				this.innercont.setStyle("width",2000);	
			},
			calcWidth: function() {
				var tw = 0;
				this.lsts.each(function(el,i) {
					tw += el.getSize().size.x;
				});
				//BROWSERHACK: ie6 makes the value too small.
				//	the multiplier is probably completely bogus.
				tw += this.lsts.length * 10;
				//BROWSERHACK: safari width
				this.container.setStyle("width",
					(this.container.getStyle("width") == "450px") ? "451px" : "450px");
				this.innercont.setStyle("width",tw);				
			},
			getBG: function(over,remain) {
				if (remain.keys) {
					if (over) {
						return "url(img/projects/LstItemOver.gif) no-repeat center right";
					} else {
						return "url(img/projects/LstItem.gif) no-repeat center right";
					}
				} else {
					return "";
				}
			},
			getItem: function(trail, remain) {
				var elm = new Element("li").setStyles({
					"display":"block",
					"margin-left":"-30px",
					"padding-right":"30px",
					"width":(window.ie)?"auto":"100%",
					"background":ObjProjects.ObjCategory.CatBrowser.getBG(false,remain),
					"font-size":"16px"
				});
				var content = trail[trail.length - 1];
				elm.setHTML(content);
				elm.content = content;
				var hint = ObjProjects.cathints[elm.content];
				if (hint) {
					elm.setProperty("title",hint[0]);
				} else {
					elm.setProperty("title","");
				}
				elm.trail = trail;
				elm.remain = remain;

				elm.getList = function() {
					return ObjProjects.ObjCategory.CatBrowser.lsts[this.trail.length-1];
				};
				elm.highlight = function() {
					this.setStyles({
						"background":ObjProjects.ObjCategory.CatBrowser.getBG(true,this.remain),
						"text-decoration":"underline",
						"cursor":"pointer"
					});					
				};
				elm.addEvent("mouseover", function() {
					if (!(this.getList().selected == this)) {
						this.highlight();
					}
				});
				elm.delight = function() {
					this.setStyles({
						"background":ObjProjects.ObjCategory.CatBrowser.getBG(false,this.remain),
						"text-decoration":"none",
						"cursor":"default"
					});					
				};
				elm.addEvent("mouseout", function() {
					if (!(this.getList().selected == this)) {
						this.delight();
					}					
				});
				elm.addEvent("mousedown", function() {
					//hide the starting image
					if (ObjProjects.ObjCategory.firstshow) {
						ObjProjects.ObjCategory.firstshow.effects().start(
							{"opacity":0.0}
						).chain(function() {
							ObjProjects.ObjCategory.firstshow.setStyles({"display":"none"});
							ObjProjects.ObjCategory.firstshow = null;
						});
					}
					var browser = ObjProjects.ObjCategory.CatBrowser;
					var idx = this.trail.length - 1;
					
					if (browser.lsts[idx].selected == elm) {
						//remove the remaining lists
						for (var i = idx + 2; i < browser.lsts.length; ++i) {
							browser.lsts[i].effects({
								onComplete: function() {
									this.browser.innercont.removeChild(this.lst);
									this.browser.calcWidth();
								}.bind({"browser":browser,"lst":browser.lsts[i]})
							}).start({
								"width":0
							});
						}
						
						//deselect the previously selected one
						if (idx + 1 < browser.lsts.length) {
							browser.lsts[idx+1].selected.delight();
						}
					} else {
						//deselect all the others
						for (var i = 0; i < browser.lsts[idx].subels.length; ++i) {
							browser.lsts[idx].subels[i].delight();
						}
						browser.lsts[idx].selected = elm;
						elm.highlight();
						
						//remove the remaining lists
						for (var i = idx + 1; i < browser.lsts.length; ++i) {
							browser.lsts[i].effects({
								onComplete: function() {
									this.browser.innercont.removeChild(this.lst);
									this.browser.calcWidth();
								}.bind({"browser":browser,"lst":browser.lsts[i]})
							}).start({
								"width":0
							});
						}
	
						if (this.remain.keys) {
							browser.lsts.splice(idx+1,browser.lsts.length-(idx+1));
							//place the next list
							browser.bigWidth();
							browser.lsts[idx+1] = browser.getList(this.trail,this.remain)
								.injectInside(browser.innercont);
							browser.calcWidth();
						}
					}
					
					var dexes = ObjProjects.recurseindices(this.remain);
					ObjProjects.ObjCategory.plist.refreshData(ObjProjects.index,dexes);
				});
				return elm;
			},
			show: function(immediate) {
				this.container.fx.slide[(immediate) ? "show" : "slideIn"]();
			},
			hide: function(immediate) {
				this.container.fx.slide[(immediate) ? "hide" : "slideOut"]();
			}
		},//CatBrowser
		loaded: false,
		show: function(immediate) {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"7px",
					"top":"7px"
				});
				this.cdiv.injectInside(elms.cbox);
				this.CatBrowser.make(this.cdiv);
				
				this.plist = new ProjList(450,40,ObjProjects.categories,[]);
				this.plistelm = this.plist.getMain().setStyles({
					"left":"0px",
					"top":(this.CatBrowser.height+SCROLLWIDTH)+"px"
				}).injectInside(this.cdiv);
				this.firstshow = new Element("img").setStyles({
					"position":"absolute",
					"left":"0px","top":"1px",
					"z-index":"100"
				}).setProperty("src","img/projects/startimage.png").injectInside(this.plistelm);
				this.plistelm.fx = {};
				this.plistelm.fx.slide = new Fx.Slide(this.plistelm);
				this.plistelm.fx.slide.hide();
			} else {
				this.cdiv.injectInside(elms.cbox);
			}
			this.CatBrowser.show(immediate);
			this.plistelm.fx.slide[(immediate) ? "show" : "slideIn"]();
		},
		getMain: function() {
			return this.cdiv;	
		},
		hide: function(immediate, remover) {
			if (this.loaded && curpage == "SecProjects") {
				this.CatBrowser.hide(immediate);
				this.plistelm.fx.slide[(immediate) ? "hide" : "slideOut"]().chain(remover);
			} else {
				remover();
			}
		},
		getMinHloc: function() {
			var sh = 0;
			sh += 40+7;
			sh += this.CatBrowser.height;
			sh += SCROLLWIDTH;
			sh += 25; //padding
			return sh;
		},
		getMinH: function() {
			var h = this.getMinHloc();
			h += (ObjProjects.ObjCategory.plist != null &&
				ObjProjects.ObjCategory.plist.currows.length > 0) ? 72 : 0;
			return h;
		},
		getMaxH: function() {
			var th = 0;
			th += (ObjProjects.ObjCategory.plist != null) ? 
					ObjProjects.ObjCategory.plist.currows.length*72 : 0;
			th += this.getMinHloc();
			return th;
		},
		layout: function(height,immediate) {
			if (ObjProjects.ObjCategory.plist != null) {
				ObjProjects.ObjCategory.plist.layout(height-this.getMinHloc()+40,immediate);
			}
		}
	},//ObjCategory
	ObjSearch: {
		cdiv:null,
		plist:null,
		plistelm:null,
		Searcher: {
			height:40,
			width:450,
			charsmin:3,
			loaded:false,
			searchstarted:false,
			searchstack:[],
			sbox:null,
			searchname:true,
			searchcategory:true,
			searchdesc:true,
			make: function(parent) {
				if (!this.loaded) {
					this.loaded = true;
					this.sbox = new Element("input").setStyles({
						"position":"absolute",
						"left":"1px","top":"0px",
						"width":(this.width-12)+"px",
						"height":(this.height-12)+"px",
						"padding":"4px","font-size":"24px",
						"color":"#999999",
						"background":"url(img/projects/searchbg.gif)"
					});
					this.sbox.setProperty("value","Enter "+
						this.charsmin+"+ Characters...");
					this.sbox.injectInside(parent);
					this.sbox.fx = {};
					this.sbox.fx.slide = new Fx.Slide(this.sbox);
					this.sbox.fx.slide.hide();
					
					this.sbox.addEvent("mousedown", function() {
						if (!this.searcher.searchstarted) {
							this.searcher.searchstarted = true;
							this.setStyle("color","black");
							this.setProperty("value","");
							this.focus();
						}
					});
					this.sbox.addEvent("keyup", function() {
						var val = this.getProperty("value").trim();
						if (val.length >= this.searcher.charsmin) {
							this.searcher.searchstack.push(val);
						} else {
							this.searcher.searchstack.push("");
						}
						if (!this.searcher.searching) {
							this.searcher.searching = true;
							this.searcher.sbox.setStyle("background",
								"url(img/projects/searchbganim.gif)");
							setTimeout(this.searcher.dosearch.bind(this.searcher),500);
						}
					});
					this.sbox.searcher = this;
				}
			},
			searching: false,
			dosearch: function() {
				if (this.searchstack.length > 0) {
					var val = this.searchstack.pop();
					this.searchstack = [];
					if (val == "") {
						ObjProjects.ObjSearch.plist.refreshData(ObjProjects.index,[]);
					} else {
						var dexes = this.getIndices(ObjProjects.index,val,100);
						ObjProjects.ObjSearch.plist.refreshData(ObjProjects.index,dexes);
					}
				}
				this.searching = false;
				this.sbox.setStyle("background",
								"url(img/projects/searchbg.gif)");
			},
			getIndices: function(index,sstr,maxres) {
				var dexes = [];
				
				outer:
				for (var i = 0; i < index.length; ++i) {
					var arr = index[i];
					if (dexes.length >= maxres) {
						break;
					}
					if (this.searchname && this.domatch(arr[1],sstr)) {
						dexes.push(i);
						continue outer;
					}
					if (this.searchcategory || this.searchdesc) {
						for (var j = 0; j < arr[2].length; ++j) {
							var subarr = arr[2][j];
							switch (subarr[0]) {
							case "category":
								if (this.searchcategory && 
									this.domatch(subarr[1].join(" "),sstr)) {
									dexes.push(i);
									continue outer;
								} break;
							case "desc":
								if (this.searchdesc && 
									this.domatch(subarr[1],sstr)) {
									dexes.push(i);
									continue outer;
								} break;
							}
						}
					}
				}
				
				return dexes;
			},
			domatch: function(haystack,needle) {
				return haystack.toLowerCase().contains(needle.toLowerCase());	
			},
			getMain: function() {
				return this.sbox;	
			},
			show: function(immediate) {
				this.sbox.fx.slide[(immediate) ? "show" : "slideIn"]();
			},
			hide: function(immediate) {
				this.sbox.fx.slide[(immediate) ? "hide" : "slideOut"]();
			}
		}, //Searcher
		loaded: false,
		show: function(immediate) {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"7px",
					"top":"7px"
				});
				this.cdiv.injectInside(elms.cbox);
				this.Searcher.make(this.cdiv);
				this.plist = new ProjList(450,40,ObjProjects.categories,[]);
				this.plistelm = this.plist.getMain().setStyles({
					"left":"0px",
					"top":(this.Searcher.height)+"px"
				}).injectInside(this.cdiv);
				this.plistelm.fx = {};
				this.plistelm.fx.slide = new Fx.Slide(this.plistelm);
			} else {
				this.cdiv.injectInside(elms.cbox);
			}
			this.plistelm.fx.slide.hide();
			this.Searcher.hide(true);
			
			this.Searcher.show(immediate);
			this.plistelm.fx.slide[(immediate) ? "show" : "slideIn"]();
		},
		getMain: function() {
			return this.cdiv;
		},
		hide: function(immediate,remover) {
			if (this.loaded && curpage == "SecProjects") {
				this.Searcher.hide(immediate);
				this.plistelm.fx.slide[(immediate) ? "hide" : "slideOut"]().chain(remover);
			} else {
				remover();
			}			
		},
		getMinH: function() {
			var sh = 0;
			sh += 40+7;
			sh += this.Searcher.height;
			sh += 25; //padding
			return sh;
		},
		getMaxH: function() {
			var th = 0;
			th += (this.plist != null) ? 
					this.plist.currows.length*72 : 0;
			th += this.getMinH();
			return th;
		},
		layout: function(height,immediate) {
			if (this.plist != null) {
				this.plist.layout(height-this.getMinH()+40,immediate);
			}
		}
	}, //ObjSearch
	ObjSelected: {
		cdiv:null,
		topdiv:null,
		gradtop:null, //title
		catdiv:null, //category
		tldiv:null, //timeline
		tldivdyn:null, //dynamic contents for timeline
		curprojcont:null, //current project container
		curproj:null,
		curprojobj:null,
		curprojdiv:null,
		width:450,
		loaded:false,
		make: function() {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"5px",
					"top":"0px",
					"z-index":"20"
				});
				this.curprojcont = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px","height":"450px",
					"left":"0px","top":"65px",
					"z-index":1
				}).injectInside(this.cdiv);
				this.curprojcont.fx = {};
				this.curprojcont.fx.top = new Fx.Style(this.curprojcont,'top');
				this.curprojcont.fx.top.set(-450);
				this.topdiv = new Element("div").setStyles({
					"position":"absolute",
					"overflow":"visible",
					"width":"450px","height":"55px",
					"left":"0px",
					"top":"0px",
					"background-color":"#CCCCCC"
				}).injectInside(this.cdiv);
				this.gradtop = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px","height":"41px",
					"left":"0px","top":"0px",
					"background":"url(img/projects/largebgover.png)",
					"font-size":"26px","text-align":"center",
					"font-weight":"bold","color":"white"
				}).setHTML("No project selected")
				.injectInside(this.topdiv);
				this.catdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px","height":"20px",
					"left":"0px","top":"30px","text-align":"center",
					"font-weight":"bold"
				}).setHTML("").injectInside(this.topdiv);
				this.tldiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px","height":"1px",
					"left":"0px","top":"48px"
				}).injectInside(this.topdiv);
				//timeline start/end
				new Element("div").setStyles({
					"position":"absolute",
					"bottom":"2px","left":"3px",
					"text-align":"left"
				}).setHTML(this.Dater.getDtStr(this.Dater.begin))
				.injectInside(this.tldiv);
				new Element("div").setStyles({
					"position":"absolute",
					"bottom":"2px","right":"3px",
					"text-align":"right"
				}).setHTML(this.Dater.getDtStr(this.Dater.end))
				.injectInside(this.tldiv);
				this.tldivdyn = new Element("div").setStyles({
					"position":"absolute",
					"overflow":"visible",
					"width":this.Dater.width+"px","height":"1px",
					"left":(450-this.Dater.width)/2+"px",
					"top":"1px"
				}).injectInside(this.tldiv);
				new Element("img").setStyles({
					"position":"absolute","left":"0px","top":"0px",
					"width":"450px","height":"1px"
				}).setProperty("src","img/projects/timeline.gif")
				.injectInside(this.tldiv);
				var concealbot = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px","height":"50px",
					"left":"0px","bottom":"-50px"
				}).injectInside(this.topdiv);
				//BROWSERHACK: ie6 transparency
				new Element("img").setStyles({
					"position":"absolute","left":"0px","top":"0px",
					"width":"450px","height":"50px"
				}).setProperty("src",(window.ie6) ? "img/projects/ie6/topfade.gif" : "img/projects/topfade.png")
				.injectInside(concealbot);
				this.topdiv.setStyle("z-index",20);
				this.tldiv.setStyle("z-index",30);
				this.tldivdyn.setStyle("z-index",30);
				this.topdiv.fx = {};
				this.topdiv.fx.top = new Fx.Style(this.topdiv, 'top');
			}
		},
		//fix for firefox z-index bug. Recursively set the z-index
		setzrec: function(elm,zdex) {
			var stk = [elm];
			
			while (stk.length > 0) {
				var celm = stk.pop();
				if (celm.setStyle) {
					celm.setStyle("z-index",zdex);
				}
				for (var x = 0; x < celm.childNodes.length; ++x) {
					stk.push(celm.childNodes[x]);
				}
			}
		},
		Dater: {
			begin: [0,2004],
			end: [(new Date()).getMonth(), (new Date()).getFullYear()],
			width: 380,
			stamp: function(arr) {
				return arr[1]*12+arr[0];	
			},
			getDt: function(str) {
				var arr = str.split("/");
				var ret = [0,0];
				ret[0] = parseInt(arr[0],10)-1;
				ret[1] = parseInt(arr[1],10);
				ret[1] += (ret[1] > 80) ? 1900 : 2000;
				return ret;
			},
			getDtStr: function(arr) {
				return (arr[0]+1) + "/" + (arr[1] + "").substring(2);
			},
			getArrLoc: function(arr) {
				return (this.stamp(arr) - this.stamp(this.begin)) /
				(this.stamp(this.end) - this.stamp(this.begin)) * this.width;
			},
			getLoc: function(str) {
				return Math.floor(this.getArrLoc(this.getDt(str)));
			}
		},
		//set the project then show
		setprojshow: function(name) {
			this.setproj(name, function() {
				//setpage("SecProjects",true);
				ObjProjects.setpage("SecSelected",false);
			});
		},
		setproj: function(name, continuation) {
			this.make();
			this.projshowing = true;
			this.curproj = name;
			this.currentcontinuation = continuation;
			var projroot = "proj/";
			var req = new Json.Remote(
				projroot + this.curproj + "/content.js", {
				onComplete: function(obj) {
					//load the required
					var reqimgs = [];
					obj.reqimgs.each(function(el,i){
						reqimgs.push(projroot+this.curproj+"/"+el);
					}.bind(this));
					
					var nfo = ProjList.prototype.getInfo(obj.tags);
					this.gradtop.setHTML(obj.title);
					this.catdiv.setHTML(nfo.category.join("&nbsp&gt;&nbsp;"));
					
					//dynamic timeline elements
					while (this.tldivdyn.firstChild) {
						this.tldivdyn.removeChild(this.tldivdyn.firstChild);
					}
					var tlstart = this.Dater.getLoc(nfo.dstart);
					var tlend = this.Dater.getLoc(nfo.dend);
					var tweendiv = new Element("div").setStyles({
						"position":"absolute",
						"width":(tlend-tlstart)+"px",
						"height":"15px",
						"top":"0px","left":tlstart+"px",
						"background-color":"#000000"
					}).injectInside(this.tldivdyn);
					new Element("img").setStyles({
						"position":"absolute",
						"width":"15px","height":"15px",
						"top":"0px","left":"-15px"
					}).setProperty("src","img/projects/timelinel.gif")
					.injectInside(tweendiv);
					new Element("img").setStyles({
						"position":"absolute",
						"width":"15px","height":"15px",
						"top":"0px","right":"-15px"
					}).setProperty("src","img/projects/timeliner.gif")
					.injectInside(tweendiv);
					new Element("div").setStyles({
						"position":"absolute",
						"width":"30px","height":"14px",
						"left":"-42px","top":"1px",
						"text-align":"right"
					}).setHTML(nfo.dstart).injectInside(tweendiv);
					new Element("div").setStyles({
						"position":"absolute",
						"width":"30px","height":"14px",
						"right":"-39px","top":"1px",
						"text-align":"left"
					}).setHTML(nfo.dend).injectInside(tweendiv);
					
					//size and description
					var szwidth = 50;
					var nfoarea = new Element("div").setStyles({
						"position":"absolute","top":"1px"
					});
					var lval = -(450-this.Dater.width)/2+2+"px";
					if (tlstart > 200) {
						nfoarea.setStyles({
							"left":lval,"text-align":"left"
						});
					} else {
						nfoarea.setStyles({
							"right":lval,"text-align":"right"
						});						
					}
					var dsclnk = new Element("a").setHTML("[click for description]").
					setStyles({
						"float":"left"	
					}).addEvent("mouseover", function() {
						if (!this.open) {
							this.setStyle("color","white");
						}
					}).addEvent("mouseout", function() {
							this.setStyle("color","black");
					}).addEvent("mousedown", function() {
						if (this.closing) {
							this.closing = false;
							return;
						}
						if (!this.open) {
							this.open = true;
							if (!this.descbox) {
								this.descbox = new Element("div").setStyles({
									"position":"absolute",
									"left":"0px","top":"0px",
									"width":this.getSize().size.x+"px",
									"background-color":"#CCCCCC",
									"padding":"2px"
								});
								new Element("div").
									setHTML(this.desc).injectInside(this.descbox);
								new Element("div").setStyles({
									"text-align":"right",
									"font-weight":"bold"
								}).setHTML("[close]")
								.addEvent("mouseover", function() {
									this.setStyle("color","white");
								})
								.addEvent("mouseout", function() {
									this.setStyle("color","black");	
								})
								.addEvent("mousedown", function() {
									this.descbox.fx.opacity.start(0.0);
									this.closing = true;
									this.open = false;
								}.bind(this)).injectInside(this.descbox);
								this.descbox.injectInside(this);
								this.descbox.fx = {};
								this.descbox.fx.opacity = 
									new Fx.Style(this.descbox, 'opacity');
							}
							this.descbox.fx.opacity.set(0.0);
							this.descbox.fx.opacity.start(1.0);
						}
					});
					dsclnk.desc = nfo.desc;
					dsclnk.open = false;
					dsclnk.injectInside(nfoarea);
					new Element("span").setHTML("size:").setStyles({
						"float":"left",
						"padding-left":"3px"
					}).injectInside(nfoarea);
					var progbox = new Element("div").setStyles({
						"float":"left",
						"width":szwidth+"px","height":"11px",
						"margin":"1px",
						"border":"1px solid #666666","padding":"1px"
					}).injectInside(nfoarea);
					nfoarea.injectInside(this.tldivdyn);
					new Element("div").setStyles({
						"width":Math.floor(szwidth*nfo.size/5),
						"height":"11px",
						"background-color":"#666666"
					}).injectInside(progbox);
					
					this.curprojobj = obj;
					new Asset.images(reqimgs, {
						onProgress: function(i) {
	
						},
						onComplete: function() {
							//invoke the project creation code
							this.curprojdiv
								= this.curprojobj.make(projroot + this.curproj + "/");
							this.setzrec(this.curprojdiv,2);
							new Element("img").setStyles({
								"position":"absolute",
								"left":"0px","bottom":"0px",
								"width":"50px","height":"50px",
								"z-index":4
							}).setProperty("src","img/projects/hidelcorner.gif")
							.injectInside(this.curprojdiv);
							this.curprojdiv.injectInside(this.curprojcont);
							new Element("img").setStyles({
								"position":"absolute",
								"right":"0px","bottom":"0px",
								"width":"50px","height":"50px",
								"z-index":4
							}).setProperty("src","img/projects/hidercorner.gif")
							.injectInside(this.curprojdiv);
							
							//check the honor code status
							if (this.curprojobj.honorcode) {
								if (ObjPrefs["HonorCode"] != "yes") {
									var hcode = new Element("img").setStyles({
										"position":"absolute",
										"left":"0px","height":"0px",
										"width":"450px","height":"450px",
										"z-index":3
									}).setProperty("src","img/projects/honorcode.png")
									.addEvent("mousedown", function() {
										ObjPrefs["HonorCode"] = "yes";
										this.effects().start({"opacity":0.0}).chain(function() {
											this.pdiv.removeChild(this);
										}.bind(this));
									}).injectInside(this.curprojdiv);
									hcode.pdiv = this.curprojdiv;
								}
							}
							
							while (this.curprojcont.firstChild) {
								this.curprojcont.removeChild(
									this.curprojcont.firstChild
								);
							}
							this.curprojdiv.injectInside(this.curprojcont);
							
							if (this.currentcontinuation) {
								this.currentcontinuation();
								this.currentcontinuation = null;
							}
						}.bind(this)
					});
				}.bind(this)	
			}).send();	
		},
		getMain: function() {
			return this.cdiv;
		},
		show: function(immediate) {
			this.make();
			this.cdiv.injectInside(elms.cbox);
			this.topdiv.fx.top.set(-100);
			this.curprojcont.fx.top.set(-450);
			this.topdiv.fx.top[(immediate) ? "set" : "start"](0);
			this.curprojcont.fx.top[(immediate) ? "set" : "start"](65);
		},
		hide: function(immediate,remover) {
			this.curprojcont.fx.top[(immediate) ? "set" : "start"](-450);
			this.topdiv.fx.top[(immediate) ? "set" : "start"](-100).chain(remover);
		},
		getMinH: function() {
			//100 is good for no project
			return (this.projshowing) ? 515 : 100; 
		},
		getMaxH: function() {
			return (this.projshowing) ? 515 : 100;
		},
		layout: function(height,immediate) {
			
		}
	} //ObjSelected
};
SecFuncs.bindobj(ObjProjects, "projects", 
	["Category","Search","Selected"],
	[ObjProjects.ObjCategory,ObjProjects.ObjSearch,ObjProjects.ObjSelected],
	"proj/index.js",
	["Category","Search","Selected",
	"CategoryOver","SearchOver","SelectedOver",
	"largebg","sizeswish","sizeswishhover","smallbg",
	"largebgover","sizeswishover","smallbgover",
	"rowbg","rowbgo","rowbg2","rowbg2o","startimage","honorcode"],
	"SecProjects",0);

var ObjAbout = {
	jsondone: function(obj) {
		this.ObjPersonal.about = obj.personal;
		this.ObjAcademic.about = obj.academic;
		var secpush = function(container, head, content) {
			new Element("div").setHTML(head)
			.setStyles(Styles.head).injectInside(container);
			content.setStyles(Styles.body).injectInside(container);	
		};
		this.ObjPersonal.secpush = this.ObjAcademic.secpush = secpush;
	},
	ObjPersonal: {
		cacheh: 0,
		show: function(immediate) {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"7px",
					"top":"7px",
					"padding-top":"0px",
					"padding-bottom":"15px"
				});
				this.secpush(this.cdiv, this.about.historyhead,
					new Element("div").setHTML(this.about.history));

				var lst = new Element("ul");
				for (var x = 0; x < this.about.presence.length; ++x) {
					new Element("li").setHTML(this.about.presence[x]).
					setStyles(Styles.li).injectInside(lst);					
				}
				lst.setStyles(Styles.list);
				this.secpush(this.cdiv, this.about.presencehead,lst);

				var nums = [];
				for (var x = 0; x < this.about.interests.length; ++x) {
					nums.push([Math.random(), this.about.interests[x]]);
				}
				nums.sort(function(a,b) {return a[0] - b[0];});
				lst = new Element("ul");
				for (var x = 0; x < nums.length; ++x) {
					new Element("li").setHTML(nums[x][1]).
					setStyles(Styles.li).injectInside(lst);
				}
				lst.setStyles(Styles.list);
				this.secpush(this.cdiv, this.about.interestshead,lst);				

				this.cdiv.fx = {};
				this.cdiv.fx.top = new Fx.Style(this.cdiv,"top");
			}
			this.cdiv.injectInside(elms.cbox);
			this.cdiv.fx.top.set(-this.cacheh);
			this.cdiv.fx.top[(immediate) ? "set" : "start"](0);
			doresize(function() {/*globallayout(false);*/});
		},
		hide: function(immediate, remover) {
			if (this.loaded && curpage == "SecAbout") {
				this.cdiv.fx.top[(immediate) ? "set" : "start"](-this.cacheh).chain(remover);
			} else {
				remover();
			}
		},
		storeh: function() {
			this.cacheh = Math.max(this.cacheh, this.cdiv.getSize().size.y);
			return this.cacheh;
		},
		getMain: function() {
			return this.cdiv;
		},
		getMinH: function() {
			return (this.cdiv == null) ? lastheight : this.storeh();
		},
		getMaxH: function() {
			return (this.cdiv == null) ? lastheight : this.storeh();
		},
		layout: function(height,immediate) {
			
		}
	},
	ObjAcademic: {
		cacheh: 0,
		show: function(immediate) {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"7px",
					"top":"7px",
					"padding-top":"0px",
					"padding-bottom":"15px"
				});
				
				/*
				var lst = new Element("ul").setStyles(Styles.list);
				for (var x = 0; x < this.about.whathire.length; ++x) {
					new Element("li").setHTML(this.about.whathire[x]).
					setStyles(Styles.li).injectInside(lst);
				}
				this.secpush(this.cdiv, this.about.whathirehead, lst);
				*/
				
				this.secpush(this.cdiv, this.about.acadpagehead,
					new Element("div").setHTML(this.about.acadpage));
				
				var otbl = new Element("table");
				var orow = new Element("tr"); orow.injectInside(otbl);
				var curtd = new Element("td"); curtd.injectInside(orow);
				curtd.setStyles({"width":"200px"});
				
				var tbl = new Element("table");
				for (var x = 0; x < this.about.inbrief.length; ++x) {
					var info = this.about.inbrief[x];
					var row = new Element("tr");
					(new Element("td"))
						.setHTML("<img src='img/about/icons/" + info[2] + "' alt=''> &nbsp;" +info[0])
						.setStyles({"font-weight":"bold"}).injectInside(row);
					(new Element("td"))
						.setHTML(info[1])
						.injectInside(row);
					row.injectInside(tbl);
				}
				tbl.injectInside(curtd);
				
				curtd = new Element("td"); curtd.injectInside(orow);
				curtd.setStyles({"vertical-align":"top"});
				curtd.setHTML(this.about.inbriefwords);

				this.secpush(this.cdiv, this.about.inbriefhead, otbl);
				
				this.cdiv.fx = {};
				this.cdiv.fx.top = new Fx.Style(this.cdiv,"top");
			}
			this.cdiv.injectInside(elms.cbox);
			this.cdiv.fx.top.set((this.cacheh == 0) ? -800 : -this.cacheh);
			this.cdiv.fx.top[(immediate) ? "set" : "start"](0);
			doresize(function() {globallayout(false);});			
		},
		hide: function(immediate, remover) {
			this.cdiv.fx.top[(immediate) ? "set" : "start"](-this.cacheh).chain(remover);			
		},
		storeh: function() {
			this.cacheh = Math.max(this.cacheh, this.cdiv.getSize().size.y);
			return this.cacheh;
		},
		getMain: function() {
			return this.cdiv;
		},
		getMinH: function() {
			return (this.cdiv == null) ? lastheight : this.storeh();
		},
		getMaxH: function() {
			return (this.cdiv == null) ? lastheight : this.storeh();
		},
		layout: function(height,immediate) {
			
		}
	},
	ObjContact: {
		cacheh: 0,
		inputh: 35,
		show: function(immediate) {
			if (!this.loaded) {
				this.loaded = true;
				this.cdiv = new Element("div").setStyles({
					"position":"absolute",
					"width":"450px",
					"left":"7px",
					"top":"7px",
					"padding-top":"0px",
					"padding-bottom":"15px"
				});
				
				var reqtext = "<br><small style='color:#FF0000'>(required)</small>";
				var cury = 5;
				var inputh = this.inputh;
				var labelw = 100;
				var inputpad = 7;
				
				var getline = function(text,y) {
					new Element("div").setHTML(text)
					.setStyles({
						"position":"absolute","left":"0px",
						"top":y+"px","height":inputh+"px","width":(labelw)+"px",
						"text-align":"right","font-size":"1.2em"
					}).injectInside(this.cdiv);
					
					return new Element("input").setProperty("type","text")
					.setStyles({
						"position":"absolute","left":(labelw+inputpad)+"px",
						"top":y+"px","width":(450-labelw-inputpad*3)+"px"
					}).injectInside(this.cdiv);
				}.bind(this);
				
				new Element("div").setHTML("To reduce spam, please use this contact form.")
				.setStyles({
					"position":"absolute","left":"0px",
					"top":cury+"px","height":"15px","width":"450px",
					"text-align":"center","font-size":"1.2em"
				}).injectInside(this.cdiv);
				cury += 30;
				
				this.fm = {};
				this.fm.name = getline("Your name:"+reqtext, cury);
				cury += inputh;
				
				this.fm.email = getline("Your email:"+reqtext,cury);
				cury += inputh;
				
				this.fm.website = getline("Your website:",cury);
				cury += inputh;
				
				this.fm.subject = getline("Subject:"+reqtext,cury);
				cury += inputh;
				
				new Element("div").setHTML("Message:")
				.setStyles({
					"position":"absolute","left":"0px",
					"top":cury+"px","height":inputh+"px","width":(labelw)+"px",
					"text-align":"right","font-size":"1.2em"
				}).injectInside(this.cdiv);
				
				this.fm.message = new Element("textarea")
				.setStyles({
					"position":"absolute","left":(labelw+inputpad)+"px",
					"top":cury+"px","width":(450-labelw-inputpad*3)+"px",
					"height":40+"px"
				}).injectInside(this.cdiv);
				this.fm.message.fx = {};
				this.fm.message.fx.height = new Fx.Style(this.fm.message,"height");
				
				this.fm.elms = [this.fm.name, this.fm.email, this.fm.website,
								this.fm.subject, this.fm.message];
				
				cury += 50;
				this.lowerdiv = new Element("div")
				.setStyles({
					"position":"absolute","left":"0px",
					"top":cury+"px","width":(450-inputpad)+"px",
					"text-align":"right"
				});
				this.msg = new Element("span")
				.setHTML("Ready to send?").setStyles({
					"padding-right":"3px",
					"font-size":"1.2em"
				}).injectInside(this.lowerdiv);
				new Element("button").setHTML("Submit").
				addEvent("click", function() {
					var etxt = "";
					//validate form
					do {
						if (this.fm.name.value.length == 0) {
							etxt = "Please enter your name";
							this.fm.name.focus(); break;
						}
						if (this.fm.email.value.length == 0) {
							etxt = "Please enter your email address";
							this.fm.email.focus(); break;
						}
						if (this.fm.subject.value.length == 0) {
							etxt = "Please enter a subject";
							this.fm.subject.focus(); break;
						}
					} while (false);
					
					if (etxt != "") {
						this.msg.setHTML(etxt);
						this.msg.setStyles({
							"color":"#FF0000"
						});
					} else {
						this.fm.elms.each(function(el,i) {
							el.setProperty("disabled","true");
						});
						this.msg.setHTML("Sending...");
						this.msg.setStyles({
							"color":"#000000"
						});
						var xhrsub = new XHR({
							method:"post",
							headers:{'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'},
							onSuccess: function(text) {
								//the return code is the first character
								var code = text.substring(0,1);
								if (code == "0") {
									this.msg.setHTML(text.substring(1));
									this.fm.elms.each(function(el,i) {
										el.value = "";
										el.setHTML("");
									});
								} else if (code == "1") {
									this.msg.setHTML(text.substring(1));
								} else {
									this.msg.setHTML("Unknown error!");
								}
								
								this.fm.elms.each(function(el,i) {
									el.removeProperty("disabled");
								});
							}.bind(this)
						}).send(
							"contactsend.php",
							"name="+encodeURIComponent(this.fm.name.value) + "&" +
							"email="+encodeURIComponent(this.fm.email.value) + "&" +
							"website="+encodeURIComponent(this.fm.website.value) + "&" +
							"subject="+encodeURIComponent(this.fm.subject.value) + "&" +
							"message="+encodeURIComponent(this.fm.message.value)
						);
					}
				}.bind(this))
				.setStyles({"width":"100px"}).injectInside(this.lowerdiv);
				this.lowerdiv.fx = {};
				this.lowerdiv.fx.top = new Fx.Style(this.lowerdiv,"top");
				this.lowerdiv.injectInside(this.cdiv);
				
				this.cdiv.fx = {};
				this.cdiv.fx.top = new Fx.Style(this.cdiv,"top");
			}
			this.cdiv.injectInside(elms.cbox);
			this.cdiv.fx.top.set(-this.cacheh);
			this.cdiv.fx.top[(immediate) ? "set" : "start"](0);
			this.fm.name.focus();
		},
		hide: function(immediate, remover) {
			this.cdiv.fx.top[(immediate) ? "set" : "start"](-this.cacheh).chain(remover);	
		},
		getMain: function() {
			return this.cdiv;
		},
		getMinH: function() {
			return this.inputh*5 + 80;
		},
		getMaxH: function() {
			return 1e6;
		},
		layout: function(height,immediate) {
			this.cacheh = height;
			var messageh = height - this.inputh*5 - 50;
			this.fm.message.fx.height[(immediate) ? "set" : "start"](messageh);
			this.lowerdiv.fx.top[(immediate) ? "set" : "start"](height - 40);
		}		
	}
};
SecFuncs.bindobj(ObjAbout, "about", 
	["Personal","Academic","Contact"],
	[ObjAbout.ObjPersonal,ObjAbout.ObjAcademic,ObjAbout.ObjContact],
	"about.js",
	["Personal","Academic","Contact",
	"PersonalOver","AcademicOver","ContactOver",
	"AcadLink","AcadLinkOver"],
	"SecAbout",1);

var curpageobj = ObjHome;
