/*
  * Last review : 2007/1/22
  * by Guillaume Bodi (eHeadLine)
  * for MS4D
  */
var lastCheck;
var searchIndex = new Object();
var snippets = new Object();
var allProjects = new Array();
var allCategories = new Object();
var serializerType = null;
var preselection = null;
var images = new Object();
var initLoading = true;
var ss_STEPS = 30; 
var ss_INTERVAL;
var loadingFlag = false;
var currentPage = "";
var myLightbox;
var opened = true;

var isIE7 = (BrowserDetect.browser == 'Explorer' && BrowserDetect.version == "7");
var isNN = (navigator.userAgent.search("Netscape") != -1);

if (!isIE7 && !isNN)
{
	document.write("\n"+'<script type="text/javascript" src="http://www.ms4d.co.jp/showcase/js/dhtmlHistory.js"></script>'+"\n");
}

/*
  * Settings
  */

/*
  * CSS classes
  */
var enabledSearchOption = "searchOption";
var disabledSearchOption = "searchOption_Off";
var selectedSearchOption = "searchOption_Checked";
  
/*
  * Path to the loading animation file
  */
var host = "http://"+window.location.hostname+"/";

var blogDirectory = "showcase/";

//var loadingAnimFile = "http://www.ms4d.co.jp/showcase/images/static/loading.gif";
var loadingAnimFile = host + blogDirectory + "images/static/loading.gif";

/*
  * Path to the dynamically generated XML file containing the data for search
  */
//var searchDataFile = "http://www.ms4d.co.jp/showcase/searchData.xml";
var searchDataFile = host + blogDirectory + "searchData.xml";

/*
  * Path to the directory where the archive entries are built
  */
//var projectsPath = "http://www.ms4d.co.jp/showcase/";
var projectsPath = host + blogDirectory;

/*
  * Set to true if you wish to enable the functionality, to false to disable it.
  * It will disable the choices leading to empty results during the research but puts a heavier burden on the browser side. Sets intersections check is not a cheap operation.
  */
var disableEmptyChoices = true;

/*
  * End settings
  */

try
{
	serializerType = new XMLSerializer();
}
catch(ex)
{
	//ignore
}

function intersect(_array1, _array2)
{
	var intsct = new Array();
	var array1 = _array1.sort();
	var array2 = _array2.sort();
	var i = 0, j = 0;
  
	while (i < array1.length && j < array2.length)
	{
		if (array1[i] == array2[j])
		{
			intsct[intsct.length] = array1[i];
			i++;
			j++;
		}
		else if (array1[i] < array2[j])
		{
			i++;
		}
		else
		{
			j++;
		}
	}
	return intsct;
}

function isIntersectionVoid(_array1, _array2)
{
	var intsct = new Array();
	var array1 = _array1.sort();
	var array2 = _array2.sort();
	var i = 0, j = 0;
  
	while (i < array1.length && j < array2.length)
	{
		if (array1[i] == array2[j])
		{
			return false;
		}
		else if (array1[i] < array2[j])
		{
			i++;
		}
		else
		{
			j++;
		}
	}
	return true;
}

function getAjaxHandler()
{
	if (window.XMLHttpRequest) 
	{ // Mozilla, Safari, ...
		http_request = new XMLHttpRequest();
	} 
	else if (window.ActiveXObject) 
	{ // IE
		http_request = new ActiveXObject("Microsoft.XMLHTTP");
	}
	if (http_request.overrideMimeType) 
		http_request.overrideMimeType('text/xml');
	return http_request;
}

function loading(mode)
{
	document.getElementById('loadingAnim').style.display = (mode)?"block":"none";
}

function init()
{
        document.getElementById("mainForm").reset();
	var initialLocation = null;
	if (!isNN && !isIE7)
	{
		// initialize RSH
		dhtmlHistory.initialize();
	  
		// add ourselves as a listener for history
		// change events
		dhtmlHistory.addListener(loadProjectPage_real);
		initialLocation = dhtmlHistory.getCurrentLocation();
	}
	else
	{
		initialLocation = document.location.hash;
		var endIndex = (initialLocation.indexOf('?')> -1)?initialLocation.indexOf('?'):initialLocation.length;
		initialLocation = initialLocation.substring(1, endIndex);
		
	}
	 
	loadProjectPage_real(initialLocation, null);
	
	var loadingAnim = document.createElement('div');
	var loadingGif = document.createElement('img');
	loadingGif.setAttribute('src', loadingAnimFile);
	loadingAnim.appendChild(loadingGif);
	loadingAnim.appendChild(document.createTextNode("LOADING..."));
	loadingAnim.id = "loadingAnim";
	document.getElementById('searchBox').appendChild(loadingAnim);
	loading(true);
	loadSearchData();
}

