// assumes cartesian coordinates start at top left, positive x extending right and positive y extending down, and 0 degrees points straight up

/******************************
 * BTool - Random Library     *
 *                            *
 *                            *
 ******************************/
var BTool = {
	screenWidth: function() {
		if(!window.innerWidth) {
			return document.documentElement.clientWidth != 0 ? document.documentElement.clientWidth : document.body.clientWidth;
		} else {
			return window.innerWidth;
		}
	},
	screenHeight: function() {
		if(!window.innerHeight) {
			return document.documentElement.clientHeight != 0 ? document.documentElement.clientHeight : document.body.clientHeight;
		} else {
			return window.innerHeight;
		}
	}
};

/******************************
 * BMath - Move Library       *
 *                            *
 *                            *
 ******************************/
var BMath = {
	fixAng: function(ang) {
		if(ang>=360) {
			ang-=360;
		} else if(ang<0) {
			ang+=360;
		}
		return ang;
	},
	fixDirs: function(x,y,ang) {
		if(ang<180) {
			x = Math.abs(x);
		} else {
			x = Math.abs(x)*-1;
		}
		if(ang>90 && ang<270) {
			y = Math.abs(x);
		} else {
			y = Math.abs(x)*-1;
		}
		return [x,y];
	},
	toDegrees: function(val) {
		return val * 180 / Math.PI;
	},
	toRadians: function(val) {
		return val * Math.PI / 180;
	},
	getXYOffset: function(dir,dist) {
		var nx = 0;
		var ny = 0;
		var dir2 = this.fixAng(dir);
		//opposite leg uses sine
		//adjacent leg uses cosine
		
		//so we need to assume that if the angle is within certain specs we reverse the lookup
		var rem = dir % 90;
		
		if((dir>=90 && dir<180) || (dir>=270 && dir<360)) {
			ny = this.fixNum(Math.abs(Math.cos(this.toRadians(rem))*dist));   
			nx = this.fixNum(Math.abs(Math.sin(this.toRadians(rem))*dist));
		} else {
			nx = this.fixNum(Math.abs(Math.cos(this.toRadians(rem))*dist));   
			ny = this.fixNum(Math.abs(Math.sin(this.toRadians(rem))*dist));
		}

		if(dir>90 && dir<270) nx*=-1;
		if(dir>180) ny*=-1;

		return [nx,ny];
		
		//if(dir<90) {
		//	ny = Math.abs(this.fixNum(Math.cos(dir))*dist)*-1; // |/
		//	nx = Math.abs(this.fixNum(Math.sin(dir))*dist);   
		//} else if(dir<180) {
		//	nx = Math.abs(this.fixNum(Math.cos(dir-90))*dist); //  \|
		//	ny = Math.abs(this.fixNum(Math.sin(dir-90))*dist);
		//} else if(dir<270) {
		//	ny = Math.abs(this.fixNum(Math.cos(dir-180))*dist);  // /|
		//	nx = Math.abs(this.fixNum(Math.sin(dir-180))*dist)*-1;
		//} else {
		//	nx = Math.abs(this.fixNum(Math.cos(dir-270))*dist)*-1;  // |\
		//	ny = Math.abs(this.fixNum(Math.sin(dir-270))*dist)*-1;
		//}
		//BOARD.panel.innerHTML = '<b>nx:</b> '+nx+'&nbsp;&nbsp;<b>ny:</b> '+ny+'&nbsp;&nbsp;<b>calc:</b> '+dir+'/'+dist+'<br/>'+BOARD.panel.innerHTML;
		//return [nx,ny];
	},
	fixNum: function(val) {
		return Math.round((val)*10000)/10000; //  val.toFixed(3); //
	},
	getNewDir: function(cx,cy,dx,dy) {
		var xdist = dx-this.fixNum(cx);
		var ydist = this.fixNum(cy)-dy;
		var dist = Math.sqrt(this.fixNum(xdist*xdist)+this.fixNum(ydist*ydist));
		var dir = 0;
		var idir = 360-this.fixAng(this.toDegrees(Math.atan2(ydist,xdist)));
		var tdir = idir;
		if(xdist>=0) {
			if(ydist>=0) {
				dir = 90+this.toDegrees(Math.atan(this.fixNum(Math.abs(ydist)/Math.abs(xdist))));
			} else {
				dir = this.toDegrees(Math.atan(this.fixNum(Math.abs(xdist)/Math.abs(ydist))));
			}
		} else {
			if(ydist>=0) {
				dir = 180+this.toDegrees(Math.atan(this.fixNum(Math.abs(xdist)/Math.abs(ydist))));
			} else {
				dir = 270+this.toDegrees(Math.atan(this.fixNum(Math.abs(ydist)/Math.abs(xdist))));
			}
		}
		
		return [tdir,dist]; //[this.fixAng(dir),dist];
	}
};

