﻿ColinBell = {};

ColinBell.commons = {
	supports : function(prop){
		var div = document.createElement('div');
		var vendors = ["Khtml","Ms","O","Moz","Webkit"];
		if(prop in div.style) return true;
		
		//try lowercase begginging for ie
		var prop2 = prop.charAt(0).toLowerCase() + prop.slice(1);
		if(prop2 in div.style) return true;
		
		//try upper begginging 
		var prop3 = prop.charAt(0).toUpperCase() + prop.slice(1);
		if(prop3 in div.style) return true;
		
		for(var i = 0; i < vendors.length ; i++){
			if(vendors[i] + prop in div.style){return true;}
			if(vendors[i] + prop2 in div.style){return true;}
			if(vendors[i] + prop3 in div.style){return true;}
		}
		return false
	},
	track: function(category, action) {
		try{
			var pageTracker = _gat._getTracker(ColinBell.commons.UA);
			pageTracker._trackEvent(category, action);
		} catch(err) {}
	},
	window : function(){
		var myWidth = 0, myHeight = 0;
		if( typeof( window.innerWidth ) == 'number' ) {
			//Non-IE
			myWidth = window.innerWidth;
			myHeight = window.innerHeight;
		}
		else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			myWidth = document.documentElement.clientWidth;
			myHeight = document.documentElement.clientHeight;
		}
		else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			//IE 4 compatible
			myWidth = document.body.clientWidth;
			myHeight = document.body.clientHeight;
		}
		return({"width":myWidth, "height" : myHeight});
	},
	deactivateMask: function(){
		Event.stopObserving(window, 'resize', this.bfx);
		if(this.mask){
			this.mask.parentNode.removeChild(this.mask);
		}
		this.mask = null;
		
		document.body.style.overflow = "scroll";
	},
	activateMask : function(){
		this.deactivateMask(); // just in case exists
		
		document.body.style.overflow = "hidden";
		
		this.mask = document.createElement('div');
		this.mask.id = "searchmask";
		this.mask.style.height = "100%";
		this.mask.style.width = "100%";
		this.mask.style.top = 0;
		if(window.scrollY){
			this.mask.style.top = window.scrollY;
		}
		else if(document.documentElement.scrollTop){
			this.mask.style.top = document.documentElement.scrollTop;
		}
		this.mask.style.position = "absolute";
		this.mask.style.zIndex = 1100;
		this.mask.style.backgroundColor = "#000000";
		this.mask.style.opacity = (60 / 100);
		this.mask.style.MozOpacity = (60 / 100);
		this.mask.style.KhtmlOpacity = (60 / 100); 
		this.mask.style.filter = "alpha(opacity="+ 60 +")";
		if(document.body.childNodes.length > 0){
			document.body.insertBefore(this.mask, document.body.childNodes[0]);
		}
		else{
			document.body.appendChild(this.mask);
		}
		
		this.bfx = this.resetMask.bindAsEventListener(this);
		
		Event.observe(window, 'resize', this.bfx);
		
	},
	resetMask : function(){
		if(this.mask){
			//this.mask.style.height = document.viewport.getHeight() + "px";
			
			if(window.scrollY){
				this.mask.style.height = document.viewport.getHeight() + window.scrollY +"px";
			}
			else if(document.documentElement.scrollTop){
				this.mask.style.height = document.viewport.getHeight() + document.documentElement.scrollTop +"px";
			}
			else{
				this.mask.style.height = document.viewport.getHeight() + "px";
			}
		}
	}
}

ColinBell.CookieManager = Class.create({
	initialize : function(options) {
		this.setOptions(options);
	},
	setOptions: function(options){
		this.options = {}
		Object.extend(this.options, options || {});
	},
	setCookie : function(c_name,value,exdays){
		var exdate=new Date();
		exdate.setDate(exdate.getDate() + exdays);
		var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString());
		document.cookie=c_name + "=" + c_value;
	},
	getCookie : function(c_name){
		var i,x,y,ARRcookies=document.cookie.split(";");
		for (i=0;i<ARRcookies.length;i++){
			x=ARRcookies[i].substr(0,ARRcookies[i].indexOf("="));
			y=ARRcookies[i].substr(ARRcookies[i].indexOf("=")+1);
			x=x.replace(/^\s+|\s+$/g,"");
			if (x==c_name){
				return unescape(y);
		    }
		}
	}
});

ColinBell.InformationGrabber = Class.create({
	formItems: [],
	initialize : function(options) {
		this.setOptions(options);
	},
	setOptions: function(options){
		this.options = {}
		Object.extend(this.options, options || {});
	},
	createField : function(form, name, type, text, optional, validation){
		var div = document.createElement("div");
		div.className = "formel";
		form.appendChild(div);
		
		var label = document.createElement("label");
		label.setAttribute("for", name);
		label.innerHTML = text + ":" + (optional ? "" : "&nbsp;<span class=\"nag\">*</span>");
		div.appendChild(label);
		
		var field;
		if(type == "textarea"){
			field = document.createElement("textarea");
			field.setAttribute("type", type);
			field.setAttribute("name", name);
			div.appendChild(field);
		}
		else{
			field = document.createElement("input");
			if(!optional){
				field.onblur = this.checkFieldText.bindAsEventListener(this, validation);
				field.onkeyup = this.checkFieldText.bindAsEventListener(this, validation);
			}
			field.setAttribute("type", type);
			field.setAttribute("name", name);
			div.appendChild(field);
		}
		
		this.formItems[this.formItems.length] = {"text" : text, "item" : field, "optional" : optional, "validation" : validation}
		return field;
	},
	formIsInvalid : function(){
		var formValid = true;
		for(var i = 0; i < this.formItems.length ; i++){
			if(!this.formItems[i].optional){
				formValid = this.validateFieldItem(this.formItems[i].item, this.formItems[i].validation);
			}
		}
		return formValid;
	},
	validateFieldItem : function(target, validation){
		var invalid = false;
		if(target.value.length <= 2){invalid = true;}
		else{invalid = false}
		
		if(invalid){
			target.oldClassName = target.className;
			target.className = "invalid";
		}
		else{
			target.className = "";
		}
		
		return invalid;
	},
	checkFieldText : function(e, validation){
		var target;
		if (!e) var e = window.event;
		if (e.target) target = e.target;
		else if (e.srcElement) target = e.srcElement;
		this.validateFieldItem(target, validation);
	},
	show : function(){
		this.form = document.createElement("form");
		
		var legend = document.createElement("legend");
		this.form.appendChild(legend);
		
		this.personname = this.createField(legend, "name", "text", "Name", false, "text");
		this.company = this.createField(legend, "company", "text", "Company", false, "text");
		
		var obj = this;
		var dialog = new ColinBell.MessageWindow({
			"title" : "Please personalise your visit by providing some details",
			"content" : this.form ,
			"allowClose" : false,
			"buttonsWidth" : 100
		});
		
		dialog.setButtons([{
			text : "Continue",
			onmouseup : function(){
				if(!obj.formIsInvalid()){
					ColinBell.ContactName = obj.personname.value;
					ColinBell.Company = obj.company.value;
					
					var cm = new ColinBell.CookieManager({});
					cm.setCookie("cbell.info.name", ColinBell.ContactName, 365);
					cm.setCookie("cbell.info.company", ColinBell.Company, 365);
					dialog.remove();
					
					ColinBellsPortfolio = new ColinBell.Portfolio({
						allowGraphicSelect : ColinBellsPortfolioCanDisplayGraphics,
						graphical : ColinBellsPortfolioCanDisplayGraphics
					});

					ColinBell.commons.track("portfolio", "/new_visitor?name=" + ColinBell.ContactName + "&company=" + ColinBell.Company);
				}
			}
		}]);
		
		dialog.show();
	}
});