function loadProjectPage(fragment) //function called by a click  IS NOT THE FUNCTION THAT DISPLAYS
{
	// historize the page
	//console.log("click method !");
	if (!isNN && !isIE7) 
		dhtmlHistory.add(fragment, null);
	loadProjectPage_real(fragment, null);
}

function loadProjectPage_real(fragment, ignore) //really starts the page display NOTE : the second parameter is always ignored
{
	//console.log (currentPage+ " - "+ fragment + " loading flag : "+ loadingFlag);
	if(myLightbox != null) {
		myLightbox.end();
	}
	//check the currently displayed content
	if (!loadingFlag && (currentPage == ""|| currentPage != fragment))
	{
		currentPage = fragment;
		loadingFlag = true;
		window.scrollTo(0, 0);
		if (document.getElementById('projectPageWrapper').display != "none" && !isNN && opened) {
			opened = false;
			//new Effect.BlindUp('projectPageWrapper', { duration: 0.8, queue:'front', afterFinish:function(){dataRetrieve(fragment);}});
                       var mySlide = new Fx.Height('projectPageWrapper', {duration:800, onComplete : function(){dataRetrieve(fragment);}});

		        mySlide.toggle();
                }
		else
			dataRetrieve(fragment);
	}
}

function dataRetrieve(fragment)
{
	if (fragment != null && fragment != "")
	{
		var endIndex = (fragment.indexOf('?')> -1)?fragment.indexOf('?'):fragment.length;
		fragment = fragment.substring(0, endIndex);
		
		var http_request = getAjaxHandler();
		http_request.onreadystatechange = function()
		{
			if (http_request.readyState == 4) 
			{
				if(http_request.status == 200)
				{
					displayProject(http_request.responseText);
				}
				else
				{
					alert("HTTP Error "+http_request.status);
				}
			}
		};
		var URL = projectsPath+fragment+".inc?rnd="+Math.random();
		http_request.open('GET', URL, true);
		http_request.setRequestHeader("Cache-Control", "no-cache"); 
		http_request.send("");
	}
	else
		loadingFlag = false;
}


function displayProject(HTMLcode)
{	
	document.getElementById('projectPage').innerHTML = HTMLcode;
	initLightbox();
	if (!isNN && !opened) {
		//new Effect.BlindDown('projectPageWrapper', {duration: 0.8, afterFinish:function(){loadingFlag = false;}});
                var mySlide = new Fx.Height('projectPageWrapper', {duration:800, onComplete:function(){loadingFlag = false;}});
		mySlide.toggle();
        }
	else
		loadingFlag = false;
	opened = true;
}

function selectCategory(category)
{
	loading(true);
	document.forms['mainForm'].reset();
	if (category != null)
	{
		document.getElementById(category).getElementsByTagName('input')[0].checked = true;
	}
	updateSearch();
	if (category != null)
	{
		smoothScrollTo(document.getElementById("searchBox"));
	}
}

function loadSearchData()
{
	var http_request = getAjaxHandler();
	http_request.onreadystatechange = function()
	{
		if (http_request.readyState == 4) 
		{
			if(http_request.status == 200)
			{
				processSearchData(http_request.responseXML);
			}
			else
			{
				alert("HTTP Error "+http_request.status);
			}
		}
	};
	http_request.open('GET', searchDataFile+"?rnd="+Math.random(), true);
	http_request.setRequestHeader("Cache-Control", "no-cache"); 
	http_request.send("");
}

function preloadImages(images)
{
	for (var n in images)
	{
		images[n].src = n;
	}
}

/*
 * Parses the search data gathered from the request and sets the index variables of the script.
 */
