// <!--
/**
directory.js

Copyright 2005 Pyramis Studios, Inc. / http://www.pyramis-studios.com

Author: 		Andrew Mace
Created: 		20050329
Last Modified:	20050802
Description: 	Javascript-mediated directory/personnel listing interface.  It dynamically loads xml files per-user created by personnel.cgi and person.cgi.
Requirements:	xhr.js
				content source (xml files)

LEGAL NOTICE:
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY KIND EITHER EXPRESS OR IMPLIED. TO THE FULLEST EXTENT POSSIBLE PURSUANT TO THE APPLICABLE LAW, PYRAMIS STUDIOS, INC. DISCLAIMS ALL WARRANTIES, EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT OR OTHER VIOLATION OF RIGHTS. 

LIMITATION OF LIABILITY
UNDER NO CIRCUMSTANCES, INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE, SHALL PYRAMIS STUDIOS, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA OR PROFIT, ARISING OUT OF THE USE, OR THE INABILITY TO USE, THE MATERIALS IN THIS FILE, EVEN IF PYRAMIS STUDIOS, INC. OR A PYRAMIS STUDIOS AUTHORIZED REPRESENTATIVE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IF YOUR USE OF MATERIALS FROM THIS FILE RESULTS IN THE NEED FOR SERVICING, REPAIR OR CORRECTION OF EQUIPMENT OR DATA, YOU ASSUME ANY COSTS THEREOF. SOME PROVINCES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES OR THE EXCLUSION OF LIABILITY IN CERTAIN CIRCUMSTANCES, SO THE ABOVE LIMITATION OR EXCLUSION MAY NOT APPLY TO YOU.

THIS FILE MAY NOT BE USED IN ANY OTHER WAY THAN ITS EXPRESS PURPOSE. REDISTRIBUTION OF THIS FILE OR THE CREATION OF DERIVATIVE WORKS IS NOT PERMITTED.

COPYRIGHT 2005 PYRAMIS STUDIOS, INC. ALL RIGHTS ARE RESERVED.

MODIFYING OR REMOVING THE CONTENTS OF THIS FILE BEFORE THIS LINE IS NOT PERMITTED.
**/


// column ordering/headers
var cols = {
				name:			0,
				title:			1,
				department: 	2,
				phone:			3,
				email:			4
			};

// the initial sort
var last_sort_cat = 'name';
var last_sort_dir = 1;
var xml_src = "/personnel/xml/";
var stock_img_directory = "/img/stock/";
var img_directory = "/img/personnel/";
var arrow_off_src = stock_img_directory + "shim.gif";
var arrow_up_src = stock_img_directory + "arrow_up.gif";
var arrow_down_src = stock_img_directory + "arrow_down.gif";
var default_img_src = stock_img_directory + "dir_missing.gif";

var view_state = {};

var is_safari = (navigator.userAgent.toLowerCase().indexOf('safari') >= 0);

function xhr_error_custom(r)
{
// update the status of the request
	// determine the id
	var url = xhr_url(r);
	if(url == null) return(false);
	var id = url.substring(xml_src.length, url.indexOf('.xml'));
	var x = document.getElementById('x' + id);
	x.firstChild.innerHTML = 'Error'; // update the table row to relate status
	return(true); // bypass normal error reporting
}