ColinBell.LightBox = Class.create({
	initialize : function(options) {
		this.setOptions(options);
	},
	
	setOptions: function(options){
		this.options = {
			media: {},
			width: 200,
			height: 200,
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	positionWindow : function(){
		var winTop = ((ColinBell.commons.window().height / 2) - (this.lightBoxWin.offsetHeight /2));
		if(window.scrollY){
			winTop = winTop + window.scrollY;
		}
		else if(document.documentElement.scrollTop){
			winTop = winTop + document.documentElement.scrollTop;
		}
		if(winTop < 5){
			winTop = 10;
		}
		
		this.lightBoxWin.style.top = winTop + "px";
		this.lightBoxWin.style.left = ((ColinBell.commons.window().width / 2) - (this.lightBoxWin.offsetWidth /2)) + "px";
		
		
		
		this.positionLoading();
		
		ColinBell.commons.resetMask();
	},
	
	positionNavigation : function(){
		this.navigation.style.position = "absolute";
		this.navigation.style.top = 15 + "px";
		this.navigation.style.left = ((this.lightBoxWin.offsetWidth / 2) - (this.navigation.offsetWidth /2)) + "px";
	},
	
	positionLoading : function(){
		this.loading.style.top = ((this.lightBoxWin.offsetHeight / 2) - (this.loading.offsetHeight /2)) + "px";
		this.loading.style.left = ((this.lightBoxWin.offsetWidth / 2) - (this.loading.offsetWidth /2)) + "px";
	},
	
	selectMediaItem : function(e, item){
		this.loading.style.display = "";
		this.mediaElement.style.display = "none";
		for(var i = 0; i < this.options.media.length ; i++){
			$("navitem_" + i).removeClassName("navitemselected");
		}
		
		this.currentItem = item;
		this.mediaElement.onload = this.mediaLoaded.bindAsEventListener(this);
		this.mediaElement.src = this.options.media[this.currentItem].url;
		$("navitem_" + this.currentItem).addClassName("navitemselected");
		
		this.title.innerHTML = this.options.media[this.currentItem].desc;
	},
	
	render : function(){
		if(!this.currentItem){
			this.currentItem = 0;
		}	
		
		var titleHolder = document.createElement('div');
		titleHolder.style.cssFloat = "left";
		titleHolder.style.styleFloat = "left";
		this.lightBoxWin.appendChild(titleHolder);
		
		var title = document.createElement('p');
		title.className = "title";
		titleHolder.appendChild(title);
		this.title = title;
		
		this.closeHolder = document.createElement('div');
		this.closeHolder.style.cssFloat = "right";
		this.closeHolder.style.styleFloat = "right";
		this.closeHolder.className = "lbclose";
		this.closeHolder.onmouseup = this.remove.bindAsEventListener(this);
		this.lightBoxWin.appendChild(this.closeHolder);
		
		//navigation
		this.navigation = document.createElement('div');
		this.navigation.style.display = "none";
		for(var i = 0; i < this.options.media.length ; i++){
			var navItem = document.createElement('div');
			navItem.className = "navitem";
			navItem.id = "navitem_" + i;
			navItem.style.cssFloat = "left";
			navItem.style.styleFloat = "left";
			navItem.innerHTML = "&bull;";
			navItem.onmouseup = this.selectMediaItem.bindAsEventListener(this,i);
			this.navigation.appendChild(navItem);
		}
		var navItem = document.createElement('div');
		navItem.style.clear = "both";
		this.navigation.appendChild(navItem);
		this.lightBoxWin.appendChild(this.navigation);
		
		//loading symbol
		this.loading = document.createElement('img');
		this.loading.src = "/images/loading.gif";
		this.loading.style.position = "absolute";
		this.loading.style.top = "100";
		this.loading.style.left = "100";
		this.lightBoxWin.appendChild(this.loading);
		
		var content = document.createElement('p');
		this.lightBoxWin.appendChild(content);
		
		var media = document.createElement('img');
		content.appendChild(media);
		this.mediaElement = media;
		
		this.selectMediaItem(null,0);
	},
	
	show : function(result){
		ColinBell.commons.activateMask();

		this.lightBoxWin = document.createElement('div');
		this.lightBoxWin.style.display = "none";
		this.lightBoxWin.style.height = this.options.height + "px";
		this.lightBoxWin.style.width = this.options.width + "px";
		this.lightBoxWin.className = "messageBox";
		document.body.appendChild(this.lightBoxWin);
		
		this.bfx = this.positionWindow.bindAsEventListener(this);
		
		Event.observe(window, 'resize', this.bfx);
		
		
		this.lightBoxWin.style.display = "";
		
		try{
			this.render();
		} catch(e){}
		
		this.positionWindow();
	},
	
	showMedia : function(){
		this.loading.style.display = "none";
		this.navigation.style.display = "";
		this.positionNavigation();
		this.mediaElement.style.display="";
	},
	
	mediaLoaded : function(){
		this.mediaElement.style.visibility="hidden"; //ie issue
		this.mediaElement.style.display="";
		var height = this.mediaElement.height + this.title.offsetHeight;
		var width = this.mediaElement.width;
		
		if(width == 0){
			var t = new Image();
			t.src = this.mediaElement.src;
			width = t.width;
		}//webkit fix

		this.mediaElement.style.display="none";
		this.mediaElement.style.visibility="visible";

		
		new Effect.Morph(this.lightBoxWin, {
			style:{
				height: height + "px",
				width: width + "px"
			},
			duration: 0.8,
			afterFinish: this.showMedia.bindAsEventListener(this),
			afterUpdate: this.positionWindow.bindAsEventListener(this)
		});
	},
	
	remove : function(){
		this.removeComplete();
		/*new Effect.Morph(this.lightBoxWin, {
			style:{
				height: 100 + "px",
				width: 100 + "px"
			},
			duration: 0.8,
			afterFinish: this.removeComplete.bindAsEventListener(this),
			afterUpdate: this.positionWindow.bindAsEventListener(this)
		});*/
	},
	
	removeComplete : function(){
		Event.stopObserving(window, 'resize', this.bfx);
		ColinBell.commons.deactivateMask();
		if(this.lightBoxWin){
			this.lightBoxWin.parentNode.removeChild(this.lightBoxWin);
		}
		this.lightBoxWin = null;
	}
});

ColinBell.ToolTip = Class.create({
	initialize : function(options) {
		this.setOptions(options);
	},
	
	setOptions: function(options){
		this.options = {
			offsetTop : 60,
			offSetLeft : 210,
			width: 200,
			hidedelay: 0,
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	hide : function(){
		if(this.mouseIsOver){
			return; //dont hide when the user is on the tooltip
		}
		
		if(this.tooltip){
			if(this.options.hidedelay > 0){
				setTimeout(this.doHide.bind(this), this.options.hidedelay);
			}
			else{
				this.doHide();
			}
		}
	},
	
	doHide : function(){
		Effect.Fade(this.tooltip, { duration: 0.3});
	},
	
	setMouseIsOver : function(){
		this.mouseIsOver = true;
	},
	
	setMouseIsOut : function(){
		this.mouseIsOver = false;
	},

	show : function(e, item, content){
		if(this.tooltip){
			this.tooltip.style.top = (item.positionedOffset()[1] - this.options.offsetTop) + "px";
			this.tooltip.style.left = (item.positionedOffset()[0] - this.options.offSetLeft) + "px";
			this.tooltip.innerHTML = content;
			Effect.Appear(this.tooltip, { duration: 0.5 });
		}
		else{
			var el = document.createElement("div");
			el.className = "tooltip";
			el.style.position = "absolute";
			el.style.display = "none";
			el.style.top = (item.positionedOffset()[1] - this.options.offsetTop) + "px";
			el.style.left = (item.positionedOffset()[0] - this.options.offSetLeft) + "px";
			el.style.height = "auto";
			el.style.width = this.options.width + "px";
			el.innerHTML = content;
			el.onmouseover = this.setMouseIsOver.bindAsEventListener(this);
			el.onmouseout = this.setMouseIsOut.bindAsEventListener(this);
			this.options.container.appendChild(el);
			this.tooltip = el;
			
			Effect.Appear(el, { duration: 0.5 });
		}
	}
});

ColinBell.MessageWindow = Class.create({
	initialize : function(options) {
		this.setOptions(options);
	},
	
	setOptions: function(options){
		this.options = {
			title : null,
			buttons: [],
			buttonsWidth: null,
			content : null,
			rendered: false,
			allowClose: true,
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	setButtons : function(buttons){
		this.options.buttons = buttons;
	},
	
	positionWindow : function(){
		var winTop = ((ColinBell.commons.window().height / 2) - (this.messageWin.offsetHeight /2));
		if(winTop < 5){
			winTop = 10;
		}
		
		this.messageWin.style.top = winTop + "px";
		this.messageWin.style.left = ((ColinBell.commons.window().width / 2) - (this.messageWin.offsetWidth /2)) + "px";
		
		ColinBell.commons.resetMask();
	},
	
	callback : null,
	
	render : function(){
		var defer = false;
		var title = document.createElement('p');
		title.className = "title";
		this.messageWin.appendChild(title);
		this.title = title;
		
		var titleText = document.createTextNode(this.options.title);
		title.appendChild(titleText);
		
		var content = document.createElement('p');
		this.messageWin.appendChild(content);
		if(typeof(this.options.content) == "string"){
			content.innerHTML=this.options.content;
		}
		else{
			content.appendChild(this.options.content);
		}
		
		this.buttonholder = document.createElement('div');
		this.buttonholder.className = "buttonholder";
		if(this.options.buttonsWidth){
			this.buttonholder.style.width = this.options.buttonsWidth + "px";
		}
		this.messageWin.appendChild(this.buttonholder);
		
		for(var i = 0; i < this.options.buttons.length ; i++){
			this.addButton(this.options.buttons[i].text, this.options.buttons[i].onmousedown, this.options.buttons[i].onmouseup);
		}
		
		if(this.options.allowClose){
			this.addButton("Close", this.buttonClicked.bindAsEventListener(this), this.remove.bindAsEventListener(this));
		}
		
		return defer;
	},
	
	addButton : function(text, onmousedown, onmouseup){
		this.button = document.createElement('div');
		this.button.className = "button";
		if(onmousedown){this.button.onmousedown = onmousedown;}
		if(onmouseup){this.button.onmouseup = onmouseup;}
		this.buttonholder.appendChild(this.button);
			
		var buttonText = document.createTextNode(text);
		this.button.appendChild(buttonText);
	},
	
	buttonClicked : function(){
		this.button.addClassName("buttonSelected");
		if(this.callback){
			this.callback();
		}
	},
	
	show : function(result){
		ColinBell.commons.activateMask();

		this.messageWin = document.createElement('div');
		this.messageWin.style.display = "none";
		this.messageWin.className = "messageBox";
		document.body.appendChild(this.messageWin);
		
		this.messageWin.style.display = "";
		
		try{
			this.render();
		} catch(e){}
		
		this.positionWindow();
	},
	
	remove : function(){
		ColinBell.commons.deactivateMask();
		if(this.messageWin){
			this.messageWin.parentNode.removeChild(this.messageWin);
		}
		this.messageWin = null;
	}
});

ColinBell.SkillsPath = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		
		if(this.options.graphical){
			this.render();
		}
		else{
			this.renderText();		
		}
	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			graphical : true,
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	hideTooltip : function(e,icon, item){
		if(this.tooltip){
			this.tooltip.hide();
		}
		
		//Effect.Fade(icon, { duration: 0.3, to: 0.5});
			
		item.removeClassName("selected");
	},
	
	showTooltip : function(e, icon, item, data){
		if(this.tooltip){
			this.tooltip.show(e, item, data.description);
		}
		else{
			this.tooltip = new ColinBell.ToolTip({
				container : this.options.container,
				offsetTop : 60,
				offSetLeft : -40,
				width: 200,
			});
			this.tooltip.show(e, item, data.description);
		}
		
		item.addClassName("selected");
		
		//Effect.Appear(icon, { duration: 0.5 });
	},
	
	template : function(data){
		var template = "<p><span class='bold'>"+ data.name +"<\/span><p>";
		template+= "<p class'description'>"+ data.description +"<p>";
		return(template);
	},
	
	renderText : function(){
		var holder = document.createElement("div");
		holder.className = "skills";
		this.options.container.appendChild(holder);

		for(var i = 0; i < this.options.data.length ; i++){
			var label = document.createElement("div");
			label.className = "skill";
			label.innerHTML = this.template(this.options.data[i]);
			holder.appendChild(label);
		}
	},
	
	render : function(){
		var holder = document.createElement("div");
		holder.className = "skills";
		this.options.container.appendChild(holder);
		
		var lineWidth = 700;
		var increment = (lineWidth / this.options.data.length);
		increment = increment + (increment/this.options.data.length);
		var left = 20;
		var top = 30;
		
		var line = document.createElement("div");
		line.className = "skillsline";
		line.style.position = "absolute";
		line.style.left = left + 5 + "px";
		line.style.top = top + 15 + "px";
		line.style.width = (lineWidth - 5) + "px";
		this.options.container.appendChild(line);
		
		for(var i = 0; i < this.options.data.length ; i++){
			var label = document.createElement("div");
			label.className = "label";
			label.style.position = "absolute";
			label.style.left = (left) + 10 + "px";
			label.style.top = top-40 + "px";
			label.style.width = 100 + "px";
			label.style.transform = "rotate("+ 325 +"deg)";
			label.style.MozTransform = "rotate("+ 325 +"deg)";
			label.style.WebkitTransform = "rotate("+ 325 +"deg)";
			label.style.msTransform = "rotate("+ 325  +"deg)";
			
			label.innerHTML = this.options.data[i].name;
			holder.appendChild(label);
			
			var item = document.createElement("div");
			item.className = "dot";
			item.style.position = "absolute";
			item.style.left = left + "px";
			item.style.top = top + "px";
			
			holder.appendChild(item);
			
			var icon = document.createElement("img");
			icon.src = "./images/" + this.options.data[i].icon;
			icon.onmouseover = this.showTooltip.bindAsEventListener(this, icon, item, this.options.data[i]);
			icon.onmouseout = this.hideTooltip.bindAsEventListener(this, icon, item);
			icon.className = "icon";
			/*icon.style.opacity = (50 / 100);
			icon.style.MozOpacity = (50 / 100);
			icon.style.KhtmlOpacity = (50 / 100); 
			icon.style.filter = "alpha(opacity="+ 50 +")";*/
			item.appendChild(icon);
			
			Effect.Pulsate(icon, {pulses: 100,duration: 100,from: 0.4});
			
			left = left + increment;
		}
	}
})

ColinBell.ValueBox = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		
		if(this.options.graphical){
			this.render();
		}
		else{
			this.renderText();
		}
	},
	
	setOptions: function(options){
		this.options = {
			topText : null,
			icon : null,
			bottomText : null,
			value: null,
			tooltips: false,
			description : "",
			graphical: true,
			showTopText : true,
			showBottomText : true,
			clazz : "",
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	template : function(data){
		template= "<p class'description'>"+ this.options.description +"<p>";
		return(template);
	},
	
	renderText : function(){
		var holder = document.createElement("div");
		holder.className = "valuebox";
		holder.innerHTML = this.template();
		this.options.container.appendChild(holder);
	},
	
	hideTooltip : function(e, item){
		if(this.tooltip){
			this.tooltip.hide();
		}
	},
	
	showTooltip : function(e, item){
		if(this.tooltip){
			this.tooltip.show(e, item, this.options.description);
		}
		else{
			this.tooltip = new ColinBell.ToolTip({
				container : this.options.container,
				offsetTop : 60,
				offSetLeft : 0,
				hidedelay: 2000,
				width: 200,
			});
			this.tooltip.show(e, item, this.options.description);
		}
	},
	
	render : function(){
		var holder = document.createElement("div");
		if(this.options.clazz){
			holder.className = "valuebox " + this.options.clazz;
		}
		else{
			holder.className = "valuebox";
		}
		this.options.container.appendChild(holder);
		
		if(this.options.topText && this.options.showTopText){
			var top = document.createElement("div");
			top.className = "text";
			top.innerHTML = this.options.topText;
			holder.appendChild(top);
		}
		
		if(this.options.value){
			var topText = document.createElement("div");
			topText.className = "value";
			topText.innerHTML = this.options.value;
			holder.appendChild(topText);
		}
		
		if(this.options.icon){
			var iconEl = document.createElement("img");
			iconEl.className = "icon";
			iconEl.src = this.options.icon;
			if(this.options.tooltips && this.options.description){
				iconEl.onmouseover = this.showTooltip.bindAsEventListener(this, iconEl);
				iconEl.onmouseout = this.hideTooltip.bindAsEventListener(this, iconEl);
			}
			holder.appendChild(iconEl);
		}
		
		if(this.options.bottomText && this.options.showBottomText){
			var bottomText = document.createElement("div");
			bottomText.className = "text";
			bottomText.innerHTML = this.options.bottomText;
			holder.appendChild(bottomText);
		}
	}
})

ColinBell.InfoBox = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		if(this.options.graphical){
			this.render();
		}
		else{
			this.renderText();
		}
	},
	
	setOptions: function(options){
		this.options = {
			title : null,
			content: null,
			graphical : true,
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	template : function(data){
		var template = "<div>";
		template+= "<p><span class='bold'>"+ data.title +"<\/span><p>";
		template+= "<p class'description'>"+ data.content +"<p>";
		template+= "<div>";
		return(template);
	},
	
	renderText : function(){
		var holder = document.createElement("div");
		holder.className = "infobox";
		this.options.container.appendChild(holder);
		
		holder.innerHTML = this.template({
			title : this.options.title,
			content : this.options.content
		})
	},
	
	render : function(){
		var holder = document.createElement("div");
		holder.className = "infobox";
		this.options.container.appendChild(holder);
		
		var title = document.createElement("div");
		title.className = "title";
		title.innerHTML = this.options.title;
		holder.appendChild(title);
		
		var content = document.createElement("div");
		content.className = "content";
		content.innerHTML = this.options.content;
		holder.appendChild(content);
	}
})

ColinBell.ToolsText = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		this.render();
	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	template : function(data){
		var template = "<p><span class='bold'>"+ data.name +"<\/span><p>";
		if(data.includes){
			template+= "<p><span class='bold'>Includes: <\/span>"+ data.includes +"<p>";
		}
		template+= "<p><span class='bold'>Proficiency: <\/span>"+ data.expertise +"%<p>";
		template+= "<p><span class='bold'>Used: <\/span>"+ data.frequency +"% of the time<p>";
		template+= "<p class'description'>"+ data.description +"<p>";
		return(template);
	},
	
	render : function(){
		var el = document.createElement("div");
		el.className = "toolstext";
		this.options.container.appendChild(el);
		
		for(var i = 0; i < this.options.data.length ; i++){
			var item = document.createElement("div");
			item.className = "tool";
			item.innerHTML = this.template(this.options.data[i]);
			el.appendChild(item);
		}
	}
});