function processSearchData(xmlDataRoot)
{
	var categories = xmlDataRoot.getElementsByTagName('cat');
	searchIndex = new Object();
	var id, projects;
	for (var i = 0; i < categories.length; i++)
	{
		id = categories[i].getAttribute('cat_id');
		allCategories[id] = 1;
		var tmp = new Array();
		projects = categories[i].getElementsByTagName('project');
		for (var j = 0; j < projects.length; j++)
		{
			tmp[j] = projects[j].getAttribute('project_id');
		}
		searchIndex[id] = tmp;
		//activate the corresponding checkbox and div
		var checkBoxDiv = document.getElementById(id);
		checkBoxDiv.className = enabledSearchOption;
		checkBoxDiv.getElementsByTagName('input')[0].disabled = false;
	}
	var projectSnippets = xmlDataRoot.getElementsByTagName('snippet');

	for (var i = 0; i < projectSnippets.length; i++)
	{
		id = projectSnippets[i].getAttribute('project_id');
		allProjects[i] = id;
		var pics = projectSnippets[i].getElementsByTagName('img');
		for (var j = 0; j < pics.length; j++)
		{
			images[pics[j].getAttribute('src')] = new Image();
		}
		var tmp = serialize(projectSnippets[i]);
		snippets[id] = tmp;
	}
	var res = searchForResultSet(preselection);
	if (disableEmptyChoices)
		updateDisplay(null, res, searchForEmptyDerivedSearch(preselection, res));
	else
		updateDisplay(null, res, null);
}

function serialize(node)
{
	return (serializerType == null)?node.xml:serializerType.serializeToString(node);
}

function updateSearch()
{
	loading(true);
	/*
	First, gather all research criterias
	*/
	var form = document.getElementById('mainForm');
	var requestedCategories = new Array();
	var elements = form.getElementsByTagName('input');
	var j = 0;
	for (var i = 0; i < elements.length; i++) 
	{
		if (elements[i].checked)
			requestedCategories[j++] = elements[i].getAttribute("name");
	}

	var resultSet = searchForResultSet(requestedCategories);
	if (disableEmptyChoices)
		updateDisplay(requestedCategories, resultSet, searchForEmptyDerivedSearch(requestedCategories, resultSet));
	else
		updateDisplay(requestedCategories, resultSet, null);
}

/*
 * Updates the layout according to the read data and the current selection.
 * Sets the gray boxes for disabled choices. 
 */
function updateDisplay(cats, resultSet, emptyChoices)
{
	var resultsBox = document.getElementById('resultBox');
	var HTML = "";
	if (cats != null && cats.length != 0)
	{
		var reorderTool = new Object();
		for (var i = 0; i < resultSet.length; i++)
			reorderTool[resultSet[i]] = true;
		/*
		  * Update the result display
		  */
		if (resultSet != null && resultSet.length > 0)
		{
			for (var i = 0; i < allProjects.length; i++)
			{
				if (reorderTool[allProjects[i]] != null) 
					HTML += snippets[allProjects[i]];
			}
		}
		else
			HTML = "No results";
	}
	else
	{
		initLoading = false;
	}
	
	resultsBox.innerHTML = HTML;
	
	/*
	  * Repaint the styles for each search option
	  * Lock-unlock the checkboxes
	  */
	for (var n in allCategories)
	{
		var searchOption = document.getElementById(n);
		var checkBox = searchOption.getElementsByTagName('input')[0];
		searchOption.className = (checkBox.checked)?selectedSearchOption:enabledSearchOption;
		if (emptyChoices != null)
		{
			if (emptyChoices[n])
				searchOption.className = disabledSearchOption;
			checkBox.disabled=emptyChoices[n];
		}
	}
	loading(false);
}

function searchForEmptyDerivedSearch(categories, resultSet)
{
	var emptyResults = new Object();
	var hashTable = new Object();
	for (var n in allCategories)
	{
		emptyResults[n] = false;
		hashTable[n] = 1;
	}
	if (categories != null)
	{
		for (var i = 0; i < categories.length; i++)
			hashTable[categories[i]] = null;
	}
	var counter = 0;
	for (var cat in hashTable)
	{
		if (isIntersectionVoid(resultSet, searchIndex[cat]))
			emptyResults[cat] = true;
	}
	return emptyResults;
}