/******************************
 *                            *
 * Globals & Structs          *
 ******************************/

var FS = 60;
var INTERVAL = 1000/FS;

var SPECIES = {
	human: {
		feet:[
			{name:'brown_yellow/human_barefoot/right',type:'img',className:'rfoot',dim:10},
			{name:'brown_yellow/human_barefoot/left',type:'img',className:'lfoot',dim:10}
		],
		dmode: 'walk',
		amodes: [
			'walk',
			'run',
			'skip',
			'dance'
		],
		basespd: 20,
		basetime: 200,
		baseturn: 15,
		xscale:.7,
		yscale:1,
		acc: 1.2,
		dcc: .7
	},
	trex: {
		feet:[
			{name:'brown_yellow/dinosaur/right',type:'img',className:'rfoot',dim:50},
			{name:'brown_yellow/dinosaur/left',type:'img',className:'lfoot',dim:50}
		],
		dmode: 'walk',
		amodes: [
			'walk',
			'run'
		],
		basespd: 220,
		basetime: 1200,
		baseturn: 20,
		xscale:.7,
		yscale:1,
		acc: 1.2,
		dcc: .8
	},
	crow: {
		feet:[
			{name:'brown_yellow/bird/right',type:'img',className:'rfoot',dim:5},
			{name:'brown_yellow/bird/left',type:'img',className:'lfoot',dim:5}
		],
		dmode: 'walk',
		amodes: [
			'walk',
			'run'
		],
		basespd: 10,
		basetime: 150,
		baseturn: 25,
		xscale:.7,
		yscale:1,
		acc: 1.2,
		dcc: .6
	}
};

var MODES = {
	walk: {
		steps:[
			[1,-1.2,0,0],
			[0,1.2,0,0]
		],
		spdmod:1,
		timemod:1,
		turnmod:1
	},
	run: {
		steps:[
			[1,-.8,0,0],
			[0,.8,0,0]
		],
		spdmod:1.75,
		timemod:.7,
		turnmod:.8
	},
	wait: {
	},
	dance: {
		steps:[
			[1,-1.6,.4,-15],
			[1,-2,.6,15],
			[0,.4,-.2,-30],
			[1,-2.4,.6,-15],
			[0,1.2,-.4,35],
			[0,2,.2,40]
		],
		spdmod:.75,
		timemod:1.5,
		turnmod:.4
	},
	skip: {
		steps:[
			[1,-1.2,0,0],
			[1,-1.2,0,-15],
			[0,1.2,0,0],
			[0,1.2,0,15]
		],
		spdmod:1.5,
		timemod:.8,
		turnmod:.8
	}
};

var tm = new Date();