ColinBell.ToolsGraph = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		this.render();
	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			expertise : ["JUST LEARNING","BEGINNER","GETTING THERE","ADVANCED", "PRO"],
			frequency : ["RARELY","SOMETIMES","EVERY WEEK","EVERY DAY", "ALL DAY"],
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	render : function(){
		var el = document.createElement("div");
		el.className = "toolsgraph";
		//el.style.position = "relative";
		this.options.container.appendChild(el);
		var startLeft = "20";
		var frequecyLeft = 170;
		var left = 170;
		var top = 40;
		var labelTop = 70;
		var topIncrement = 50;
		var increment = 100;
		
		var expertiseLabel = document.createElement("div");
		expertiseLabel.className = "expertiseLabel";
		expertiseLabel.style.position = "absolute";
		expertiseLabel.innerHTML = "EXPERTISE";
		expertiseLabel.style.top = top + "px";
		expertiseLabel.style.left = startLeft + "px";
		expertiseLabel.style.width = 120 + "px";
		el.appendChild(expertiseLabel);
		
		//draw expertise labels and lines
		for(var i = 0; i < this.options.expertise.length ; i++){
			var text = document.createElement("div");
			text.className = "expertiseLabelsmall";
			text.style.position = "absolute";
			text.style.top = top + "px";
			text.style.left = left + "px";
			text.style.width = increment + "px";
			text.style.cssFloat = "left";
			text.innerHTML = this.options.expertise[i];
			el.appendChild(text);
			
			var line = document.createElement("div");
			line.style.position = "absolute";
			line.style.height = (this.options.data.length * topIncrement) - (15) +"px";
			line.style.width = 1 + "px";
			line.style.backgroundColor = "#a69e89";
			line.style.left = left + "px";
			line.style.top = top + 20 + "px";
			el.appendChild(line);
			left+=increment;
		}
		
		for(var i = 0; i < this.options.data.length ; i++){
			var text = document.createElement("div");
			text.className = "itemlabel";
			text.style.position = "absolute";
			text.innerHTML = this.options.data[i].name;
			text.style.top = labelTop + "px";
			text.style.left = startLeft + "px";
			text.style.width = 140 + "px";
			el.appendChild(text);
			
			if(this.options.data[i].includes){
				var extra = document.createElement("div");
				extra.className = "itemlabelextra";
				extra.style.position = "absolute";
				extra.innerHTML = this.options.data[i].includes;
				extra.style.top = labelTop + 15 + "px";
				extra.style.left = startLeft + "px";
				extra.style.width = 140 + "px";
				el.appendChild(extra);
			}
			
			var frequencyValue = this.options.data[i].frequency * ((this.options.expertise.length * increment) - increment) / 100;
			var expertiseValue = this.options.data[i].expertise * ((this.options.frequency.length * increment) - increment) / 100;
			
			var expertiseBar = document.createElement("div");
			expertiseBar.className = "expertisebar";
			expertiseBar.style.position = "absolute";
			expertiseBar.style.top = labelTop - 10 + "px";
			expertiseBar.style.left = frequecyLeft+1 + "px";
			expertiseBar.style.width = expertiseValue + "px";
			expertiseBar.style.height = 20 + "px";
			expertiseBar.title = expertiseValue;
			el.appendChild(expertiseBar);
			
			var frequencyBar = document.createElement("div");
			frequencyBar.className = "frequencybar";
			frequencyBar.style.position = "absolute";
			frequencyBar.style.top = labelTop + 5 + "px";
			frequencyBar.style.left = frequecyLeft+1 + "px";
			frequencyBar.style.width = frequencyValue + "px";
			frequencyBar.style.height = 20 + "px";
			frequencyBar.title = frequencyValue;
			el.appendChild(frequencyBar);
			
			labelTop+= topIncrement;
		}
		
		var frequencyLabel = document.createElement("div");
		frequencyLabel.className = "frequecyLabel";
		frequencyLabel.style.position = "absolute";
		frequencyLabel.innerHTML = "FREQUENCY OF USE";
		frequencyLabel.style.top = labelTop + "px";
		frequencyLabel.style.left = startLeft + "px";
		frequencyLabel.style.width = 140 + "px";
		el.appendChild(frequencyLabel);
		
		//draw frequency
		for(var i = 0; i < this.options.frequency.length ; i++){
			var text = document.createElement("div");
			text.className = "frequencyLabelsmall";
			text.style.position = "absolute";
			text.style.top = (labelTop) + "px";
			text.style.left = frequecyLeft + "px";
			text.style.width = increment + "px";
			text.style.cssFloat = "left";
			text.innerHTML = this.options.frequency[i];
			el.appendChild(text);
			frequecyLeft+=increment;
		}
	}
})