function searchForResultSet(categories)
{
	var result = allProjects.slice(0);
	if (categories == null || categories.length == 0) return result;
	for (var i = 0; i < categories.length; i++)
	{
		var registeredItems = searchIndex[categories[i]];
		if (registeredItems != null)
		{
			result = intersect(result, registeredItems);
		}
		else
		{
			// Should not happen since this item should be disabled, but covers the case...
			return null;
		}
	}
	return result;
}

function smoothScrollTo(element)
{	
	// Stop any current scrolling
	clearInterval(ss_INTERVAL);
	var desty = locate(element)[1];
	var cypos = getCurrentYPos();
	 
	var stepsize = parseInt((desty-cypos)/ss_STEPS);
	ss_INTERVAL = setInterval('scrollWindow('+stepsize+','+desty+')',10); 
}

function scrollWindow(scramount, dest) {
	var wascypos = getCurrentYPos();
	var isAbove = (wascypos < dest);
	window.scrollTo(0, wascypos + scramount);
	var iscypos = getCurrentYPos();
	var isAboveNow = (iscypos < dest);
	if ((isAbove != isAboveNow) || (wascypos == iscypos)) 
	{
		// cancel the repeating timer
		clearInterval(ss_INTERVAL);
	}
} 

/*
function smoothScrollTo(element)
{	
	// Stop any current scrolling
	clearInterval(ss_INTERVAL);
	var desty = locate(element)[1];
	var cypos = getCurrentYPos();
	//return if the jump is less than a half screen height from the current position
	if (Math.abs(desty-cypos) - (screen.availHeight / 4) < 0)
		return;
	var delta = desty-cypos;
	
	var factor = 1;
	if (delta < 0)
		factor = -1;
	delta = Math.abs(delta)-parseInt(screen.availHeight/4); 
	
	var steps = new Array(ss_STEPS);
	var cruiseSpeed = parseInt(3*delta/(2*ss_STEPS));
	var accelSteps = parseInt(ss_STEPS/3);
	var accelSpeedIncrements = parseInt(cruiseSpeed / accelSteps);
	var currentSpeed = 0;
	var report ="delta : "+ delta+ " accelSteps : "+ accelSteps+ "from "+cypos+" to "+(cypos+factor*delta)+ "accelSpd : "+accelSpeedIncrements+" cruise spd : "+cruiseSpeed+"\n";
	for (var i=0; i< ss_STEPS; i++)
	{
		if (i < accelSteps) // acceleration phase
		{
			currentSpeed += accelSpeedIncrements;
		}
		else if	(i >= 2*accelSteps) // deceleration phase
		{
			currentSpeed -= accelSpeedIncrements;
		}
		else // cruise speed phase
		{
			currentSpeed = cruiseSpeed;
		}
		cypos = getCurrentYPos() + factor * currentSpeed;
		report += factor*currentSpeed+" : "+cypos+"\n";
		window.scrollTo(0, cypos);
		pause(10);
	}
	alert(report);
}

function scrollWindow(scramount, dest) {
	var wascypos = getCurrentYPos();
	var isAbove = (wascypos < dest);
	window.scrollTo(0, wascypos + scramount);
	var iscypos = getCurrentYPos();
	var isAboveNow = (iscypos < dest);
	if ((isAbove != isAboveNow) || (wascypos == iscypos)) 
	{
		// cancel the repeating timer
		clearInterval(ss_INTERVAL);
	}
}*/

function getCurrentYPos() 
{
	if (document.body && document.body.scrollTop)
		return document.body.scrollTop;
	if (document.documentElement && document.documentElement.scrollTop)
		return document.documentElement.scrollTop;
	if (window.pageYOffset)
		return window.pageYOffset;
	return 0;
}

function locate(element)
{
	var x = element.offsetLeft;  
	var y = element.offsetTop;
	var thisNode = element;
	while (thisNode.offsetParent && (thisNode.offsetParent != document.body)) 
	{
		thisNode = thisNode.offsetParent;
		x += thisNode.offsetLeft;
		y += thisNode.offsetTop;
	}
	var result = new Array(x, y);
	return result;
}