var BOARD = {
	walkers: [],
	numwalkers: 0,
	wcount: 0,
	numsteps: 0,
	imgCache:[],
	frames:0,
	ftimes: [],
	fdur: [],
	ftimetot: 0,
	hundredframes: 0,
	lastframe: tm.getTime(),
	addWalker: function() {
		this.wcount++;
		BOARD.walkers.push(new Walker());
	},
	remWalker: function() {
		//var w = BOARD.walkers.shift();
		BOARD.walkers[0].die();
	},
	takesteps: function() {
		BOARD.frames++;
		var tm = new Date();
		var mtime = tm.getTime();
		var etime = mtime-BOARD.lastframe;
		BOARD.ftimes.push(etime);
		BOARD.ftimetot += etime;
		BOARD.hundredframes += etime;
		if(BOARD.ftimes.length > 100) {
			var rtime = BOARD.ftimes.shift();
			BOARD.hundredframes-=rtime;		
		}
		document.getElementById('f_last').innerHTML = Math.round(1000/etime,2)+'|';
		document.getElementById('f_100').innerHTML = Math.round(1000/(BOARD.hundredframes/100),2)+'|';
		document.getElementById('f_all').innerHTML = Math.round(1000/(BOARD.ftimetot/BOARD.frames),2);
		BOARD.lastframe =mtime;
		
		//BOARD.lastframe = mtime;
		for(var i=0;i<BOARD.walkers.length;i++) {
			var alive = BOARD.walkers[i].step(tm);
			if(!alive) {
				//BOARD.cPrint('walker dead! '+i);
				BOARD.walkers.splice(i,1);
				i--;
			}
		}
		if(BOARD.running) {
			BOARD.interval = setTimeout(BOARD.takesteps,INTERVAL);
		}
	},
	cProcess: function(code) {
		BOARD.cPrint('no console entry support yet!');
	},
	cPrint: function(msg) {
		var sw = BOARD.consoleScreen;
		sw.appendChild(makeEle('div',{
			className:'note',
			html:msg
		}));
		if(sw.childNodes.length>10) {
			sw.removeChild(sw.childNodes[0]);
		}
		sw.scrollTop = parseInt(sw.scrollHeight,10);
	},
	toggleConsole: function() {
		var console = document.getElementById('console');
		if(console.style.display == 'none') {
			console.style.display = 'block';
			document.getElementById('consoleMarker').style.display = 'none';
		} else {
			console.style.display = 'none';
			document.getElementById('consoleMarker').style.display = 'block';
		}
	},
	init: function() {
		// remove all board content
		//while(document.body.childNodes.length) {
		//	document.body.removeChild(document.body.childNodes[0]);
		//}
		// create panel
		BOARD.consoleScreen = makeEle('div',{className:'cscreen'});
		BOARD.consoleInput = makeEle('div',{
			className:'cinput',
			dom:[
				makeEle('input',{
					name:'centry',
					id:'centry',
					type:'text',
					width:'392px'
				}),
				makeEle('input',{
					name:'csubmit',
					id:'csubmit',
					type:'submit',
					width:'50px',
					value:'Enter'
				})
			]
		});
		BOARD.consoleControls = makeEle('div',{
			className:'ccontrol',
			dom:[
				makeEle('div',{
					style:'float:right;padding:5px;', 
					dom:[
						makeEle('span',{html:'fps: '}),
						makeEle('span',{id:'f_last'}),
						makeEle('span',{id:'f_100'}),
						makeEle('span',{id:'f_all'})
					]
				}),
				makeEle('input',{
					name:'cstop',
					id:'cstop',
					type:'button',
					value:'Stop',
					onclick:function() {
						BOARD.cPrint('Stopping board activity...');
						BOARD.running=0;
						clearInterval(BOARD.interval);
					}
				}),
				makeEle('input',{
					name:'cstart',
					id:'cstart',
					type:'button',
					value:'Start',
					onclick:function() {
						BOARD.cPrint('Starting board activity...');
						BOARD.running=1;
						BOARD.takesteps();
					}
				}),
				makeEle('input',{
					name:'cstep',
					id:'cstep',
					type:'button',
					value:'Step',
					onclick:function() {
						BOARD.cPrint('Step!');
						BOARD.takesteps();
					}
				}),
				makeEle('input',{
					name:'cadd',
					id:'cadd',
					type:'button',
					value:'Add',
					onclick:function() {
						BOARD.cPrint('Added Walker...');
						BOARD.addWalker();
					}
				}),
				makeEle('input',{
					name:'crem',
					id:'crem',
					type:'button',
					value:'Remove',
					onclick:function() {
						BOARD.cPrint('Killed Walker!');
						BOARD.remWalker();
					}
				})
			]
		});
		document.body.appendChild(
			makeEle('div',{
				className:'console',
				id:'console',
				style:'display:none;',
				dom:[
					BOARD.consoleScreen,
					makeEle('form',{
						name:'consoleForm',
						id:'consoleForm',
						method:'GET',
						action:'#',
						onsubmit:function() {
							BOARD.cProcess(this.centry.value);
							this.centry.value='';
							return false;
						},
						dom: [
							BOARD.consoleInput,
							BOARD.consoleControls
						]
					})
				]

			})
		);
		document.body.appendChild(
			makeEle('div',{
				className:'consoleMarker',
				id:'consoleMarker',
				html:'press <b>~</b> for console',
				style:'position:absolute;right:2px;bottom:2px;font-size:75%;'
			})
		);
		document.onkeyup = function(e) {
			e = e||window.event;
			var keyid = e.keyCode;
			switch(keyid) {
				case 192:
					BOARD.toggleConsole();
					break;
			}
		}
		BOARD.addWalker();
		BOARD.running = 1;
		BOARD.takesteps();
	},
	running:0
};