ColinBell.Welcome = Class.create({
	formItems: [],
	initialize : function(options) {
		this.setOptions(options);
		this.fillInBlanks();
		this.renderHeader();
		this.renderMessage();
	},
	
	fillInBlanks : function(){
		if(ColinBell.ContactName){
			this.options.welcomeHeader = this.options.welcomeHeader.replace("\{contact name\}", ColinBell.ContactName);
		}
		
		this.options.welcomeText = this.options.welcomeText.replace("\{years\}", this.calculateYears());
		if(ColinBell.Company){
			this.options.welcomeText = this.options.welcomeText.replace("\{company name\}", ColinBell.Company);
		}
	},
	
	calculateYears : function(){
		var d = new Date();
		return d.getFullYear() - 1998;

	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			parent: null,
			container: document.body,
			welcomeHeader: "",
			welcomeText : "",
			allowGraphicSelect : true
		}
		Object.extend(this.options, options || {});
	},
	
	toggleParentMode : function(e, bool){
		var target;
		if (!e) var e = window.event;
		if (e.target) target = e.target;
		else if (e.srcElement) target = e.srcElement;

		if(this.infoGraphicLink){
			this.infoGraphicLink.className = "";
			this.textLink.className = "";
			target.className = "selected";
		}
		
		this.options.parent.toggleMode(bool);
		
		ColinBell.commons.track("portfolio", "/view_toggle?name=" + ColinBell.ContactName + "&company=" + ColinBell.Company);
	},
	
	createField : function(form, name, type, text, optional, validation){
		var div = document.createElement("div");
		div.className = "formel";
		form.appendChild(div);
		
		var label = document.createElement("label");
		label.setAttribute("for", name);
		label.innerHTML = text + ":" + (optional ? "" : "&nbsp;<span class=\"nag\">*</span>");
		div.appendChild(label);
		
		var field;
		if(type == "textarea"){
			field = document.createElement("textarea");
			field.setAttribute("type", type);
			field.setAttribute("name", name);
			div.appendChild(field);
		}
		else{
			field = document.createElement("input");
			if(!optional){
				field.onblur = this.checkFieldText.bindAsEventListener(this, validation);
				field.onkeyup = this.checkFieldText.bindAsEventListener(this, validation);
			}
			field.setAttribute("type", type);
			field.setAttribute("name", name);
			div.appendChild(field);
		}
		
		this.formItems[this.formItems.length] = {"text" : text, "item" : field, "optional" : optional, "validation" : validation}
		
		return field;
	},
	
	validateFieldItem : function(target, validation){
		var invalid = false;
		if(validation == "email"){
			var text = target.value;
			var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
			var matches = text.match(re);
			if(matches != null){invalid = false;}
			else{invalid = true;}
		}
		else{
			if(target.value.length <= 3){invalid = true;}
			else{invalid = false}
		}
		
		if(invalid){
			target.oldClassName = target.className;
			target.className = "invalid";
		}
		else{
			target.className = "";
		}
		
		return invalid;
	},
	
	checkFieldText : function(e, validation){
		var target;
		if (!e) var e = window.event;
		if (e.target) target = e.target;
		else if (e.srcElement) target = e.srcElement;
		this.validateFieldItem(target, validation);
	},
	
	formIsInvalid : function(){
		var formValid = true;
		for(var i = 0; i < this.formItems.length ; i++){
			if(!this.formItems[i].optional){
				formValid = this.validateFieldItem(this.formItems[i].item, this.formItems[i].validation);
			}
		}
		return formValid;
	},
	
	showContactMeDiaglog : function(){
		this.contactMeForm = document.createElement("form");
		
		var legend = document.createElement("legend");
		this.contactMeForm.appendChild(legend);
		
		var nameField = this.createField(legend, "name", "text", "Name", false, "text");
		var companyField = this.createField(legend, "company", "text", "Company", false, "text");
		var telephoneField = this.createField(legend, "telephone", "text", "Telephone", true, null);
		var emailField = this.createField(legend, "email", "text", "Email", false, "email");
		var commentsField = this.createField(legend, "comments", "textarea", "Comment", true, null);
		
		nameField.value = ColinBell.ContactName;
		companyField.value = ColinBell.Company
		
		var obj = this;
		var contactMeDialog = new ColinBell.MessageWindow({"title" : "Please fill in the form below and click \"send\"","content" : this.contactMeForm ,"allowClose" : true})
		
		contactMeDialog.setButtons([{
			text : "Send",
			onmouseup : function(){
				if(!obj.formIsInvalid()){
					obj.contactMeForm.setAttribute("action", "contactme.php");
					obj.contactMeForm.setAttribute("method", "post");
					obj.contactMeForm.request({
						method: 'post',
						parameters : {"name" : nameField.value, "company" : companyField.value, "telephone" : telephoneField.value, "email" : emailField.value, "comments" : commentsField.value},
						onSuccess: function(t){
							var jsonData = t.responseText.evalJSON();
						
							var messageBox = new ColinBell.MessageWindow({
								"title" : jsonData.description,
								"content" : jsonData.message,
								"allowClose" : true
							});
							
							messageBox.show();
						},
						onFailure : function(){
							var messageBox = new ColinBell.MessageWindow({"title" : "Gremlin issue!","content" : "I'm sorry, but gremlins are currently recking havock with the site, please try again later.","allowClose" : true}).show();
							//Effect.Appear($("searchmask"), { duration: 6 });
						}
					});
					contactMeDialog.remove();
				}
			}
		}]);
		
		contactMeDialog.show();
		ColinBell.commons.track("portfolio", "/contact_me?name=" + ColinBell.ContactName + "&company=" + ColinBell.Company);
	},
	
	renderHeader : function(){
		var el = document.createElement("div");
		el.className = "title";
		this.options.container.appendChild(el);
		
		var title = document.createElement("span");
		title.className = "titlemessage";
		title.style.cssFloat = "left";
		title.innerHTML = this.options.welcomeHeader;
		el.appendChild(title);
		
		var menu = document.createElement("span");
		menu.className = "menu";
		el.appendChild(menu);
		
		if(this.options.allowGraphicSelect){
			if(!this.options.parent){return;}
			this.infoGraphicLink = document.createElement("a");
			if(this.options.parent.options.graphical){
				this.infoGraphicLink.className = "selected";
			}
			this.infoGraphicLink.innerHTML = "VIEW INFOGRAPHICS";
			this.infoGraphicLink.onmouseup = this.toggleParentMode.bindAsEventListener(this, true);
			menu.appendChild(this.infoGraphicLink);
		}
		
		this.textLink = document.createElement("a");
		if(!this.options.parent.options.graphical){
			this.textLink.className = "selected";
		}
		this.textLink.innerHTML = "VIEW PLAINTEXT";
		this.textLink.onmouseup = this.toggleParentMode.bindAsEventListener(this, false);
		menu.appendChild(this.textLink);
		
		var gitHubLink = document.createElement("a");
		gitHubLink.innerHTML = "GIT HUB";
		gitHubLink.onmouseup = this.gitHub.bindAsEventListener(this);
		gitHubLink.target = "_new";
		menu.appendChild(gitHubLink);
		
		var linkedInLink = document.createElement("a");
		linkedInLink.innerHTML = "LINKED IN";
		linkedInLink.onmouseup = this.linkedIn.bindAsEventListener(this);
		linkedInLink.target = "_new";
		menu.appendChild(linkedInLink);
		
		var contactMeLink = document.createElement("a");
		contactMeLink.innerHTML = "CONTACT ME";
		contactMeLink.onmouseup = this.showContactMeDiaglog.bindAsEventListener(this);
		menu.appendChild(contactMeLink);
	},
	
	gitHub : function(){
		ColinBell.commons.track("portfolio", "/github?name=" + ColinBell.ContactName + "&company=" + ColinBell.Company);
		window.open("https://github.com/BigBadOwl/", '');
	},
	
	linkedIn : function(){
		ColinBell.commons.track("portfolio", "/linked_in?name=" + ColinBell.ContactName + "&company=" + ColinBell.Company);
		window.open("http://www.linkedin.com/pub/colin-bell/a/2a4/611", '');
	},
	
	renderMessage : function(){
		var el = document.createElement("div");
		el.style.clear = "both";
		el.className = "message";
		el.innerHTML = this.options.welcomeText;
		this.options.container.appendChild(el);
	}
});

