/****************************************************
 File:     livephotosearch.js
 Author:   Dan Wright - http://danwright.info/contact
 Version:  1.0
 Date:     Nov 16 2008
 Requires: javascript.js, prototype.js
 ****************************************************/

var liveSearch = {};

liveSearch.maxPerRow = 6; // 6
liveSearch.maxRows = 4;  // 4

if (screen.availHeight < 100 + 100*liveSearch.maxRows)
	liveSearch.maxRows = Math.max(2,Math.round((screen.availHeight - 100)/100));
if (screen.availWidth < 100 + 100*liveSearch.maxPerRow)
	liveSearch.maxPerRow = Math.max(3,Math.round((screen.availWidth - 100)/100));
	
liveSearch.activeSearchRequest = null;
liveSearch.activeSearchText = '';
liveSearch.activeSearchURL = '';

liveSearch.startSearch = function(searchText)
{
	var words = searchText.replace(/\s+/, "/");
	var maxMatch = liveSearch.maxPerRow*liveSearch.maxRows;
	var url = "/php/livesearch.php/" + searchText.replace(/\s+/g, '/') + "/limit=" + maxMatch;
	liveSearch.activeSearchURL = url;
	var request = new Ajax.Request(url, {method:'get', 
										onComplete: function(request) { liveSearch.receiveResponse(request, url); }
										});
	assert(request != null, "could not create Ajax request");
	if (request) 
		{
		liveSearch.activeSearchRequest = request;
		liveSearch.activeSearchText = searchText;
		}
	return (request != null);	
}

liveSearch.receiveResponse = function(request, url)
{
	if (url != liveSearch.activeSearchURL)
		return;

	try {
		var docXML = request.responseXML;
		assert(docXML != null, "request.responseXML is undefined");
		var searchResults = docXML ? docXML.getElementsByTagName('searchResults') : null;
		assert(searchResults != null, "searchResults is missing");
		if (null == searchResults)
			{
			liveSearch.clearResults();
			return;
			}
		var moreMatchesElement = docXML.getElementsByTagName('moreMatches');
		var haveMoreMatches = (moreMatchesElement && moreMatchesElement.length > 0) ? parseInt((moreMatchesElement[0]).firstChild.data) : 0;
		var totalEl = docXML.getElementsByTagName('total')[0];
		assert(totalEl != null, "<total> element is missing");
		var total = !totalEl ? 0 : parseInt(totalEl.innerHTML || totalEl.innerText || totalEl.textContent || totalEl.text);
		var matches = docXML.getElementsByTagName('match');
		assert(total == 0 || matches != null, "no <match> elements found");
		assert(matches.length == total, "number of matches (" + matches.length +") doesn't match <total> (" + total + ")");
		
		var matchInfoArray = new Array();
		for (var i=0, length=matches.length; i < length; i++)
			{
			var match = matches[i];
			var matchInfo = {};
			for (var ichild = 0; ichild < match.childNodes.length; ichild++)
				{
				try {
				var child = match.childNodes[ichild];
				if (child.nodeType == 1 && child.firstChild && child.firstChild.data)
					matchInfo[child.tagName] = child.firstChild.data;
					}
				catch (e)
					{
					alert("exception: " + Debug.errorToString(e));
					}
				}
			matchInfoArray.push(matchInfo);
			}
		
		try {
			liveSearch.displayResults(matchInfoArray, haveMoreMatches);
			}
		catch (e)
			{
			alert("liveSearch exception: " + Debug.errorToString(e));
			}
		}
	catch (e)
		{
		alert("exception occurred handling XML: " + e);
		}
	
	liveSearch.activeSearchRequest = null;
	liveSearch.activeURL = '';
};

liveSearch.cancelSearch = function()
{
	if (liveSearch.activeSearchRequest)
		log("liveSearch.cancelSearch");
	liveSearch.activeSearchRequest = null;
};

liveSearch.clearResults = function()
{
	var div = $('searchResults');
	if (div != null)
		{
		div.innerHTML = '';
		div.style.visibility = 'hidden';
		}
};

liveSearch.handleMouseMove = function(event)
{
	event = Event.extend(event || window.event);
	if (liveSearch.dragElement != null)
		{
		var newLeft = liveSearch.dragStartLeft + event.clientX - liveSearch.dragStartMouseX;
		var newTop  = liveSearch.dragStartTop  + event.clientY - liveSearch.dragStartMouseY;
		liveSearch.dragElement.style.left = newLeft + "px";
		liveSearch.dragElement.style.top  = newTop  + "px";
		}
	return false;

};

liveSearch.handleMouseUpDown = function(event)
{
	event = Event.extend(event || window.event);
	if (event.button > 1) 
		return true;
	
	var element = event.element();
	while (element.parentNode && !element.hasClassName('searchResultsHeading'))
		element = element.parentNode;
	if (null == element.parentNode)
		return true;
	
	if (event.type === 'mousedown')
		{
		
		if (element.hasClassName('searchResultsHeading'))
			{
			log("liveSearch.handleMouseUpDown: have drag start!");
			liveSearch.dragElement = $('searchResults');
			liveSearch.dragStartLeft = parseInt(liveSearch.dragElement.getStyle('left'));
			if (isNaN(liveSearch.dragStartLeft))
				liveSearch.dragStartLeft = liveSearch.dragElement.cumulativeOffset().left;
			liveSearch.dragStartTop  = parseInt(liveSearch.dragElement.getStyle('top'));
			if (isNaN(liveSearch.dragStartTop))
				liveSearch.dragStartTop  = liveSearch.dragElement.cumulativeOffset().top;
			liveSearch.dragStartMouseX = event.clientX;
			liveSearch.dragStartMouseY = event.clientY;
			liveSearch.dragStartTime = new Date().getTime();
			event.element().style.cursor = 'move';
			Event.observe(document, 'mousemove', liveSearch.handleMouseMove);
			event.stop();
			}
		}
	else if (event.type === 'mouseup' && liveSearch.dragElement != null)
		{
		log("liveSearch.handleMouseUpDown: have drag end!");
		var now = new Date().getTime();
		var elapsed = now - liveSearch.dragStartTime;
		Event.stopObserving(document, 'mousemove', liveSearch.handleMouseMove);
		liveSearch.dragElement = null;
		element.style.cursor = 'pointer';
		}
	else if (event.type === 'dragstart')
		{
		event.stop();
		}
};