/******************************
 * Walker                     *
 *                            *
 *                            *
 ******************************/

function Walker() {
	this.speciesname = 'human';
	var nw = BOARD.wcount;
	if(nw && nw % 3 == 0) {
		this.speciesname = 'trex';
	}
	if(nw && nw % 4 == 0) {
		this.speciesname = 'crow';
	}
	this.species = SPECIES[this.speciesname];
	if(arguments[0]) {
		this.mode = MODES[arguments[0]];
	} else {
		this.mode = MODES[this.species.dmode];
	}
	var tm = new Date();
	this.laststep = tm.getTime();
	this.lastfade = tm.getTime();
	this.steps = [];
	this.ai = new AI(this);
	this.cdir = 0;
	this.ddir = this.cdir;
	this.cspd = 0;
	this.cx = Math.round(Math.random()*BTool.screenWidth());
	this.cy = Math.round(Math.random()*BTool.screenHeight());
	this.dx = this.cx;
	this.dy = this.cy;
	this.cstep = -1;
	this.scount = 0;
	this.alive = 1;
	this.fadetime = 200;
}
Walker.prototype.addAction = function(atype,aref) {
	if(!arguments[1] || arguments[1] == '0') {
		this.ai.actions.unshift([atype,aref]);
	} else if(arguments[1] < this.ai.actions.length()) {
		this.ai.actions.splice(arguments[1],0,[atype,aref]);
	} else {
		this.ai.actions.push([atype,aref]);
	}
}
Walker.prototype.die = function() {
	for(var i=0;i<20;i++) {
		this.steps.push(new Step(this.cx+(Math.random()*40)-20,this.cy+(Math.random()*40)-20,0,{className:'hittarget'}));
		this.alive=0;
	}
}
Walker.prototype.ageSteps = function(num) {
	for(var i=0;i<this.steps.length;i++) {
		var salive = this.steps[i].degrade(num);
		if(!salive) {
			this.steps.splice(i,1);
			i--;
		}
	}
}
Walker.prototype.step = function(tm) {
	this.scount++;
	
	var tm = new Date();
	
	var numsfade = Math.round(((tm.getTime()-this.lastfade)/this.fadetime)-.5);
	if(numsfade) this.ageSteps(numsfade);
	this.lastfade = this.lastfade+(numsfade*this.fadetime);
	
	var stime = this.species.basetime*this.mode.timemod;
	var numsteps = Math.round(((tm.getTime()-this.laststep)/stime)-.5);
	//BOARD.cPrint('numsteps: '+numsteps);
	this.laststep = this.laststep+(numsteps*stime);
	
	if(numsteps>0) {
		if(!this.alive) {
			return this.steps.length;
		} else {
			for(var i=0;i<numsteps;i++) {
				this.cstep++;
				var step = this.cspd;
				if(this.cstep >= this.mode.steps.length) {
					this.cstep = 0;
					this.ai.upkeep();
				}

				var rarr = BMath.getNewDir(this.cx,this.cy,this.ai.dx,this.ai.dy);
				var ddir = rarr[0];
				var rdist = rarr[1];

				var tdist = Math.abs(ddir-this.cdir);
				var cdspd = this.species.basespd*this.mode.spdmod;
				var spdratio = cdspd/(this.cspd>0?this.cspd:cdspd/5);
				var turnratio = this.species.baseturn * spdratio;
				turnratio = this.species.baseturn + ((turnratio-this.species.baseturn)/3);
				var noacc = 0;
				//BOARD.cPrint(turnratio);
				if(tdist < turnratio || tdist > 360-turnratio) {
					this.cdir = ddir;
				} else {
					var tdir = BMath.fixAng(ddir-this.cdir);
					if(tdist<180) {
						this.cdir = BMath.fixAng(this.cdir+(turnratio*(ddir>this.cdir?1:-1)));
						this.cspd-=(this.cspd/10);
						noacc=1;
					} else {
						this.cdir = BMath.fixAng(this.cdir+(turnratio*(ddir>this.cdir?-1:1)));
						this.cspd-=(this.cspd/10);
						noacc=1;
					}
				}


				//freaky... not sure how else to do this...
				if(this.cspd==0 && cdspd>0) {
					this.cspd=cdspd/5;
				}
				var ac = '';
				if(this.cspd*7>rdist) {
					this.cspd-=(this.cspd/8);
					if(this.cspd<cdspd/5) this.cspd = cdspd/5;
					step = this.cspd;
					if(this.cspd>rdist) {
						step = rdist;
						this.ai.gotTarget();
						ac = 'hittarget';
					}
				} else {
					if(this.cspd<cdspd && !noacc) {
						this.cspd*=this.species.acc;
						if(this.cspd>cdspd) this.cspd = cdspd;
						step = this.cspd;
					}
				}

				var tarr = BMath.getXYOffset(this.cdir,step);
				var tx = BMath.fixNum(tarr[0]);
				var ty = BMath.fixNum(tarr[1]);

				// if the step's okay...
				this.cx += tx;
				this.cy += ty;

				var sinfo = this.mode.steps[this.cstep];
				var finfo = this.species.feet[sinfo[0]];

				ac += ' '+finfo.className;

				// now calc step actual offset...
				var xsd = finfo.dim*this.species.xscale;
				var ysd = finfo.dim*this.species.yscale;
				var sarr = BMath.getNewDir(0,0,sinfo[2]*ysd,sinfo[1]*xsd); // reverse x/y for correct angle
				var sdir = BMath.fixNum(sarr[0]);
				var sdist = BMath.fixNum(sarr[1]);
				//BOARD.cPrint('dir: '+sdir+' / dist: '+sdist+' | from: '+sinfo[1]+'/'+sinfo[2]);
				var sarr2 = BMath.getXYOffset(BMath.fixAng(this.cdir+sdir),sdist);
				var sx = BMath.fixNum(sarr2[0]);
				var sy = BMath.fixNum(sarr2[1]);
				//BOARD.cPrint('step offset: '+sx+'/'+sy+' | sdist: '+sdist);


				// try tracing the line...
				//var fdist = rdist/5;
				//for(var i=0;i<6;i++) {
				//	var ttarr = BMath.getXYOffset(this.cdir,fdist*i);
				//	var ttx = ttarr[0];
				//	var tty = ttarr[1];
				//	var pt = document.getElementById('point'+i);
				//	if(!pt) {
				//		pt = document.createElement('div');
				//		pt.id = 'point'+i;
				//		document.body.appendChild(pt);
				//	}
				//	pt.style.top = (this.cy+tty)+'px';
				//	pt.style.left = (this.cx+ttx)+'px';
				//}

				finfo.numsteps = this.species.savesteps;
				var nstep = new Step((this.cx+sx)-finfo.dim,(this.cy+sy)-finfo.dim,this.cdir+sinfo[3],finfo);
				nstep.degrade(numsteps-(i+1));
				this.steps.push(nstep);
			} // foreach step
		} // alive?
	} // numsteps>0
	return this.alive?1:this.steps.length;
}