ColinBell.Legend = Class.create({
	cData : [],
	initialize : function(options) {
		this.setOptions(options);
		this.calculateData(this.options.data);
		this.cData.sort(this.dataSorter);
		this.render();
	},
	
	dataSorter : function(a, b) {
		if(a.name<b.name){return -1;}
		if(a.name>b.name){return 1;}
		return 0;
	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			container: document.body,
			parent: null
		}
		Object.extend(this.options, options || {});
	},
	
	render : function(){
		for(prop in this.cData){
			if(this.cData[prop].color){
				var el = this.createItem(this.cData[prop].name, this.cData[prop].color, this.cData[prop].clazz);
				this.options.container.appendChild(el);
			}
		}
	},
	
	selectItem : function(e, className){
		this.options.parent.CoreTechnologiesInfoGraphic.toggleHighlight(20);
		var nodes = document.getElementsByClassName(className);
		for(var i = 0; i < nodes.length ; i++){
			nodes[i].style.opacity = (100);
			nodes[i].style.MozOpacity = (100);
			nodes[i].style.KhtmlOpacity = (100); 
			nodes[i].style.filter = "alpha(opacity="+ 100 +")";
			nodes[i].style.boxShadow="5px 5px 5px #888888";
			nodes[i].style.MozBoxShadow="5px 5px 5px #888888";
			nodes[i].style.webkitBoxShadow="5px 5px 5px #888888";
		}
	},
	
	deSelectItem : function(e, className){
		this.options.parent.CoreTechnologiesInfoGraphic.toggleHighlight(100);
		var nodes = document.getElementsByClassName(className);
		for(var i = 0; i < nodes.length ; i++){
			nodes[i].style.boxShadow= "none";
			nodes[i].style.MozBoxShadow= "none";
		}
	},
	
	createItem : function(text, color, className){
		var el = document.createElement("div");
		el.className = "item";
		el.onmouseover = this.selectItem.bindAsEventListener(this, className);
		el.onmouseout = this.deSelectItem.bindAsEventListener(this, className);
		
		var elDot = document.createElement("div");
		elDot.className = "dot";
		elDot.style.backgroundColor = color;
		el.appendChild(elDot);
		
		var elText = document.createElement("span");
		elText.appendChild(document.createTextNode(text));
		el.appendChild(elText);

		return(el);
	},
	
	calculateData : function(data){
		if(!data){return;}
		for(var i = 0; i < data.length ; i++){
			if(data[i].xtype == "skill"){
				var name = data[i].name;
				var value = data[i].value;
				var color = data[i].color;
				var className = data[i].clazz;
				if(this.cData[name]){
					this.cData[name].value = this.cData[name].value + value;
				}
				else{
					var obj = new Object();
					obj.name = name;
					obj.value = value;
					obj.color = color;
					obj.clazz = className;
					this.cData[name] = obj;
				}
			}
			
			if(this.options.data[i].data){
				this.calculateData(data[i].data);
			}
			
		}
	}
});

