
// contact form ----------------------------------------------------------------------

function trim(string) {
	return string.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}

function isEmail(string) {
	if ( !string.match( /^([a-zA-Z0-9_'+*$%\^&!\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9:]{2,4})+$/ ) )
		return false;
	return true;
}

function textInputFocus(){
	if( this.value == this.defaultValue ) this.value = '';
}

function textInputBlur(){
	if( trim(this.value) == '' ) this.value = this.defaultValue;
}

// initialize form fields
function setupContactForm(){
	var contactForm = document.getElementById('contactFormContent');
	if( contactForm != null ){
		var input, i, textInputs = getElementsByClassName('textInput',contactForm);
		for( i=0; i<textInputs.length; i++ ){
			input = textInputs[i];
			input.defaultValue = input.value;
			input.onfocus = textInputFocus;
			input.onblur = textInputBlur;
		}
	}
}

// events ----------------------------------------------------------------------

function jumpOutOfFrame(){
	if (top.location != self.location) top.location.replace(self.location);
}

function toggleMap(){
	var map = document.getElementById('map');
	var mapIframe = document.getElementById('mapIframe');
	if( map.style.display != 'block' ){
		var activeSrc = mapIframe.activeSrc;
		if( activeSrc == null ) activeSrc = mapIframe.getAttribute('activeSrc');
		if( activeSrc == null ) return true;  // unable to retrieve custom attribute
		setOpacity(map,0);  map.style.display = 'block';
		map.onFadeInComplete = function(){ mapIframe.src = activeSrc; };
		fadeIn(map);
	} else {
		map.onFadeOutComplete = function(){ mapIframe.src = ''; };
		fadeOut(map);
	}
	return false;
}

function setupIntro(){
	document.write('<style type="text/css">');
	document.write('#content0 { display:none; }');
	if( !isOldIE ) document.write('div.fullImageContainer{ filter: inherit; }');  /* cancel IE7- filter fix */
	document.write('</style>');
}

function setupContent(){
	setupContactForm();
}

function onLoadBody(){
	// initialize
	if( ajaxEnabled ) hijaxLinks();
	setupSwapImg();
	setupContent();
	// define current location
	currentLocation = window.location + '';
	var token = currentLocation.indexOf('#');
	if( token > 0 ) currentLocation = currentLocation.substring(0,token);
	// initialize history management
	if( rshSupported ){
		dhtmlHistory.initialize();  dhtmlHistory.addListener(historyChange);
	} else if( isIE8 ){ window.onhashchange = ie8onHashChange; }
	// begin intro
	intro();
}

function intro(){
	//initialize
	var content0 = document.getElementById('content0');
	var menu = document.getElementById('menu');
	var content1 = document.getElementById('content1');
	var leftPanel = document.getElementById('leftPanel');
	var content4 = document.getElementById('content4');
	setOpacity(content0,0);  setOpacity(menu,0);
	content0.onFadeInComplete = function(){  fadeIn( menu );  };
	if( !leftPanel ){
		// not in portfolio
		setOpacity(content1,0);
		menu.onFadeInComplete = function(){  fadeIn( content1 );  };
		content1.onFadeInComplete = function(){  onFadeInComplete( content0 );  };
	} else {
		// in portfolio
		setOpacity(content1,1);  setOpacity(leftPanel,0);  setOpacity(content4,0);
		menu.onFadeInComplete = function(){ fadeIn( leftPanel ); };
		leftPanel.onFadeInComplete = function(){ fadeIn( content4 ); };
		content4.onFadeInComplete = function(){  onFadeInComplete( content0 );  };
	}
	// start sequence
	fadeIn( content0, 500 );
}

function onFadeInComplete(container) {
	var iFrames = getElementsByClassName('innerIframe', container);
	for (i = 0; i < iFrames.length; i++) {
		iFrames[i].src = iFrames[i].src;
	}
}

// ajax ----------------------------------------------------------------------

var ajaxEnabled = false;
var xmlHttp = null;
var loadingIcon;
var errorHtml;
var rshSupported = false;
var isIE8 = false;
var isOldIE = false;
var currentLocation;

function detectAjax(){
	if( (!document._error) && getXmlHttpObject() ){
		ajaxEnabled = true;
		loadingIcon = document._base + 'images/ajax.gif';
		errorHtml = '<div class="ajaxError">Page not found.</div>';
		MM_preloadImages(loadingIcon);
	}
}

function getLoadingNode(){
	var loadingNode = document.createElement('div');
	loadingNode.className = 'ajaxLoading';
	loadingNode.innerHTML = '<img src="'+loadingIcon+'" /><span class="ajaxLoadingText">&nbsp;...&nbsp;</span>';
	return loadingNode;
}

// transform normal links into ajax links
function hijaxLinks(){
	var anchors, i, container;
	if( arguments.length == 1 ) container = arguments[0];
	else container = document;
	anchors = getElementsByClassName('ajax[0-4]a?',container);
	for( i=0; i<anchors.length; i++ ){
		anchors[i].onclick = ajaxRequest;
	}
}

// onclick event handler
function ajaxRequest(){
	// no ajax, use standard link
	if( !ajaxEnabled ) return true;
	// cancel any ongoing request
	_ajaxAbort();
	// on error, use standard link
	xmlHttp = getXmlHttpObject();
	if( xmlHttp == null ) return true;
	if( !_ajaxSetParameters(this) ) return true;
	// add to history when completed successfully
	xmlHttp._addToHistory = true;
	// perform transitions and send request
	switch(xmlHttp._variant){
		case '0':	_ajaxRequest0();	break;
		case '1':	_ajaxRequest1();	break;
		case '1a':	_ajaxRequest0();	break;
		case '2':	_ajaxRequest2();	break;
		case '3':	_ajaxRequest3();	break;
		case '3a':	_ajaxRequest3a();	break;
		case '4':	_ajaxRequest4();	break;
	}
	return false;
}

function _ajaxRequest0(){
	_ajaxTransitionBegin('content1');  _ajaxSendRequest();
}

function _ajaxRequest1(){
	// menu transitions
	var i, items = document.getElementById('menu').getElementsByTagName('a');
	for( i=0; i<items.length; i++ ){
		items[i].className = items[i].className.replace('menuItemSelected','');
	}
	var caller = xmlHttp._caller;
	caller.className = caller.className + ' menuItemSelected';
	// send request
	_ajaxTransitionBegin('content1');  _ajaxSendRequest();
}

function _ajaxRequest2(){
	// menu transitions
	var items = new Array(
		document.getElementById('submenu1Item1'),
		document.getElementById('submenu1Item2'),
		document.getElementById('submenu1Item3')
	);
	var caller = xmlHttp._caller.parentNode;
	if( caller != items[0] ){
		items[0].className = '';  items[0].onmouseover = function(){ this.className = 'submenu1ItemRed'; };
		items[0].onmouseout = function(){ this.className = ''; };
	} else { items[0].className = 'submenu1ItemRed';  items[0].onmouseover = null;  items[0].onmouseout = null; }
	if( caller != items[1] ){
		items[1].className = '';  items[1].onmouseover = function(){ this.className = 'submenu1ItemRed'; };
		items[1].onmouseout = function(){ this.className = ''; };
	} else { items[1].className = 'submenu1ItemRed';  items[1].onmouseover = null;  items[1].onmouseout = null; }
	if( caller != items[2] ){
		items[2].className = '';  items[2].onmouseover = function(){ this.className = 'submenu1ItemYellow'; };
		items[2].onmouseout = function(){ this.className = ''; };
	} else { items[2].className = 'submenu1ItemYellow';  items[2].onmouseover = null;  items[2].onmouseout = null; }
	// show loading icons
	_ajaxTransitionBegin('content2','content4');
	// after loading content2, load full image
	xmlHttp._onLoadComplete = _loadFirstImage;
	// send request
	_ajaxSendRequest();
}

function _ajaxRequest3(){
	// menu transitions
	var i, items = new Array(
		document.getElementById('submenu2Item1'),
		document.getElementById('submenu2Item2'),
		document.getElementById('submenu2Item3')
	);
	for( i=0; i<items.length; i++ ){
		items[i].className = items[i].className.replace('menuItemSelected','');
	}
	var caller = xmlHttp._caller;
	caller.className = caller.className + ' menuItemSelected';
	// after loading content3, load full image
	xmlHttp._onLoadComplete = _loadFirstImage;
	window.setTimeout(
		function(){
			// show loading icons
			_ajaxTransitionBegin('content3','content4');
			// send request
			_ajaxSendRequest();
		}
		, 10);
}

function _ajaxRequest3a(){
	// show loading icons
	_ajaxTransitionBegin('content3','content4');
	// after loading content3, load full image
	xmlHttp._onLoadComplete = _loadFirstImage;
	// send request
	_ajaxSendRequest();
}

function _ajaxRequest4(){
	// menu transitions
	var i, items = document.getElementById('submenu3').getElementsByTagName('img');
	for( i=0; i<items.length; i++ ){
		items[i].className = '';
	}
	var caller = xmlHttp._caller.getElementsByTagName('img');
	caller[0].className = 'menuItemSelected';
	// send request
	_ajaxTransitionBegin('content4');  _ajaxSendRequest();
}

function _loadFirstImage(){
	try {
		var firstLink = document.getElementById('submenu3Item1').parentNode;
		xmlHttp = getXmlHttpObject();
		if( xmlHttp == null ) return;
		if( !_ajaxSetParameters(firstLink) ) return;
		_ajaxSendRequest();
	} catch(e){}
}

function _ajaxSendRequest(){
	xmlHttp.open("GET",xmlHttp._url,true);  xmlHttp.send(null);
}

// cancel any ongoing request
function _ajaxAbort(){
	var parent;
	if( (xmlHttp!=null) && (xmlHttp.readyState!=0) && (xmlHttp.readyState!=4) ){ try{ xmlHttp.abort(); }catch(e){} }
	if( (xmlHttp!=null) && (xmlHttp._syncPreloader!=null) ) xmlHttp._syncPreloader.cancel = true;
	var loadingNodes = getElementsByClassName('ajaxLoading');
	for( var i=0; i<loadingNodes.length; i++ ){
		parent = loadingNodes[i].parentNode;
		parent.removeChild(loadingNodes[i]);
	}
	xmlHttp = null;
}

function _ajaxStateChanged(){
	if( (xmlHttp.readyState==4) && (xmlHttp.status==200) ){
		// bad request
		if( xmlHttp.responseText == ' ' ){
			window.setTimeout(
				function(){ _ajaxAbort();  document.getElementById('content1').innerHTML = errorHtml; }
				, 10 );
			return;
		}
		// preload and show content
		xmlHttp._syncPreloader = new syncImagePreloader( xmlHttp.responseText );
		if( xmlHttp._syncPreloader.error ) _ajaxFinished();
		else {
			// start image preloader
			var label = getElementsByClassName( 'ajaxLoadingText', document.getElementById('content'+xmlHttp._section) )[0];
			xmlHttp._syncPreloader.loadingText = label;
			xmlHttp._syncPreloader.onError = _ajaxFinished;
			xmlHttp._syncPreloader.onLoadComplete = _ajaxFinished;
			xmlHttp._syncPreloader.startLoading();
		}
	}
}

function _ajaxFinished(){
	// add history event
	if( xmlHttp._addToHistory ){
		currentLocation = xmlHttp._caller.href;
		if( isIE8 ){ window.location.hash = 'permalink='+currentLocation; }
		if( rshSupported ){ dhtmlHistory.add( 'permalink='+currentLocation, null ); }
	}
	// track page view (google analytics)
	pageTracker._trackPageview(xmlHttp._pageView);
	// show content
	var container = document.getElementById('content'+xmlHttp._section);
	if( container == null ) return;
	fadeOut(container,0);  container.innerHTML = xmlHttp.responseText;
	// set up content behavior
	window.setTimeout(
		function(){
			setupSwapImg(container);  hijaxLinks(container);  setupContent();
			container.onFadeInComplete = function(){  onFadeInComplete( container );  };
			fadeIn(container);
			if( xmlHttp._onLoadComplete != null ) xmlHttp._onLoadComplete();
		}
		, 10
	);
}

// show loading icon in container(s)
function _ajaxTransitionBegin(){
	var containers = arguments;
	for( var i=0; i<containers.length; i++ ){
		document.getElementById(containers[i]).appendChild( getLoadingNode() );
		if( containers[i] == 'content4' ){  // center icon according to fullImage size
			var icon = getElementsByClassName( 'ajaxLoading', document.getElementById('content4') )[0];
			icon.style.left = (document.getElementById('fullImage').width/2) + 'px';
		}
	}
}

// set parameters of the xmlHttp object
function _ajaxSetParameters(elem){
	var variant, section, className, token1, token2, url;
	// define section ( 0-4 ) and variant ( 0-4, 1a )
	className = elem.className;
	token1 = className.indexOf('ajax')+4;
	token2 = className.indexOf(' ',token1);
	if( token2 < 0 ) variant = className.substring(token1);
	else variant = className.substring(token1,token2);
	section = variant.charAt(0);
	// append ajax parameters to the url
	url = 'ajax/' + section + elem.href.substring(document._base.length-1);
	// set parameters
	xmlHttp._caller = elem;
	xmlHttp._section = section;
	xmlHttp._variant = variant;
	xmlHttp._url = document._base + url;
	xmlHttp._pageView = '/' + url;
	xmlHttp.onreadystatechange = _ajaxStateChanged;
	xmlHttp._onLoadComplete = null;
	xmlHttp._syncPreloader = null;
	xmlHttp._addToHistory = false;
	return true;
}

function getXmlHttpObject(){
	var object = null;
	// Firefox, Opera 8.0+, Safari
	if( object == null ) { try{ object = new XMLHttpRequest(); } catch(e){} }
	// Internet Explorer
	if( object == null ) { try{ object = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e){} }
	if( object == null ) { try{ object = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e){} }
	return object;
}

// load an url fragment
function _loadFragment(fragment){
	// define the url to load
	if( fragment.indexOf('permalink='+document._base) < 0 ){
		// incomplete initial fragment, load main url
		fragment = window.location+'';
		var token = fragment.indexOf('#');
		if( token > 0 ) fragment = fragment.substring(0,token);
	} else fragment = fragment.replace('permalink=','').replace('#','');
	// check if fragment == currentLocation
	if( currentLocation.charAt(currentLocation.length-1) != '/' ) currentLocation += '/';
	if( fragment.charAt(fragment.length-1) != '/' ) fragment += '/';
	if( fragment == currentLocation ) return;
	// cancel any ongoing request
	_ajaxAbort();
	// update currentLocation
	currentLocation = fragment;
	// define a 'virtual link' that defines the request
	var link = new Object();  link.href = fragment;  link.className = 'ajax0';
	// set up and send request
	xmlHttp = getXmlHttpObject();
	if( xmlHttp == null ) return;
	if( !_ajaxSetParameters(link) ) return;
	_ajaxTransitionBegin('content1');  _ajaxSendRequest();
}

// history management ----------------------------------------------------------------------

function setupRSH(){
	if( ajaxEnabled ){
		// set user-agent flags
		var UA = navigator.userAgent.toLowerCase();
		var platform = navigator.platform.toLowerCase();
		var vendor = navigator.vendor || "";
		if( vendor === "KDE" ) rshSupported = false;  // konqueror
		else if( typeof window.opera !== "undefined" ) rshSupported = true;  // opera
		else if( typeof document.all !== "undefined" ){
			// IE
			var re = new RegExp("msie ([0-9]{1,}[\.0-9]{0,})");
			if( (re.exec(UA)!=null) && (parseFloat(RegExp.$1)>=8.0) ){ rshSupported = false;  isIE8 = true; }
			else{ rshSupported = true; isOldIE = true; }
		}
		else if( vendor.indexOf("Apple Computer, Inc.") > -1 ) rshSupported = (platform.indexOf("mac") > -1);  // safari
		else if( UA.indexOf("gecko") != -1 ) rshSupported = true;  // gecko-based
		// initialize rsh
		if( rshSupported ){
			window.dhtmlHistory.create({
				toJSON: function(o){
					return JSON.stringify(o);
				}
				, fromJSON: function(s) {
					return JSON.parse(s);
				}
			});
		}
	}
}

function historyChange(newLocation, historyData){
	_loadFragment(newLocation);
}

function ie8onHashChange(){
	_loadFragment(window.location.hash);
}

// preload images ----------------------------------------------------------------------

function MM_preloadImages() {
	var d = document, a = MM_preloadImages.arguments;
	if(d.images){
		if(!d.MM_p) d.MM_p=new Array();
		var i, j = d.MM_p.length;
		for(i=0; i<a.length; i++)
			if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i]; }
	}
}

// 'class' for synchronous image preloading ----------------------------------------------------------------------

function syncImagePreloader(html){
	var loader = this;
	loader.error = true;
	if( document.images ){
		loader.imagesSrc = _getImagesSrcFromHtml(html);
		if( loader.imagesSrc.length > 0 ) {
			loader.images = new Array();
			loader.loadedImages = 0;
			loader.loadingText = null;
			loader.startLoading = function(){ _startLoading(loader); };
			loader.onImageLoaded = function(){ _imageLoaded(loader); };
			loader.timeOut = function() { _timeOut(loader); };
			loader.timer = null;
			loader.onLoadComplete = null;
			loader.onError = null;
			loader.error = false;
			loader.cancel = false;
			loader.maxTime = 10000;
		}
	}
}

function _startLoading(loader){
	loader.timer = window.setTimeout( loader.timeOut, loader.maxTime );
	var i = loader.loadedImages, total = loader.imagesSrc.length, newImage;
	for (i = 0; i < total; i++) {
		newImage = new Image();
		loader.images[i] = newImage;
		newImage.onload = loader.onImageLoaded;
		if( loader.onError != null ){ newImage.onerror = loader.onError; }
		else{ newImage.onerror = newImage.onload; }
		newImage.src = loader.imagesSrc[i];
	}
}

function _imageLoaded(loader) {
	if( loader.cancel ) return;
	loader.loadedImages++;   window.clearTimeout(loader.timer);
	var i = loader.loadedImages, total = loader.imagesSrc.length;
	if( i < total ){
		if( loader.loadingText!=null ){
			loader.loadingText.innerHTML = '&nbsp;'+Math.floor(100*i/total)+'&nbsp;';
		}
		loader.timer = window.setTimeout( loader.timeOut, loader.maxTime );
	} else if( loader.onLoadComplete != null ){
		if( loader.loadingText != null ) loader.loadingText.innerHTML = '&nbsp;100&nbsp;';
		loader.onLoadComplete();
	}
}

function _timeOut(loader) {
	if( loader.cancel ) return;
	loader.cancel = true;
	if( loader.loadingText != null ) loader.loadingText.innerHTML = '';
	loader.onLoadComplete();
}

function _getImagesSrcFromHtml(html){
	var maxImages = 100;
	var src = new Array(), tokenImg, tokenSrc1, tokenSrc2, count = 0;
	tokenImg = html.indexOf('<img');
	while( (tokenImg>=0) && (count<maxImages) ){
		tokenSrc1 = html.indexOf(' src="',tokenImg);
		if( tokenSrc1 < 0 ) tokenImg = -1;
		else {
			tokenSrc1 += 6;
			tokenSrc2 = html.indexOf('"',tokenSrc1);
			if( tokenSrc2 < 0 ) tokenImg = -1;
			else {
				src[count] = html.substring(tokenSrc1,tokenSrc2);
				tokenImg = html.indexOf('<img',tokenSrc2);  count++;
			}
		}
	}
	return src;
}

// swap images ----------------------------------------------------------------------

function swapImage(img){
	if( img.imgOver != null ){
		var tmp = img.src;
		img.src = img.imgOver;
		img.imgOver = tmp;
	}
}

function setupSwapImg(){
	var i, img, container, canSwap;
	if( arguments.length == 1 ) container = arguments[0];
	else container = document;
	canSwap = getElementsByClassName('swapImg',container);
	for( i=0; i<canSwap.length; i++ ){
		img = canSwap[i];
		//get user-defined attributes
		if( img.imgOver == null ) img.imgOver = img.getAttribute('imgOver');
		//preload imgOver
		if( img.imgOver != null ){
			MM_preloadImages(img.imgOver);
			img.onmouseover = function(){ swapImage(this); };
			img.onmouseout = img.onmouseover;
		}
	}
}

// getElementsByClassName ----------------------------------------------------------------------

function getElementsByClassName(cl) {
	var retnode = [];
	var myclass = new RegExp('\\b'+cl+'\\b');
	var elem, container;
	if( arguments.length == 2 ) container = arguments[1];
	else container = document;
	elem = container.getElementsByTagName('*');
	for( var i=0; i<elem.length; i++ ){
		var classes = elem[i].className;
		if (myclass.test(classes)) retnode.push(elem[i]);
	}
	return retnode;
}

// fading ----------------------------------------------------------------------

function fadeOut(elem){
	if( elem != null ){
		var timeToFade = 200.0, timeStep = 50;
		if( arguments.length >= 2 ){
			timeToFade = arguments[1];
			if( timeToFade < 100 ){  setOpacity(elem,0);  elem.style.display = 'none';  return; }
		}
		if( arguments.length >= 3 ){
			timeStep = arguments[2];
			if( timeToFade < 50 ) timeStep = 50;
		}
		if( elem.interval != null ) window.clearInterval(elem.interval);
		elem.opacityStep = timeStep/timeToFade;
		elem.currentOpacity = getOpacity(elem);
		elem.interval = window.setInterval(
			function(){ _fadeOut(elem); }, timeStep
		);
	}
}

function _fadeOut(elem){
	if( elem.currentOpacity > elem.opacityStep ){
		elem.currentOpacity -= elem.opacityStep;
		setOpacity(elem,elem.currentOpacity);
	} else {
		elem.currentOpacity = 0;
		setOpacity(elem,0);
		window.clearInterval(elem.interval);
		if( elem.hideOnFadeOut !== false ) elem.style.display = 'none';
		if( elem.onFadeOutComplete != null ) elem.onFadeOutComplete();
	}
}

function fadeIn(elem){
	if( elem != null ){
		var timeToFade = 200.0, timeStep = 50;
		if( arguments.length >= 2 ){
			timeToFade = arguments[1];
			if( timeToFade < 100 ){ setOpacity(elem,1);  elem.style.display = 'block';  return; }
		}
		if( arguments.length >= 3 ){
			timeStep = arguments[2];
			if( timeToFade < 50 ) timeStep = 50;
		}
		elem.style.display = 'block';
		if( elem.interval != null ) window.clearInterval(elem.interval);
		elem.opacityStep = timeStep/timeToFade;
		elem.currentOpacity = getOpacity(elem);
		elem.interval = window.setInterval(
			function(){ _fadeIn(elem); }, timeStep
		);
	}
}

function _fadeIn(elem){
	if( elem.currentOpacity + elem.opacityStep < 1 ){
		elem.currentOpacity += elem.opacityStep;
		setOpacity(elem,elem.currentOpacity);
	} else {
		elem.currentOpacity = 1;  setOpacity(elem,1);
		if( (typeof document.all!=="undefined") && (typeof window.opera=="undefined") )
			elem.style.removeAttribute('filter');  //IE cleartype fix
		window.clearInterval(elem.interval);
		if( elem.onFadeInComplete != null ){ elem.onFadeInComplete(); }
	}
}

function setOpacity(elem,value){
	elem.style.filter = 'alpha(opacity = ' + (value*100) + ')';  //IE7
	elem.style.KHTMLOpacity = value;  //Safari (pre version 1.2), Konqueror
	elem.style.MozOpacity = value;  //Olders Mozilla and Firefox
	elem.style.opacity = value;  //CSS3
}

function getOpacity(elem){
	var opacity = 1;
	if( (elem.style.filter!=null) && (elem.style.filter.alpha!=null) && (elem.style.filter.alpha.opacity!=null) )
		opacity = parseFloat(elem.style.filter.alpha.opacity)/100;  //IE/Win
	if(elem.style.KHTMLOpacity != null)
		opacity = parseFloat(elem.style.KHTMLOpacity);  //Safari (pre version 1.2), Konqueror
	if(elem.style.MozOpacity != null)
		opacity = parseFloat(elem.style.MozOpacity);  //Olders Mozilla and Firefox
	if(elem.style.opacity != null)
		opacity = parseFloat(elem.style.opacity);  //CSS3
	if( isNaN(opacity) ) opacity = 1;
	return opacity;
}