/******************************
 * AI                         *
 *                            *
 *                            *
 ******************************/

function AI() {
	this.walker = arguments[0];
	this.targets = [];
	this.feelings = {
		boredom: 0,
		curiosity: 0,
		stamina: 100
	};
	this.actions = [];
	this.dx = 0;
	this.dy = 0;
}
AI.prototype.addTarget = function(target) {
	if(!arguments[1] || arguments[1] == '0') {
		this.targets.unshift(target);
	} else if(arguments[1] < this.targets.length) {
		this.targets.splice(arguments[1],1,target);
	} else {
		this.targets.push(target);
	}
	//document.body.appendChild(makeEle('div',{className:'target',top:target.loc.y+'px',left:target.loc.x+'px'}));
}
AI.prototype.gotTarget = function() {
	this.targets.shift();
}
AI.prototype.upkeep = function() {
	this.feelings.boredom++;
	if(this.feelings.boredom>40+(Math.random()*40)) {
		if(Math.random()>.9) {
			this.walker.die();
			BOARD.addWalker();
		} else {
			var nmode = this.walker.species.amodes[Math.round((Math.random()*(this.walker.species.amodes.length))-.5)];
			this.walker.mode = MODES[nmode];
			this.feelings.boredom=0;
			BOARD.cPrint('Walker is now in mode: '+nmode+'!');
		}
	}
	if(!this.targets.length) {
		// pick a new target!!
		var smod = this.walker.species.basespd*2;
		var newx = Math.round((Math.random()*(BTool.screenWidth()+(smod*2)))-smod);
		var newy = Math.round((Math.random()*(BTool.screenHeight()+(smod*2)))-smod);
		this.addTarget({type:'point',loc:{x:newx,y:newy}});
	}
	ttarg = this.nextTarget();
	if(ttarg.type == 'point') {
		this.dx = ttarg.loc.x;
		this.dy = ttarg.loc.y;
	}
}
AI.prototype.nextTarget = function() {
	return this.targets[0];
}