ColinBell.Radial = Class.create({
	parent : null,
	children : [],
	coordinates : null,
	initialize : function(options) {
		this.setOptions(options);
		this.render();
	},
	setOptions: function(options){
		this.options = {
			data : [],
			height: 5,
			width: 5,
			container: document.body,
			radius: 10,
			centerX : 0,
			centerY : 0,
			border: false,
			growth: 100,//% value of dot size
			color : "#FFFFFF",
			rotate : false,
			showValue : false,
			showLine : false,
			position: "absolute",
			showLabel: false,
			bClockwise: true,
			getRotation : function(degrees, index, numItems){return degrees;}
		}
		Object.extend(this.options, options || {});
	},
	
	getAngleAtIndex : function(iIdx, iNum){
		return 2 * Math.PI * parseFloat(iIdx/iNum); // radians
	},
	
	getCoords: function(radius, iIdx, iNum, bClockwise, cluster){
		var angle = this.getAngleAtIndex(iIdx, iNum);
		
		if(cluster){
			//iNum= iNum * 2;
			//angle = 2 * cluster * parseFloat(iIdx/iNum*4);
		}
		
		var left = this.options.centerX + ( Math.cos( angle ) * radius );
		var top = this.options.centerY + ( Math.sin( parseInt(angle*100)/100 ) * radius );
		var degrees = this.options.rotate ? this.options.getRotation( angle * 180 / Math.PI, iIdx, iNum ) : 0;
		var lineAngle = this.options.getRotation( angle * 180 / Math.PI, iIdx, iNum);
		var slice = this.options.rotate ? ( this.getAngleAtIndex(1, iNum) * 180 / Math.PI ) : 0;
		var rotation = ( bClockwise==true ? "-=" : "+=" ) + slice;
		return {
			left: left, 
			top: top, 
			angle: degrees,
			lineAngle: lineAngle,
			animObj:{
				left: left, 
				top: top, 
				radrotate: rotation
			} 
		};
	},
	
	toggleHighlight : function(per){
		var nodes = this.options.container.childNodes;
		for(var i = 0; i < nodes.length ; i++){
			if(this.highlight){
				nodes[i].style.opacity = (100);
				nodes[i].style.MozOpacity = (100);
				nodes[i].style.KhtmlOpacity = (100); 
				nodes[i].style.filter = "alpha(opacity="+ 100 +")";
			}
			else{
				nodes[i].style.opacity = (per / 100);
				nodes[i].style.MozOpacity = (per / 100);
				nodes[i].style.KhtmlOpacity = (per / 100); 
				nodes[i].style.filter = "alpha(opacity="+ per +")";
				
			}
		}
		if(this.highlight){this.highlight = false;}
		else{this.highlight = true;}
	},
	
	render : function(){
		for(var i = 0; i < this.options.data.length ; i++){
			var cHeight = this.options.height;
			var cWidth = this.options.width;
			if(this.options.data[i].xtype == "skill"){
				cWidth+=(this.options.data[i].value/10);
				cHeight+=(this.options.data[i].value/10);
			}
				
			
			
			if(this.options.showLine){
				if(this.options.data[i].xtype == "skill"){
					lineCoords = this.getCoords(this.options.radius/2, i, this.options.data.length);
					spline = this.createLine(lineCoords, this.options.radius);
					this.options.container.appendChild(spline);
				}
				else{
					var lineCoords = this.getCoords(this.options.radius - (this.options.radius/6), i, this.options.data.length);
					var spline = this.createLine(lineCoords, this.options.radius/3.9);
					this.options.container.appendChild(spline);
				}
			}
			
			if(this.options.data[i].xtype == "project"){
				this.coordinates = this.getCoords(this.options.radius, i, this.options.data.length, false);
			}
			else{
				this.coordinates = this.getCoords(this.options.radius, i, this.options.data.length, true, this.options.parent.coordinates.lineAngle);
			}
			
			var el = this.createItem(this.options.data[i], cHeight, cWidth);
			this.options.container.appendChild(el);
			if(this.options.data[i].xtype == "project"){
				Effect.Pulsate(el, {
					pulses: 100,
					duration: 100,
					from: 0.4
				});
			}
			
			if(this.options.showLabel){
				var labelCoords = this.getCoords(this.options.radius  - (this.options.radius/2.5), i, this.options.data.length);
				var label = this.createLabel(labelCoords, this.options.data[i].name);
				if(this.options.data[i].media){
					var hasMedia = document.createElement("img");
					hasMedia.src="/images/camera-icon.png"
					hasMedia.style.paddingLeft = "3px";
					hasMedia.style.cursor = "pointer";
					hasMedia.border = 0;
					label.appendChild(hasMedia);
					hasMedia.onmouseup = this.showMedia.bindAsEventListener(this, label, this.options.data[i].media);
				}
				this.options.container.appendChild(label);
			}
			
			if(this.options.showValue){
				var vLabelCoords = this.getCoords(this.options.radius - (this.options.radius/1.8), i, this.options.data.length);
				var vLabel = this.createValueLabel(vLabelCoords, this.options.data[i].value);
				this.options.container.appendChild(vLabel);
			}
			
			if(this.options.data[i].data){
				var child = new ColinBell.Radial({
					data: this.options.data[i].data,
					radius: 25,
					parent: this,
					width: cWidth,
					height: cHeight,
					container: this.options.container,
					growth: 100,
					showValue : false,
					showLine : false,
					color: "transparent",
					centerX : this.coordinates.left,
					centerY : this.coordinates.top, //add half width
				});
				
				var childNode = child.render();
			}
			
			this.children[this.children.length] = el;
		}//end for loop
		
		return(el);
	},
	
	degreeToIEMatrix : function(deg){
	    var deg2radians = Math.PI * 2 / 360;
	    var rad = deg * deg2radians ;
	    var costheta = Math.cos(rad);
	    var sintheta = Math.sin(rad);
	
	    var M11 = costheta;
	    var M12 = -sintheta;
	    var M21 = sintheta;
	    var M22 = costheta;
	
		return("progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',M11="+ M11 +", M12="+ M12 +",M21="+ M21 +", M22="+ M22 +")");
	},
	
	createLine : function(lineCoords, width){
		var el = document.createElement("div");
		el.className = "line";
		//el.width = width + "px";
		el.style.width = width + "px";
		el.style.position = this.options.position;
		el.style.left = lineCoords.left - (width/2) + "px";
		el.style.top = lineCoords.top + "px";
		el.style.transform = "rotate("+ lineCoords.lineAngle +"deg)";
		el.style.MozTransform = "rotate("+ lineCoords.lineAngle +"deg)";
		el.style.WebkitTransform = "rotate("+ lineCoords.lineAngle +"deg)";
		el.style.msTransform = "rotate("+ lineCoords.lineAngle +"deg)";
		//el.style.filter = this.degreeToIEMatrix(lineCoords.lineAngle);
		//el.appendChild(document.createTextNode("a"));
		return(el);
	},
	
	createLabel : function(labelCoords, text){
		var el = document.createElement("div");
		el.className = "label";
		el.style.position = this.options.position;
		
		var compStr = this.getCompassStr(labelCoords.lineAngle);
		el.className = "label " + compStr;
		
		el.style.left = labelCoords.left - (50) + "px";
		el.style.top = labelCoords.top - (10) + "px";
		el.style.height = 20 + "px";
		el.style.width = 100 + "px";
		el.style.textAlign = "center";
		
		var rAngle = labelCoords.lineAngle - 270;
		
		el.style.transform = "rotate("+ rAngle +"deg)";
		el.style.MozTransform = "rotate("+ rAngle +"deg)";
		el.style.WebkitTransform = "rotate("+ rAngle +"deg)";
		el.style.msTransform = "rotate("+ rAngle +"deg)";
		//el.style.filter = this.degreeToIEMatrix(rAngle);
		
		el.appendChild(document.createTextNode(text));
		return(el);
	},
	
	getCompassStr : function(angle){
		if((angle >= 0) && (angle < 90)){
			return "southeast";
		}
		else if((angle >= 90) && (angle < 180)){
			return "southwest";
		}
		else if((angle >= 180) && (angle < 270)){
			return "northwest";
		}
		else if((angle >= 270) && (angle < 360)){
			return "northeast";
		}
	},
	
	createValueLabel : function(labelCoords, text){
		var el = document.createElement("div");
		el.style.position = this.options.position;
		el.style.left = labelCoords.left-15 + "px";
		el.style.top = labelCoords.top-10 + "px";
		el.className = "valuelabel";
		
		var compStr = this.getCompassStr(labelCoords.lineAngle);
		el.className = "valuelabel " + compStr;
		
		if((labelCoords.lineAngle >= 90) && (labelCoords.lineAngle < 180)){
			labelCoords.lineAngle = labelCoords.lineAngle + 180;
		}
		else if((labelCoords.lineAngle >= 180) && (labelCoords.lineAngle < 270)){
			labelCoords.lineAngle = labelCoords.lineAngle - 180;
		}
		
		el.style.transform = "rotate("+ labelCoords.lineAngle +"deg)";
		el.style.MozTransform = "rotate("+ labelCoords.lineAngle +"deg)";
		el.style.WebkitTransform = "rotate("+ labelCoords.lineAngle +"deg)";
		el.style.msTransform = "rotate("+ labelCoords.lineAngle +"deg)";
		
		//el.style.filter = this.degreeToIEMatrix(labelCoords.lineAngle);
		
		el.appendChild(document.createTextNode(text));
		
		return(el);
	},
	
	projectInfoTemplate : function(data){
		var template = "<p><span class='bold'>Project: "+ data.name +"<\/span><p>";
		template+= "<p><span class='bold'>Year: <\/span>"+ data.value +"<p>";
		template+= "<p><span class='bold'>Customer: <\/span>"+ data.customer +"<p>";
		template+= "<p class'description'>"+ data.description +"<p>";
		return(template);
	},
	
	hideTooltip : function(){
		if(this.tooltip){
			this.tooltip.hide();
		}
	},
	
	showTooltip : function(e, item, data){
		if(data.xtype == "project"){
			if(this.tooltip){
				this.tooltip.show(e, item, this.projectInfoTemplate(data));
			}
			else{
				this.tooltip = new ColinBell.ToolTip({container : this.options.container});
				this.tooltip.show(e, item, this.projectInfoTemplate(data));
			}
		}
	},
	
	showMedia : function(e, item, media){
		if(!media){return;}
		var lb = new ColinBell.LightBox({"media": media});
		lb.show();
	},
	
	createItem : function(data, height, width){
		var el = document.createElement("div");
		if(data.xtype == "skill"){
			if(data.clazz){
				el.className = "node " + data.clazz;
			}
			else{
				el.className = "node";
			}
		}
		else{
			el.className = "node nodeparent ";
		}
		el.style.position = this.options.position;
		el.style.left = this.coordinates.left - (width/2) + "px";
		el.style.top = this.coordinates.top - (height/2)  + "px";
		el.style.height = height + "px";
		el.style.width = width + "px";
		if(data.color){el.style.backgroundColor = data.color;}
		el.style.transform = "rotate("+ this.coordinates.angle +"deg)";
		if(this.options.border){
			el.style.border.width = "1px";
			el.style.border.color = "#CCCCCC";
			el.style.borderStyle = "solid";
		}
		el.style.borderRadius = '1em'; // w3c
		el.style.MozBorderRadius = '1em'; // mozilla
		
		el.onmouseover = this.showTooltip.bindAsEventListener(this, el, data);
		el.onmouseout = this.hideTooltip.bindAsEventListener(this, el, data);
		
		return(el);
	}
});