liveSearch.displayResults = function(matches, haveMoreMatches)
{
	var moreMatchesURL = !haveMoreMatches ? null : ("/galleries/photomatch.php/" + liveSearch.activeSearchText.replace(/\s+/g, '/'));
	var div = $('searchResults');
	liveSearch.buildResults(div, matches, moreMatchesURL);
	div.style.visibility = 'visible';
	$('closeSearchResults').observe('click', function (e) { liveSearch.clearResults(); });
	$$('div.searchResultsHeading').each( function (elem) {
		elem.observe('mousedown', liveSearch.handleMouseUpDown);
		elem.observe('mouseup',   liveSearch.handleMouseUpDown);
		elem.observe('dragstart', liveSearch.handleMouseUpDown);
		} );
	
	if (majik) majik.scanForMajikLoupes();
};

liveSearch.browserFailsToImplementFloatAndClearCorrectly = function()
{
	if (document.all && !window.opera)
		{
		var ieVersion = parseFloat(navigator.appVersion.split("MSIE")[1]);
		return (ieVersion < 8.0); // Bug seems to be fixed as of MSIE 8.0 beta 2 // 24-Nov-2008
		}
	return false;
};

liveSearch.buildResults = function(container, matches, moreMatchesURL)
{
	function wordBreak(str, lenMax)
	{
		if (str.length <= lenMax)
			return str;
		var idx = str.substr(0,lenMax-2).lastIndexOf(",", lenMax-2);
		if (idx == -1)
			idx = str.substr(0,lenMax-2).lastIndexOf(" ", lenMax-2);
		if (idx == -1) idx = str.lenMax-2;
		return str.substr(0,idx)+"...";
	};
	
	function setAttributes(element, attributes)
	{
		for (var attribute in attributes)
			{
			// Seemingly redundant, these do slightly different things in WebKit, so we do both
			element[attribute] = attributes[attribute];
			element.setAttribute(attribute, attributes[attribute]);
			}
	};

	function setStyle(element, style)
	{
		for (var styleItem in style)
			try { element.style[styleItem] = style[styleItem]; } catch (error) { }
	}

	function createElement(tag, attributes, style, children)
	{
		var element = document.createElement(tag);
		if (attributes) setAttributes(element, attributes);
		if (style) setStyle(element, style);
		if (children) $A(children).each(function (child) { element.appendChild(child); }); 
		return element;
	};

	
	container.innerHTML = ''; // nuke any previous contents
	if (0 == matches.length)
		{
		container.innerHTML = '<p class="searchMessage"><span id="closeSearchResults"><img src="/images/CloseButton.png" alt="" /></a> No matches found</p>';
		return;
		}
	var buggyBrowser = liveSearch.browserFailsToImplementFloatAndClearCorrectly();
	
	// Search results header
	var img = createElement('img', {src:'/images/CloseButton.png', alt:'', title:'close'});
	var closeButtonSpan = createElement('span', {id:'closeSearchResults'}, null, [img]);
	var header = createElement('div', {className:'searchResultsHeading'}, null, [closeButtonSpan, document.createTextNode(' Search results:')]);
	container.appendChild(header);
	
	// list(s) of results
	var ul = createElement('ul', {className: 'searchResults'});
	for (var i=0, length=matches.length; i < length; i++)
		{
		var match = matches[i];
		if (!match.thumb || !match.big) continue;
		if (!match.title) match.title = "";
		var folioRef = (match.gallery && match.image) ? '/portfolios/onephoto/?'+match.gallery+':'+match.image : '';
		var extra = "";
		var newRow = (i % liveSearch.maxPerRow) == 0;
		var clearBoth = newRow && !buggyBrowser;
		img = createElement('img', {src: match.thumb, alt: '', id: 'search-img-'+i, title: match.title});
		var br  = createElement('br');
		var caption = document.createTextNode(wordBreak(match.title,32));
		
		var a = createElement('a', {href: match.big, className: 'majik-loupe', id: 'search-a-'+i, altref: folioRef}, null, [img, br, caption]);
		var li = createElement('li', {id:'search-li-'+i}, clearBoth ? {clear: 'both'} : null, [a]);
		if (newRow && buggyBrowser)
			{
			container.appendChild(ul);
			ul = createElement('ul', {className: 'searchResults'});
			}
		ul.appendChild(li);
		}
	container.appendChild(ul);
	
	// footer (optional)
	if (moreMatchesURL != null)
		{
		a = createElement('a', {href: moreMatchesURL}, null, [document.createTextNode('View all search results...')]);
		var footer = createElement('div', {className: 'searchResultsHeading'}, {textAlign: 'right'}, [a]);
		container.appendChild(footer);
		}
	
};