/******************************
 * Step                       *
 *                            *
 *                            *
 ******************************/

function Step(x,y,dir,finfo) {
	this.finfo = finfo;
	this.x = x;
	this.y = y;
	this.dir = dir;
	this.draw();
	this.age = 0;
}
Step.prototype.draw = function() {
	this.html = document.createElement('div');
	this.html.className = 'foot '+this.finfo.className;
	this.html.style.width = this.finfo.dim*2;
	this.html.style.height = this.finfo.dim*2;
	if(this.finfo.type == 'img') {
		var inc = Math.round(this.dir/15)*15;
		if(inc >= 360) inc -= 360;
		if(inc < 0) inc += 360;
		var imgurl = ('/images/feet/'+this.finfo.name)+(inc+'.gif');
		//BOARD.cPrint(imgurl);
		//if(!BOARD.imgCache[imgurl]) {
		//	BOARD.imgCache[imgurl] = new Image();
		//	BOARD.imgCache[imgurl].src = imgurl;
		//}
		//this.html.appendChild(makeEle('img',{src:imgurl}));
		this.html.style.background='url('+imgurl+') no-repeat';
	}
	this.html.style.left = Math.round(this.x)+'px';
	this.html.style.top = Math.round(this.y)+'px';
	document.body.appendChild(this.html);
}
Step.prototype.degrade = function(num) {
	this.age+=num;
	this.html.style.filter = 'alpha(opacity='+(100-(this.age*4))+')';
	this.html.style.opacity = ((100-(this.age*4))/100);
	if(this.age >= 25) {
		this.destroy();
		return 0;
	}
	return 1;
}
Step.prototype.destroy = function() {
	this.html.parentNode.removeChild(this.html);
}