function xhr_process_custom(r)
{
// called on xmlHttpRequest response
// <entry affiliation="faculty" address="Mark's campus address" cn="Mark" id="3" name="S. Mark Williams" sn="Williams" email="williams@pyramis-studios.com" phone="919 KL5-7890" title="Adjunct Professor" title2=""/>
	var x = r.responseXML.lastChild;
	var id = 'p' + x.getAttribute('id');
	var el = document.getElementById('x' + id);
	if(el && el.firstChild) {
		// build the html fragment (string) according to the received xml
		var name = decodeURIComponent(x.getAttribute('name'));
		var dept = x.getAttribute('department');
		var aff = x.getAttribute('affiliation');
		var addr = x.getAttribute('address');
		var email = x.getAttribute('email');
		var phone = x.getAttribute('phone');
		var title = decodeURIComponent(x.getAttribute('title'));
		var title2 = x.getAttribute('title2');
		var pic = x.getAttribute('img');
		var url = x.getAttribute('url');
		var bio = x.getAttribute('bio');
		if(bio && bio.length) bio = decodeURIComponent(bio);
		else bio = '';
		if(pic == null || !pic.length) {
			pic = default_img_src;
		} else {
			pic = img_directory + pic + '.gif';
		}		
		var s = '<div class="dir_img"><img src="' + pic + '" alt=""></div>';

		if(bio.length) {
			s += '<div style="padding: 0px; float: right; width: 355px; margin: 5px; margin-left: 0px;">' + bio + '</div>';
		}

		s += '<div class="dir_copy" style="width: 250px; border-right: 1px solid #e0e0e0; padding-left: 10px;"><a href="javascript:do_expand(\'' + id + '\')">' + name + '</a><br />';
		s += title + '<br />';
		if(title2 != null && title2.length) s += decodeURIComponent(title2) + '<br />';
		if(dept != null && dept.length) s += dept + '<br />';
		if(email != null && email.length) s += '<a href="mailto:' + email + '">' + email + '</a><br />';
		if(phone != null && phone.length) s += phone + '<br />';
		if(addr != null && addr.length) s += decodeURIComponent(addr) + '<br />';
		if(url != null && url.length) {
			s += '<div class="dir_url">';
			if(url.toLowerCase().indexOf('http') < 0) url = '/download/' + url;
			s += '<a href="' + url + '" target="_blank">More information</a></div>';
		}
		s += '</div>';
		
		if(bio.length) {
			s += '<br style="clear: right;" />';
		}
		
		el.firstChild.innerHTML = s;
	}
	return(true); // return true to bypass normal reply processing
}

function do_expand(id)
{ 
// toggle less/more info view modes
// id = id of TR node; if expanded, hide
	var n = document.getElementById(id);
	var x = document.getElementById('x' + id);
	if(n == null || x == null) return;
	if(find_innerText(x).length < 6) { // firstChild is td
		x.firstChild.innerHTML = 'Loading&#8230;'; // update the table row to relate status
		xhr_serial = false; // allow parallel requests
		xhr_info_id = null; // bypass status message
		xhr_load(xml_src + id.slice(1) + '.xml', 'GET', '');
	}
	var d = n.style.display;
	n.style.display = x.style.display;
	x.style.display = d;
	view_state['_' + id] = (d.toLowerCase() == "none") ? '' : 'x';
}

function restyle()
{
// update the styling
	var e = document.getElementById('dir_entries_h').parentNode;
	var i = 0;
	var n;
	for(var el = 0; el < e.childNodes.length; el++) {
		n = e.childNodes[el];
		if(n.nodeName.toLowerCase() == 'tr' && n.getAttribute('id').charAt(0) != 'x' && n.getAttribute('id') != "dir_entries_h") {
			if(n.style.display != 'none' || n.nextSibling.style.display != 'none') {
				e.childNodes[el].nextSibling.className = e.childNodes[el].className = "dir_tr" + (i % 2);
				i++;
			}
		}
	}
}