ColinBell.CoreTechnicalText = Class.create({
	parent : null,
	children : [],
	coordinates : null,
	initialize : function(options) {
		this.setOptions(options);
		this.render(this.options.data, this.options.container);
	},
	
	setOptions: function(options){
		this.options = {
			data : [],
			container: document.body
		}
		Object.extend(this.options, options || {});
	},
	
	render: function(data, node){
		var el = document.createElement("div");
		node.appendChild(el);
		
		for(var i = 0; i < data.length ; i++){
			var item = this.createItem(data[i]);
			el.appendChild(item);
			
		}
	},
	
	createItem : function(data){
		var el = document.createElement("div");
		el.className = "project";
		el.innerHTML = this.projectTemplate(data);
		return(el);
	},
	
	projectTemplate : function(data){
		var template = "<p><span class='bold'>"+ data.name +"<\/span><p>";
		template+= "<p><span class='bold'>Year: <\/span>"+ data.value +"<p>";
		template+= "<p><span class='bold'>Customer: <\/span>"+ data.customer +"<p>";
		template+= "<p>"+ data.description +"<p>";
		if(data.data){
			template+= "<p>";
			template+= "<span class='bold'>Skills used: <\/span>";
			for(var i = 0; i < data.data.length ; i++){
				template+= "<span>";
				template+= data.data[i].name;
				if(i < data.data.length-1){
					template+= ",";
				}
				template+= "<\/span>";
			}
			template+= "<\/p>";
		}
		return(template);
	}
	
});