/******************************
 * Sugar Functions            *
 *                            *
 *                            *
 ******************************/

function makeEle(kind,opts) {
	var ele = document.createElement(kind);
	for(k in opts) {
	  switch(k) {
	    // html / css
	    case 'id': ele.id = opts['id']; break;
	    case 'className': ele.className = opts['className']; break;
	    case 'style': ele.setAttribute('style',opts['style']); break;
	    case 'attr': {
	    	for(var att in opts['attr']) {
	    		ele.setAttribute(att,opts['attr'][att]);
	    	}
	    }; break;
	    case 'height': ele.style.height = opts['height']; break;
	    case 'width': ele.style.width = opts['width']; break;
	    case 'top': ele.style.top = opts['top']; break;
	    case 'left': ele.style.left = opts['left']; break;
	    case 'textAlign': ele.style.textAlign = opts['textAlign']; break;
	    case 'fontSize': ele.style.fontSize = opts['fontSize']; break;
	    // content
	    case 'dom': {
	    	if(opts['dom']) {
			if(opts['dom'][1]) {
				for(var q=0;q<opts['dom'].length;q++) {
					ele.appendChild(opts['dom'][q]);
				}
			} else {
				ele.appendChild(opts['dom']);
			}
	    	}
	    }; break;
	    case 'text': ele.appendChild(document.createTextNode(opts['text'])); break;
	    case 'html': ele.innerHTML += opts['html']; break;
	    // links
	    case 'href': ele.href = opts['href']; break;
	    // forms / inputs
	    case 'type': ele.setAttribute('type',opts['type']); break;
	    case 'name': ele.setAttribute('name',opts['name']); break;
	    case 'value': ele.setAttribute('value',opts['value']); break;
	    case 'opts': {
	    	for(var i=0;i<opts['opts'].length;i++) {
	    		ele.options.add(new Option(opts['opts'][i].text,opts['opts'][i].value));
	    	}
	    }; break;
	    case 'method': ele.setAttribute('method',opts['method']); break;
	    case 'action': ele.setAttribute('action',opts['action']); break;
	    case 'onsubmit': ele.onsubmit = opts['onsubmit']; break;
	    // img / script
	    case 'src': ele.setAttribute('src',opts['src']); break;
	    // label
	    case 'labelfor': ele.setAttribute('for',opts['labelfor']); break;
	    // events
	    case 'onclick': ele.onclick = opts['onclick']; break;
	    case 'onmouseover': ele.onmouseover = opts['onmouseover']; break;
	    case 'onmouseout': ele.onmouseout = opts['onmouseout']; break;
	    case 'onkeydown': ele.onkeydown = opts['onkeydown']; break;
	    case 'onkeyup': ele.onkeyup = opts['onkeyup']; break;
	    case 'onfocus': ele.onfocus = opts['onfocus']; break;
	    case 'onunfocus': ele.onunfocus = opts['onunfocus']; break;
	    case 'onsubmit': ele.onsubmit = opts['onsubmit']; break;
	  }
	}
	return ele;
}


/******************************
 * Page Load                  *
 *                            *
 ******************************/

// haha start er up
onload = BOARD.init;