// sorting functionality 
function sort_func(a, b)
{ // actually return reversed vals
	var lhs = find_text(a);
	var rhs = find_text(b);
	if(lhs < rhs) {
		return(-1);
	} else if(lhs > rhs) {
		return(1);
	}
	return(0);
}
function lastname(s)
{
	var n = s.indexOf(',');
	if(n < 0) n = s.length;
	var n2 = s.lastIndexOf(' ', n);
	return(s.substring(n2, n) + ' ' + s.substr(0, n2));
}
function sort_byname(a, b)
{ // actually return reversed vals
 // get the last name
	var lhs = lastname(find_text(a));
	var rhs = lastname(find_text(b));
	if(lhs < rhs) {
		return(-1);
	} else if(lhs > rhs) {
		return(1);
	}
	return(0);
}
function do_sort(cat)
{
	var e = document.getElementById('dir_entries_h').parentNode;
	var s = new Array();
	for(var el = 0; el < e.childNodes.length; el++) {
		if(e.childNodes[el].nodeName.toLowerCase() == 'tr' && e.childNodes[el].getAttribute('id').charAt(0) != 'x' && e.childNodes[el].getAttribute('id') != "dir_entries_h") {
			s.push(e.childNodes[el].childNodes[cols[cat]]);			
		}
	}
	s = (cat == 'name') ? s.sort(sort_byname) : s.sort(sort_func);
	if(last_sort_cat == cat && last_sort_dir == 1) {
		s = s.reverse();
		last_sort_dir *= -1;
	} else {
		last_sort_dir = 1;
	}
	// -- update column styles
	var c;
	if(last_sort_cat != cat) {
		c = document.getElementById(last_sort_cat + '_h');
		if(c != null) {
			c.className = c.className.substr(0, c.className.lastIndexOf('_'));
			c.lastChild.src = arrow_off_src;
		}
		c = document.getElementById(cat + '_h');
		if(c != null) {
			c.className = c.className + '_on';
		}
	}
	c = document.getElementById(cat + '_h');
	if(c != null) {
		c.firstChild.blur();
		c.lastChild.src = (last_sort_dir == 1) ? arrow_up_src : arrow_down_src;	
	}
	// -- end column style updates
	
	last_sort_cat = cat;
	var n;
	for(var i = 0; i < s.length; i++) {
		if(s[i].parentNode != null) {
			n = s[i].parentNode.nextSibling;
			e.appendChild(s[i].parentNode);
			e.appendChild(n);
		}
	}
	restyle();
}

// searching functionality
function do_search()
{ // get the query from the text field
	var q = document.forms[0].q.value.toLowerCase().split(' ');
	// hide those entries that don't match
	var e = document.getElementById('dir_entries_h').parentNode;
	var s;
	for(var el = 0; el < e.childNodes.length; el++) {
		if(e.childNodes[el].nodeName.toLowerCase() == 'tr' && e.childNodes[el].getAttribute('id').charAt(0) != 'x' && e.childNodes[el].getAttribute('id') != "dir_entries_h") {
			var t1 = find_innerText(e.childNodes[el]).toLowerCase();
			var t2 = find_innerText(e.childNodes[el + 1]).toLowerCase();
			for(var i = 0; i < q.length; i++) {
				if(t1.indexOf(q[i]) < 0 && t2.indexOf(q[i]) < 0) {
					e.childNodes[el + 1].style.display = e.childNodes[el].style.display = "none";
					break;
				}
				if(i == q.length - 1) {
					s = view_state['_' + e.childNodes[el].getAttribute('id')];
					if(s == "x") {
						e.childNodes[el].style.display = "none";
						e.childNodes[el + 1].style.display = "";
					} else {
						e.childNodes[el].style.display = "";
						e.childNodes[el + 1].style.display = "none";
					}
				}
			}
		}
	}
	restyle();
	return(false);
}
function find_text(n)
{
	var t = n;
	if(t.nodeType != 3 && t.hasChildNodes()) {
		var s = '';
		for(var i = 0; i < t.childNodes.length; i++) {
			s += find_text(t.childNodes[i]);
		}
		return(s);
	} else {
		return(t.nodeType == 3 ? t.nodeValue : '');
	}
}
function find_innerText(n)
{
	if(is_safari) {
		if(n.nodeType == 3 && n.innerHTML != null) return(n.innerHTML);
	} else {
		if(n.innerText != null) return(n.innerText);	
	}
	var s = '';
	for(var i = 0; i < n.childNodes.length; i++) {
		s += find_text(n.childNodes[i]);
	}
	return(s);
}



// -->