ColinBell.Portfolio = Class.create({
	initialize : function(options) {
		this.setOptions(options);
		var comp = this;
		new Ajax.Request(this.options.url, {
			method: 'get',
			//requestHeaders: {Accept: 'application/json'},
			onSuccess: function(transport) {
				try{
					var json = transport.responseText.evalJSON();
					comp.setOptions(json);
					comp.upDateOptions(options); //main options override data
					comp.options.CoreTechnologiesData.sort(comp.dataSorter);
					comp.render();
				} catch(e){
					var messageBox = new ColinBell.MessageWindow({"title" : "Data Issue","content" : e ,"allowClose" : false}).show();
					Effect.Appear($("searchmask"), { duration: 6 });
				}
		  	},
		  	onFailure : function(){
		  		var messageBox = new ColinBell.MessageWindow({"title" : "Gremlin issue!","content" : "I'm sorry, but gremlins are currently recking havock with the site, please try again later.","allowClose" : false}).show();
				Effect.Appear($("searchmask"), { duration: 6 });
		  	}
		});
		
	},
	
	setOptions: function(options){
		this.options = {
			url : "./data_dn.json",
			container: document.body,
			allowGraphicSelect : true,
			graphical: true,
			CoreTechnologies : [],
			ToolsData : [],
			SkillsPaths : [],
			InfoBoxes : [],
			ValueBoxes : [],
			SiteInformation : []
		}
		Object.extend(this.options, options || {});
	},
	
	upDateOptions: function(updatedOpts){
		for(prop in this.options){
			if(prop in updatedOpts){
				this.options[prop] = updatedOpts[prop];
			}
		}
	},
	
	toggleMode : function(bool){
		if(this.options.graphical){
			if(!bool){
				this.options.graphical = false;
				this.renderCoreTechnologiesText();
				this.renderToolsText();
				this.renderToolInfoBoxGraphic();
				this.renderEducationBoxes();
				this.renderSkillsPath();
				this.renderSiteInformation();
			}
		}
		else{
			if(bool){
				this.options.graphical = true;
				this.renderCoreTechnologiesGraphic();
				this.renderToolsGraphic();
				this.renderToolInfoBoxGraphic();
				this.renderEducationBoxes();
				this.renderSkillsPath();
				this.renderSiteInformation();
			}
		}
	},
	
	dataSorter : function(a,b) {
		if(b.value<a.value){return -1;}
		if(b.value>a.value){return 1;}
		return 0;
	},
	
	render : function(){
		this.options.container = document.createElement("div");
		this.options.container.id = "Portfolio";
		document.body.appendChild(this.options.container);
		
		this.renderHeader();
		this.drawHeader("Previous Work");
		if(this.options.graphical){this.renderCoreTechnologiesGraphic();}
		else{this.renderCoreTechnologiesText();}
		this.drawHeader("Tools I use to get the job done");
		if(this.options.graphical){this.renderToolsGraphic();}
		else{this.renderToolsText();}
		this.renderSkillsPath();
		this.renderToolInfoBoxGraphic();
		this.drawHeader("Education & The Formative Years");
		this.renderEducationBoxes();
		this.drawHeader("What went into this site");
		this.renderSiteInformation();
		this.drawHeader("");
	},
	
	drawHeader : function(text){
		var el = document.createElement("div");
		el.className = "sectionheader";
		el.appendChild(document.createTextNode(text));
		this.options.container.appendChild(el);
	},
	
	renderHeader : function(){
		if(this.header){
			this.header.innerHTML = "";
		}
		else{
			this.header = document.createElement("div");
			this.header.className = "welcomesection";
			this.options.container.appendChild(this.header);
		}
		
		this.WelcomeHeader = new ColinBell.Welcome({
			welcomeHeader: this.options.welcomeHeader,
			welcomeText : this.options.welcomeText,
			allowGraphicSelect : this.options.allowGraphicSelect,
			parent: this,
			container: this.header
		});
	},
	
	renderToolsText : function(){
		if(this.toolsHolder){
			this.toolsHolder.innerHTML = "";
			this.toolsHolder.className = "toolsul";
		}
		else{
			this.toolsHolder = document.createElement("div");
			this.toolsHolder.className = "toolsul";
			this.toolsHolder.style.position = "relative";
			this.options.container.appendChild(this.toolsHolder);
		}
		
		//show core title
		var toolsHeader = document.createElement("div");
		toolsHeader.className = "title";
		toolsHeader.innerHTML = this.options.ToolsTitle;
		this.toolsHolder.appendChild(toolsHeader);
		
		new ColinBell.ToolsText({
			container: this.toolsHolder,
			data : this.options.ToolsData
		})
	},
		
	renderSkillsPath : function(){
		var el;
		if(this.skillsPath){
			el = this.skillsPath.options.container;
			el.innerHTML = "";
		}
		else{
			el = document.createElement("div");
			this.options.container.appendChild(el);
		}
		
		if(this.options.graphical){el.className = "skillspath";}
		else{el.className = "skillspathul";}
		
		if(!this.options.graphical){
			var label = document.createElement("div");
			label.className = "title";
			label.innerHTML = "Additional Skills";
			el.appendChild(label);
		}
		
		this.skillsPath = new ColinBell.SkillsPath({
			container : el,
			graphical : this.options.graphical,
			data : this.options.SkillsPaths
		});
	},
	
	renderToolInfoBoxGraphic : function(){
		//show tools info boxes
		if(this.toolInfoBoxes){
			this.toolInfoBoxes.innerHTML = "";
		}
		else{
			this.toolInfoBoxes = document.createElement("div");
			this.toolInfoBoxes.style.position = "relative";
			this.options.container.appendChild(this.toolInfoBoxes);
		}
				
		if(this.options.graphical){this.toolInfoBoxes.className = "infoboxes";}
		else{this.toolInfoBoxes.className = "infoboxesul";}
		
		if(!this.options.graphical){
			var label = document.createElement("div");
			label.className = "title";
			label.innerHTML = "Other";
			this.toolInfoBoxes.appendChild(label);
		}
		
		for(var i = 0; i < this.options.InfoBoxes.length ; i++){
			this.options.InfoBoxes[i].container = this.toolInfoBoxes;
			this.options.InfoBoxes[i].graphical = this.options.graphical;
			new ColinBell.InfoBox(this.options.InfoBoxes[i]);
		}
	},
	
	renderEducationBoxes : function(){
		if(this.educationBoxes){
			this.educationBoxes.innerHTML = "";
		}
		else{
			this.educationBoxes = document.createElement("div");
			this.educationBoxes.style.position = "relative";
			this.options.container.appendChild(this.educationBoxes);
		}
		
		if(this.options.graphical){this.educationBoxes.className = "educationboxes";}
		else{this.educationBoxes.className = "educationboxesul";}
		
		for(var i = 0; i < this.options.ValueBoxes.length ; i++){
			this.options.ValueBoxes[i].container = this.educationBoxes;
			this.options.ValueBoxes[i].graphical = this.options.graphical;
			
			if(i != this.options.ValueBoxes.length - 1){
				this.options.ValueBoxes[i].clazz = "border";
			}
			new ColinBell.ValueBox(this.options.ValueBoxes[i]);
		}
	},
	
	renderToolsGraphic : function(){
		if(this.toolsHolder){
			this.toolsHolder.innerHTML = "";
			this.toolsHolder.className = "tools";
		}
		else{
			this.toolsHolder = document.createElement("div");
			this.toolsHolder.className = "tools";
			this.toolsHolder.style.position = "relative";
			this.options.container.appendChild(this.toolsHolder);
		}
		
		//show tools title
		var toolsHeader = document.createElement("div");
		toolsHeader.className = "title";
		toolsHeader.innerHTML = this.options.ToolsTitle;
		this.toolsHolder.appendChild(toolsHeader);
		
		new ColinBell.ToolsGraph({
			container: this.toolsHolder,
			data : this.options.ToolsData
		})
	},
	
	renderCoreTechnologiesText : function(){
		if(this.coreTechHolder){
			this.coreTechHolder.innerHTML = "";
			this.coreTechHolder.className = "coretechnologiesul";
		}
		else{
			this.coreTechHolder = document.createElement("div");
			this.coreTechHolder.className = "coretechnologiesul";
			this.coreTechHolder.style.position = "relative";
			this.options.container.appendChild(this.coreTechHolder);
		}
		
		//show core title
		var coreTechHeader = document.createElement("div");
		coreTechHeader.className = "title";
		coreTechHeader.innerHTML = this.options.CoreTechnologiesTitle;
		this.coreTechHolder.appendChild(coreTechHeader);
		
		//show legend text
		var legendText = document.createElement("div");
		legendText.className = "legendtext";
		legendText.innerHTML = this.options.CoreTechnologiesText;
		this.coreTechHolder.appendChild(legendText);
		
		new ColinBell.CoreTechnicalText({
			data: this.options.CoreTechnologiesData,
			container: this.coreTechHolder
		})
	},
	
	renderCoreTechnologiesGraphic : function(){
		var radius = 200;
		var width = radius;
		var legendWidth = 300;
		
		if(this.coreTechHolder){
			this.coreTechHolder.innerHTML = "";
			this.coreTechHolder.className = "coretechnologies";
		}
		else{
			this.coreTechHolder = document.createElement("div");
			this.coreTechHolder.className = "coretechnologies";
			this.coreTechHolder.style.position = "relative";
			this.options.container.appendChild(this.coreTechHolder);
		}
		
		//show core title
		var coreTechHeader = document.createElement("div");
		coreTechHeader.className = "title";
		coreTechHeader.innerHTML = this.options.CoreTechnologiesTitle;
		this.coreTechHolder.appendChild(coreTechHeader);
		
		var legendHolder = document.createElement("div");
		legendHolder.className = "legend";
		this.coreTechHolder.appendChild(legendHolder);
		
		//show legend
		var legend = new ColinBell.Legend({
			data: this.options.CoreTechnologiesData,
			container: legendHolder,
			parent: this
		});
		
		//show legend hint
		var legendHint = document.createElement("div");
		legendHint.className = "hint";
		legendHint.innerHTML = "Hover to focus the infographic";
		this.coreTechHolder.appendChild(legendHint);
		
		//show legend text
		var legendText = document.createElement("div");
		legendText.className = "legendtext";
		legendText.innerHTML = this.options.CoreTechnologiesText;
		this.coreTechHolder.appendChild(legendText);
		
		var holder = document.createElement("div");
		holder.className = "radial";
		this.coreTechHolder.appendChild(holder);
		
		this.CoreTechnologiesInfoGraphic = new ColinBell.Radial({
			data: this.options.CoreTechnologiesData,
			container: holder,
			radius : radius,
			height: 10,
			width: 10,
			border: true,
			showLabel: true,
			showValue : true,
			showLine : true,
			color: "transparent",
			centerX : width + legendWidth,
			centerY : width + 50
		});
		
		var el = document.createElement("div");
		el.style.position = "absolute";
		el.style.width = width + "px";
		el.style.textAlign = "center";
		el.style.top = (width)+35 + "px";
		el.style.left = (width/2  +legendWidth) + "px";
		el.style.zIndex = 100;
		
		holder.appendChild(el);
		
		var elText = document.createElement("div");
		elText.className = "radialtext";
		elText.innerHTML = "Core Technologies and Expertise";
		el.appendChild(elText);
	},
	
	renderSiteInformation : function(){
		if(this.siteInformationBoxes){
			this.siteInformationBoxes.innerHTML = "";
		}
		else{
			this.siteInformationBoxes = document.createElement("div");
			this.siteInformationBoxes.style.position = "relative";
			this.options.container.appendChild(this.siteInformationBoxes);
		}
		
		if(this.options.graphical){
			this.siteInformationBoxes.className = "siteinformationboxes";
		}
		else{
			this.siteInformationBoxes.className = "siteinformationboxesul";
		}
		
		for(var i = 0; i < this.options.SiteInformation.length ; i++){
			this.options.SiteInformation[i].container = this.siteInformationBoxes;
			this.options.SiteInformation[i].graphical = this.options.graphical;
			
			if(this.options.graphical){
				this.options.SiteInformation[i].showTopText = false;
				this.options.SiteInformation[i].showBottomText = false;
			}
			
			new ColinBell.ValueBox(this.options.SiteInformation[i]);
			
			//add plus
			if(this.options.graphical){
				if(i != this.options.SiteInformation.length - 1){
					new ColinBell.ValueBox({
						"container" : this.siteInformationBoxes,
						"topText" : "", 
						"icon" : "./images/large_plus.png", 
						"bottomText" : "",
						"clazz" : "plus",
						"showTopText" : false, 
						"showBottomText" : false
					});
				}
			}
		}
	}
});
