// iWall v1.0.2 //
// -----------------------------
// v1.0.0 ~ greg original
// v1.0.1 ~ merwan revisions
 
// declare globals
var Q       = [];          // queue containing Persons
var globalz = new Object;  // global vars

// Configuration Options
globalz.totalRecords  = 0;
globalz.totalResults  = null;
globalz.searchTerm    = trim(document.getElementById('searchBox').value);
globalz.searchAction  = document.getElementById('s').value;
globalz.language      = document.getElementById('language').value;
globalz.missing       = document.getElementById('checkMissing'  ).checked;
globalz.alive         = document.getElementById('checkAliveWell').checked;
globalz.injured       = document.getElementById('checkInjured'  ).checked;
globalz.deceased      = document.getElementById('checkDeceased' ).checked;
globalz.unknown       = document.getElementById('checkUnknown'  ).checked;
globalz.baseUrl       = 'http://hepl.nlm.nih.gov/';
globalz.inwUrl        = globalz.baseUrl+'inw/';
globalz.baseImageUrl  = globalz.baseUrl+'index.php?stream=image&mod=mpr&act=addmp_img&thumbnail=true'; // sahana
globalz.phpPage       = 'iWall.php';
globalz.refreshRate   = 30; // in milliseconds
globalz.dX            = 1;  // # of pixels images are transposed per reDraw()
globalz.rowPadding    = 18; // # of pixels padding each row
globalz.imagePadding  = 18; // # of pixels padding between images on the same row
globalz.imageBorder   = 4;  // size of the image border in pixels
globalz.headerHeight  = 138; // pixels in height of the header
globalz.footerHeight  = 53;  // pixels in height of the footer
globalz.enableConsole = false;
globalz.nextRow       = 0;
globalz.initDone      = 0;
globalz.uuidSkipList  = []; // uuid's to always skip (sahana uuid)
globalz.uuidSkipList.push("1"); // root
globalz.uuidSkipList.push("2"); // su
globalz.doneHelpMessage = false;

globalz.maxRows = 3;


// used to simulate array functions
Array.prototype.remove = function(from, to) {
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

// called when user starts the application
function start() {
	var doc = document;  //local reference
	globalz.initDone = 1; 
 
	// add an event to monitor when the search box gains focus
	var box = doc.getElementById('searchBox');
	box.onfocus = function() {
		box.value = '';
		box.style.color = '#000000';
	}

	// init variables
	Q[0] = []; // 0-1 hours
	Q[1] = []; // 1-24 hours
	Q[2] = []; // 24+ hours
	globalz.scroll    = [];
	globalz.scroll[0] = false;
	globalz.scroll[1] = false;
	globalz.scroll[2] = false;
	globalz.on = true; // app running
	doc.getElementById('buttonPlay').style.opacity = 0.3;
	doc.getElementById('buttonPlay').style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=30)';

	// the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
	if (typeof window.innerWidth != 'undefined') {
		globalz.docWidth = window.innerWidth,
		globalz.docHeight = window.innerHeight
	}
	// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
	else if (typeof doc.documentElement != 'undefined' && typeof doc.documentElement.clientWidth != 'undefined' && doc.documentElement.clientWidth != 0) {
		globalz.docWidth = doc.documentElement.clientWidth,
		globalz.docHeight = doc.documentElement.clientHeight
	}
	// older versions of IE
	else {
		globalz.docWidth = doc.getElementsByTagName('body')[0].clientWidth,
		globalz.docHeight = doc.getElementsByTagName('body')[0].clientHeight
	}

	var loadingX = doc.getElementById('loadingX');
	loadingX.style.left = Math.round(globalz.docWidth/2)-150+'px';
	loadingX.style.top  = Math.round(globalz.docHeight/2)-10+'px';

	var matchString = doc.getElementById('sDefaultSearch').value;

	// alert user to small screen size
	if ((globalz.docWidth < 1020) && (globalz.searchTerm == matchString)) { // IE uses 4 pixels of the screen for window border
		alert('This application is designed for screen resolutions of 1024x768 or higher.\nSince your resolution is lower, you may experience problems viewing it.');
	}
	
	if (globalz.docHeight < 600)
		globalz.maxRows = 2;
	
	globalz.imageHeight = Math.floor((globalz.docHeight - globalz.headerHeight - globalz.footerHeight - (2*(globalz.rowPadding+globalz.imageBorder))) / globalz.maxRows);
	if (globalz.searchAction == 'true') {
		doc.getElementById('haitiMemorial').style.display='none';
		startThread();
		globalz.reDrawIntervalId = setInterval(reDraw, globalz.refreshRate);
	}
	totalXhr.open('POST', totalXhrUrl, true);
	totalXhr.onreadystatechange = handleTotalResponse;
	totalXhr.send(null);
}



function reDraw() {
	var row, i;
	for (row = 0; row <= globalz.maxRows; row++) {
		// only draw images that appear on the <body> !! we used to check if they finished loading ~~ && Q[row][i].image.complete ~~ not anymore
		for ( i = 0; Q[row] && i < Q[row].length; i++ ) {  //this is a hack because reDraw() is very eager; was throwing thousands of uncaught exceptions on failed/precompleted search
			if ((Q[row][i].image != null) && (Q[row][i].x + Q[row][i].imageWidth) >= 0) {
				//document.getElementById(Q[row][i].id).style.left = Q[row][i].x;
				document.getElementById('row'+row+'picture'+i).style.left = Math.round(Q[row][i].x)+'px';
			}

			// only increment x coordinates if we are scrolling the row
			if (globalz.scroll[row]) {
				Q[row][i].x = Q[row][i].x + globalz.dX;
				if (Q[row][i].x > globalz.docWidth) {
					Q[row][i].x = findNewX(row,Q[row][i].imageWidth);
				}
			}
		}
	}
}



function findNewX(row, imageWidth) {
	var min, i;
	var min = 999999;

	for (i = 0; i < Q[row].length; i++) {
		if (Q[row][i].x < min) {
			min = Q[row][i].x;
		}
	}
	if (min == 999999) {
		min = globalz.docWidth - imageWidth - (globalz.imageBorder*6);
		// min = (globalz.docWidth/2) - (imageWidth/2);
	} else {
		min = min - globalz.imagePadding - imageWidth;
	}

	// if row is full, begin scrolling it
	if (!globalz.scroll[row] && min < 0) {
		globalz.scroll[row] = true;
	}
	return min;
}



function addPersonToQ(person) {
	var newWidth, newHeight, locationString, topOverlayString, triangleString;
	var skip  = false;
	
	var writeOnDiv = false;

	// check if we are excluding this particular person from being displayed
	for (var s = 0; s < globalz.uuidSkipList.length; s++) {
		if (globalz.uuidSkipList[s] == person.uuid) {
			skip = true;
		}
	}

	// queue the person
	if (!skip) {
		// check for null names
		if ((person.name == null) || (person.name == "")) {
			person.name = "unknown";
		}

		// check for missing status ~ no tagColor assigned
		if (person.tagColor == null) {
			triangleString = "";
		} else {
			triangleString = ""; //&triangle="+person.tagColor;
		}

		//var displayName = substr(person.name, 0, 32);
		if (strpos(person.uuid, 'PFp') != 1) {
			person.infoline = document.getElementById('sDetailsName').value;
		} else {
			person.infoline = 'Infoline';
		}

		// check for null images
		if (person.imageUrl == null || person.imageUrl == '' || person.imageHeight == 0) {
			writeOnDiv = true;
			person.imageWidth  = globalz.imageHeight;
			person.imageHeight = globalz.imageHeight;
			person.image = new Image();
			if (person.age != null) {
				if (person.age > 17) {
					if (person.gender != null) {
						if (person.gender == 'mal') {
							// man
							person.image.src=globalz.inwUrl+'s2man.png';
						} else if (person.gender == 'fml') {
							// woman
							person.image.src=globalz.inwUrl+'s3woman.png';
						} else {
							// unknown
							person.image.src=globalz.inwUrl+'s4unknown.png';
						}
					} else  {
						// unknown
						person.image.src=globalz.inwUrl+'s4unknown.png';
					}
				} else {
					if (person.gender != null) {
						if (person.gender == 'mal') {
							// boy
							person.image.src=globalz.inwUrl+'s0boy.png';
						} else if (person.gender == 'fml') {
							// girl
							person.image.src=globalz.inwUrl+'s1girl.png';
						} else {
							// unknown
							person.image.src=globalz.inwUrl+'s4unknown.png';
						}
					} else {
						// unknown
						person.image.src=globalz.inwUrl+'s4unknown.png';
					}
				}
			} else {
				// unknown
				person.image.src=globalz.inwUrl+'s4unknown.png';
			}
/*
			if (person.row == 2) {
				person.image.src=globalz.baseImageUrl+"&x_uuid=s2man&height="+person.imageHeight+"&overlay_bottom="+displayName+triangleString;
			} else if (person.row == 1) {
				person.image.src=globalz.baseImageUrl+"&x_uuid=s3woman&height="+person.imageHeight+"&overlay_bottom="+displayName+triangleString;
			} else if (person.gender == "mal") {
				person.image.src=globalz.baseImageUrl+"&x_uuid=s0boy&height="+person.imageHeight+"&overlay_bottom="+displayName+triangleString;
			} else {
				person.image.src=globalz.baseImageUrl+"&x_uuid=s1girl&height="+person.imageHeight+"&overlay_bottom="+displayName+triangleString;
			}
			
			
			
*/
		} else {
			// calculate new image dimensions
			newHeight = globalz.imageHeight;
			newWidth  = newHeight/person.imageHeight*person.imageWidth;
			person.imageWidth  = newWidth;
			person.imageHeight = newHeight;
			person.image = new Image();
			person.image.src = person.imageUrl; //=globalz.baseImageUrl+"&x_uuid="+person.uuid+"&height="+person.imageHeight+"&overlay_bottom="+displayName+triangleString;
		}

		// figure out what the initial (x,y) coordinates are for the new person
		person.x = Math.round(findNewX(person.row, person.imageWidth));
		person.y = Math.floor(globalz.headerHeight + (person.row * globalz.imageHeight) + (person.row * globalz.rowPadding));
		person.opacity = 0.0;
		
		personListOld[person.uuid] = person;  //save newest changes to use in details pane.
		
		var newDiv            = document.createElement('div');
		newDiv.id             = 'row'+person.row+'picture'+Q[person.row].length;
		newDiv.className      = 'picture';
		newDiv.style.backgroundColor = '#'+person.tagColor;
		newDiv.style.position = 'absolute';
		newDiv.style.left     = person.x+'px';
		newDiv.style.top      = person.y+'px';
		newDiv.style.width    = (person.imageWidth+(2*globalz.imageBorder))+'px';
		newDiv.style.height   = (person.imageHeight+(2*globalz.imageBorder))+'px';
		
		if (!writeOnDiv)
			newDiv.innerHTML      = '<img onclick="showDetail(personListOld[\''+person.uuid+'\'])" id="row'+person.row+'picture'+Q[person.row].length+'i" style="height: '+person.imageHeight+'px; width: '+person.imageWidth+'px;" src="'+person.image.src+'" onMouseOver="info('+person.row+', '+Q[person.row].length+')" onMouseOut="unfade('+person.row+', '+Q[person.row].length+')">';
		else
			newDiv = pictureDetails(newDiv, person);

		var b = document.getElementById('b');
		b.appendChild(newDiv);
		Q[person.row].push(person);
		globalz.nextRow++;
		if (globalz.nextRow == globalz.maxRows) {
			globalz.nextRow = 0;
		}
/*
		// up count
		globalz.numDisplayed++;
		document.getElementById('numDisplayed').innerHTML = globalz.numDisplayed;
*/
		//updateCount();
	}
//	globalz.numPeople++;
//	document.getElementById('numPeople').innerHTML = globalz.numPeople;
}



function info(row, pos) {
	var place1 = document.getElementById('infoLine1');
	var c, cc, l, ll, s, ss, moar;
	var l = Q[row][pos].location;
	if (l == null || l == '' || l == 'null' || l == 'NULL') {
		l = '';
	} else {
		l = ' &nbsp; <b>'+document.getElementById('sDetailsLocation').value+'</b>: '+l;
	}
	ss = '<span class="statusSahanaFull '+Q[row][pos].tagClass+'">'+Q[row][pos].statusSahanaFull+'</span>'+l;

	place1.innerHTML = '<b>'+Q[row][pos].infoline+'</b>: '+Q[row][pos].name+' &nbsp; <b>'+document.getElementById('sDetailsStatus').value+'</b>: '+ss;

	var place2 = document.getElementById('infoLine2');
	var c = Q[row][pos].comments;
	if (c == null || c == '') {
		cc = '';
	} else {
		cc = ''; // &nbsp; <b>'+document.getElementById('sDetailsComments').value+'</b>: '+c;
	}
 	place2.innerHTML = '<b>'+document.getElementById('sDetailsWhen').value+'</b>: '+Q[row][pos].statusSahanaUpdated+' &nbsp; <b>ID</b>: '+Q[row][pos].uuid+cc;

	var place3 = document.getElementById('row'+row+'picture'+pos+'i') || document.getElementById('row'+row+'picture'+pos+'_details');
	place3.style.opacity = '0.75';
	place3.style.filter = 'alpha(opacity=75)';
}



function unfade(row, pos) {
	var place3 = document.getElementById('row'+row+'picture'+pos+'i') || document.getElementById('row'+row+'picture'+pos+'_details');
	place3.style.opacity = '1.0';
	place3.style.filter = 'alpha(opacity=100)';
}



function removePersonFromQ(uuid) {
	for (var row = 0; row <= 2; row++ ) {
		for (var i = 0; i < Q[row].length; i++) {
			if ( Q[row][i].uuid == uuid) {
				Q[row].remove(i);
				return;
			}
		}
	}
}



function zlog(msg) {
	if (globalz.enableConsole) {
		console.log(msg);
	}
}



function pause() {
	if (globalz.on) {
		clearInterval(globalz.reDrawIntervalId);
		globalz.on = false;
		document.getElementById('buttonPause').style.opacity = 0.3;
		document.getElementById('buttonPlay').style.opacity = 1.0;

		document.getElementById('buttonPause').style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=30)';
		document.getElementById('buttonPlay').style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=100)';
	}
}



function play() {
	if (!globalz.on) {
		globalz.reDrawIntervalId = setInterval(reDraw, globalz.refreshRate);
		globalz.on = true;
		document.getElementById('buttonPause').style.opacity = 1.0;
		document.getElementById('buttonPlay').style.opacity = 0.3;

		document.getElementById('buttonPause').style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=100)';
		document.getElementById('buttonPlay').style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity=30)';
	}
}



function searchSubset() {
	globalz.searchTerm = trim(document.getElementById('searchBox').value);

	var matchString = document.getElementById('sDefaultSearch').value;
	if (globalz.searchTerm == matchString || globalz.searchTerm.length < 2) {
		window.location.href = globalz.inwUrl+globalz.phpPage+'?l='+globalz.language
	} else {
		globalz.language = document.getElementById('language').value;
		globalz.missing  = document.getElementById('checkMissing'  ).checked;
		globalz.alive    = document.getElementById('checkAliveWell').checked;
		globalz.injured  = document.getElementById('checkInjured'  ).checked;
		globalz.deceased = document.getElementById('checkDeceased' ).checked;
		globalz.unknown  = document.getElementById('checkUnknown'  ).checked;
		
		window.location.href = globalz.inwUrl + globalz.phpPage + 
		                       '?l=' + globalz.language + 
		                       '&n=' + globalz.searchTerm + 
		                       '&m=' + globalz.missing + 
		                       '&a=' + globalz.alive + 
		                       '&i=' + globalz.injured + 
		                       '&d=' + globalz.deceased + 
		                       '&u=' + globalz.unknown + 
		                       '&s=true';
	}
}



function clearSubset() {
	window.location.href = globalz.inwUrl+globalz.phpPage+'?l='+globalz.language;
}



function matchTerm(s) {
	// checks if s matches the current searchTerm
	// returns true if the searchTerm is in s
	// false otherwise
	return strpos(strtolower(s), strtolower(globalz.searchTerm), 0)
}



function strtolower (str) {
	// http://kevin.vanzonneveld.net
	// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   improved by: Onno Marsman
	// *     example 1: strtolower('Kevin van Zonneveld');
	// *     returns 1: 'kevin van zonneveld'
	return (str+'').toLowerCase();
}



function strpos (haystack, needle, offset) {
	// http://kevin.vanzonneveld.net
	// +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
	// +   improved by: Onno Marsman
	// +   bugfixed by: Daniel Esteban
	// *     example 1: strpos('Kevin van Zonneveld', 'e', 5);
	// *     returns 1: 14
	var i = (haystack+'').indexOf(needle, (offset ? offset : 0));
	return i === -1 ? false : i;
}



function substr (str, start, len) {
    // Returns part of a string
    //
    // version: 909.322
    // discuss at: http://phpjs.org/functions/substr
    // +     original by: Martijn Wieringa
    // +     bugfixed by: T.Wild
    // +      tweaked by: Onno Marsman
    // +      revised by: Theriault
    // *       example 1: substr('abcdef', 0, -1);
    // *       returns 1: 'abcde'
    // *       example 2: substr(2, 0, -6);
    // *       returns 2: false

// Add: (?) Use unicode.semantics and/or unicode.runtime_encoding (e.g., with string wrapped in "binary" or "Binary" class) to
// allow access of binary (see file_get_contents()) by: charCodeAt(x) & 0xFF (see https://developer.mozilla.org/En/Using_XMLHttpRequest )
// Fix: Handle 4-byte characters

    str += '';
    var end = str.length;
    if (start < 0) {
        start += end;
    }
    end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
    // PHP returns false if start does not fall within the string.
    // PHP returns false if the calculated end comes before the calculated start.
    // PHP returns an empty string if start and end are the same.
    // Otherwise, PHP returns the portion of the string from start to end.
    return start >= str.length || start < 0 || start > end ? !1 : str.slice(start, end);
}



function trim (str, charlist) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +   improved by: mdsjack (http://www.mdsjack.bo.it)
    // +   improved by: Alexander Ermolaev (http://snippets.dzone.com/user/AlexanderErmolaev)
    // +      input by: Erkekjetter
    // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: DxGx
    // +   improved by: Steven Levithan (http://blog.stevenlevithan.com)
    // +    tweaked by: Jack
    // +   bugfixed by: Onno Marsman
    // *     example 1: trim('    Kevin van Zonneveld    ');
    // *     returns 1: 'Kevin van Zonneveld'
    // *     example 2: trim('Hello World', 'Hdle');
    // *     returns 2: 'o Wor'
    // *     example 3: trim(16, 1);
    // *     returns 3: 6

    var whitespace, l = 0, i = 0;
    str += '';

    if (!charlist) {
        // default list
        whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
    } else {
        // preg_quote custom list
        charlist += '';
        whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
    }

    l = str.length;
    for (i = 0; i < l; i++) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(i);
            break;
        }
    }

    l = str.length;
    for (i = l - 1; i >= 0; i--) {
        if (whitespace.indexOf(str.charAt(i)) === -1) {
            str = str.substring(0, i + 1);
            break;
        }
    }

    return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
}




// CROSS BROWSER ARRAY SIZE CHECK!
Object.size = function(obj) {
	var size = 0, key;
	for (key in obj) {
		if (obj.hasOwnProperty(key)) size++;
	}
	return size;
};
// Get the size of an object
//var size = Object.size(myArray);



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////thread///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




// keep a list of persons in the system and passes on person data


var listInterval   = 30000;
var dataInterval   = 3000;
var listIntervalId;
var dataIntervalId;
var listXhr        = new XMLHttpRequest();
var dataXhr        = new XMLHttpRequest();
var totalXhr       = new XMLHttpRequest();
var listXhrUrl     = 'nuSoapClient.php?call=shn_mpr_get_uuids_matching_search4&uuid='+globalz.searchTerm+'GGGdelimiterKKK'+globalz.missing+'GGGdelimiterKKK'+globalz.alive+'GGGdelimiterKKK'+globalz.injured+'GGGdelimiterKKK'+globalz.deceased+'GGGdelimiterKKK'+globalz.unknown;
var dataXhrUrl     = 'nuSoapClient.php?call=shn_mpr_get_person_data2&uuid=';
var totalXhrUrl    = 'nuSoapClient.php?call=shn_mpr_total_records2';
var person, z, zz;
var personListOld = []; // old list of persons for comparison
var personList = []; // list of people we WILL download information for



function startThread() {
	if (globalz.searchTerm != '' && globalz.searchTerm != null) {
		document.getElementById('loadingX').style.visibility = 'visible';
		getUuidList();
		listIntervalId = setInterval(getUuidList, listInterval);
	}
}



function handleTotalResponse() {
	var total = 0;
	if (totalXhr.readyState == 4) {
		if (totalXhr.responseText == "") {
			return;
		}
		temp = eval('('+totalXhr.responseText+')');
		globalz.totalRecords = temp[0].count;
		updateCount();
	}
}



function updateCount() {
	var m = '';
	var r = '';
	//globalz.totalResults = Q[0].length + Q[1].length + Q[2].length;
	var dm = document.getElementById('sDetailsMouse').value;

	// show message when we get a result, but before they have moused over anything
	if (!globalz.doneHelpMessage && (globalz.totalResults > 0)) {
		document.getElementById('infoLine1').innerHTML = '<span style="color: red;">'+dm+'</span>';
		globalz.doneHelpMessage = true;
	}
/*
	if (globalz.totalResults != 1) {
		m = 'matches';
	} else {
		m = 'match';
	}
*/
	m = document.getElementById('sMatchesFrom').value;
	r = document.getElementById('sTotalRecords').value;

	if (globalz.searchAction != 'true' || !globalz.totalResults) {
		document.getElementById('count').innerHTML = '<b>'+globalz.totalRecords+'</b> '+r;
	} else {
		document.getElementById('count').innerHTML = '<b>'+ globalz.totalResults +'</b> '+m+' <b>'+globalz.totalRecords+'</b> '+r;
	}
}



function update() {
	if (globalz.initDone != 0) {
		var count = 0;
		for (var person in personList) 
			if (personList[person].hasOwnProperty('uuid')) {
				count++;
				getPersonData(personList[person]);
				if ( count > 100 ) {
					setTimeout(update, 3000) // wait 3 seconds! this is for IE/FF3.0- not to lose their patience on big sets.
					break;
				}
			}
	}

	document.getElementById('loadingX').style.visibility = 'hidden';
	//zlog(Object.size(personList));
}

function getPersonData(person) {
	var temp, bdate1, bdate2, today, age;
	var total = 0;

	//zlog("xhr status("+xhr.status+") statusText("+xhr.statusText+") responseText("+xhr.responseText+") responseXML("+xhr.responseXML+")");
 
	if (isNaN(person.imageHeight)) {
		person.imageHeight = 0;
	}

	// TAG COLORS /////////////////////////////////////////////////////////////////////////////////

	// set the html tag color for the person
	person.tagClass = null;
	if (person.statusSahana == 'mis') {
		person.tagColor         = '00f';
		person.tagClass         = 'statusMissing';
		person.statusSahanaFull = 'missing';

	} else if (person.statusSahana == 'ali') {
		person.tagColor         = '0f0';
		person.tagClass         = 'statusAlive';
		person.statusSahanaFull = 'alive and well';

	} else if (person.statusSahana == 'inj') {
		person.tagColor         = 'f00';
		person.tagClass         = 'statusInjured';
		person.statusSahanaFull = 'injured';

	} else if (person.statusSahana == 'dec') {
		person.tagColor         = '000';
		person.tagClass         = 'statusDeceased';
		person.statusSahanaFull = 'deceased';

	} else if (person.statusSahana == 'fnd') {
		person.tagColor         = '802A2A';
		person.tagClass         = 'statusFound';
		person.statusSahanaFull = 'found';
    } else {
		person.tagColor         = '777';
		person.tagClass         = 'statusUnknown';
		person.statusSahanaFull = 'unknown';
	}

	// incremental row assignments
	person.row = globalz.nextRow;

  addPersonToQ(person);

  delete personList[person.uuid];
  
	if (Object.size(personList) == 0) {
		globalz.initDone = 0;
	}
} 



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////
//////  thread2
//////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



function getUuidList() {
	listXhr.open('POST', listXhrUrl, true);
	listXhr.onreadystatechange = handleUuidListResponse;
	listXhr.send(null);
}



function handleUuidListResponse() {
	var i, j, alreadyInList, notInList, statusIsSame, p, pp, ppp, pppp;
	var z = new Object;
	var personListNew = [];
	var temp = [], freshUuids = [];

	if ( listXhr.readyState == 4 ) {
		temp = eval( '('+listXhr.responseText+')' );
		personList = [];
		if ( temp && temp.length > 0 ) {
			globalz.totalResults = temp.length;
			for ( i = 0; i < globalz.totalResults; i++ ) {
				p = new Person();
				p.init( temp[i] );
				//if status is changed, delete from personListOld and Q so it gets readded.
				if (personListOld[p.uuid] && (personListOld[p.uuid].statusSahana !== p.statusSahana || personListOld[p.uuid].statusTriage !== p.statusTriage)) {
					removePersonFromQ(personListOld[j].uuid);
					delete personListOld[p.uuid];
				}
				if ( !personListOld[p.uuid] ) { 
					personList[p.uuid] = personListOld[p.uuid] = p;
				}
				freshUuids.push( p.uuid );
			}
			// CHECK FOR UUIDs TO REMOVE
			var fuLength = freshUuids.length;
			for ( i = 0; i < fuLength; i++ ) {
				if ( !personListOld[freshUuids[i]] ) {
					delete personListOld[ freshUuids[ i ] ];
					removePersonFromQ( freshUuids[ i ] );
				}
			}
			if ( Object.size( personList ) === 0 ) {
				globalz.initDone = 0;
			}
			updateCount();
			update();
		} else {
			pause();
			var snmf = document.getElementById( 'sNoMatchesFound' ).value;
			document.getElementById('loadingX').style.visibility = 'hidden';
			document.getElementById( 'infoLine1' ).innerHTML = '<span style="color: red; font-weight: bold;">'+snmf+'</span>';
			globalz.initDone = 0;
		} 
		
		
	}
}

function showDetail(person) { 

	var doc = document;

	//pause the scroll
	pause();
	doc.getElementById("glass").style.visibility = "visible";
	var detailsDiv = doc.getElementById("detailsPane");

	detailsDiv.style.left = Math.round(globalz.docWidth/2)-400+'px';
	detailsDiv.style.top  = Math.round(globalz.docHeight/2)-250+'px';
	detailsDiv.style.visibility = 'visible';
	
	doc.getElementById("dt_uuid").innerHTML = person.uuid;
	doc.getElementById("dt_fullName").innerHTML = person.name || "N/A";
	doc.getElementById("dt_age").innerHTML = person.yearsOld || "N/A";
	doc.getElementById("dt_gender").innerHTML = person.gender || "N/A";
	doc.getElementById("dt_status").innerHTML = person.statusSahanaFull || "N/A";
	doc.getElementById("dt_statusSahanaUpdated").innerHTML = person.statusSahanaUpdated || "N/A";
	doc.getElementById("dt_location").innerHTML = person.location || "N/A";
	doc.getElementById("dt_comments").innerHTML = person.comments;
	
	doc.getElementById("dt_image").innerHTML = '<img style="position:relative;max-height:300px;max-width:300px" src="'+person.image.src+'">';
}

function closeDetail() {
	var doc = document;

	//pause the scroll
	play();
	doc.getElementById("glass").style.visibility = "hidden";
	var detailsDiv = doc.getElementById("detailsPane");

	detailsDiv.style.left = Math.round(globalz.docWidth/2)-400+'px';
	detailsDiv.style.top  = Math.round(globalz.docHeight/2)-250+'px';
	detailsDiv.style.visibility = 'hidden';	
}

function printDetail() {
	window.open("details.php?uuid=" + document.getElementById("dt_uuid").innerHTML);
}


/* takes a div, returns a div w/ details embedded in it 
	imageDiv.id             = 'row'+person.row+'picture'+Q[person.row].length;
*/
function pictureDetails(imageDiv, person) {
	var doc = document,
		newLayer = doc.createElement("div");
		
	newLayer.id = imageDiv.id + "_details";
	newLayer.className = "picDetails";
	newLayer.style.height = (person.imageHeight - 12) + "px";
	newLayer.onclick=function() { showDetail(personListOld[person.uuid]) };
	
		
    // newLayer.innerHTML += "<label class='picDetailLabels' >Name</label><br/><div>" + person.name + "</div><br />"
					// +  "<span class='statusSahanaFull " + person.tagClass + "' style='margin-left: 10px;color:#" + person.tagColor + ";'>" + person.statusSahanaFull + "</span><br /><br />"
					// +  "<label class='picDetailLabels' >Reported</label><br/><div>" + person.statusSahanaUpdated + "</div></br><br />"
					// +  "<label class='picDetailLabels' >Id</label><br/><div><input style='width:100%' type='text' value='" + person.uuid + "' /></div><br />";

	newLayer.innerHTML += "<div>" + person.name + "</div><br />"
					+  "<span class='statusSahanaFull " + person.tagClass + "' style='margin-left: 10px;color:#" + person.tagColor + ";'>" + person.statusSahanaFull + "</span><br /><br />"
					+  "<div>" + person.statusSahanaUpdated + "</div></br><br />"
					+  "<div><input style='width:100%' type='text' value='" + person.uuid + "' /></div><br />";					
					
	var row = person.row,
	    pos = Q[person.row].length;
					
	newLayer.onmouseover=function() { info(row, pos) };
	newLayer.onmouseout = function () { unfade(row, pos) };
	
	/**		
		<div id="detailInfo" style="text-align:left;float:left;margin-top:5px;margin-left:20px; width:400px; position:relative; border: solid 0px #CCC;">
			<label for="dt_uuid">ID</label>
			<div id="dt_uuid" style="font-weight:normal;"></div>
			<label for="dt_fullName">Name</label>
			<div id="dt_fullName" style="font-weight:normal;"></div>
			<label for="dt_age">Age</label>
			<div id="dt_age" style="font-weight:normal;"></div>
			<label for="dt_gender">Gender </label>
			<div id="dt_gender" style="font-weight:normal;"></div>
			<label for="dt_status">Status </label>
			<div id="dt_status" style="font-weight:normal;"></div>
			<label for="dt_statusSahanaUpdated">When Reported</label>
			<div id="dt_statusSahanaUpdated" style="font-weight:normal;"></div>
			<label for="dt_location">Last Known Location</label>
			<div id="dt_location" style="font-weight:normal;"></div>
			<label for="dt_comments">Comments</label>
			<div id="dt_comments" style="font-weight:normal;"><pre>disabled</pre></div>
		</div>
	*/
	
	imageDiv.appendChild(newLayer);
	
	return imageDiv;
	
}



//
// Person Class
//
function Person() {
  
	// Returns a new instance of Person which is a deep-copy of this.
    	//this.clone = function(toClone) {
    	//return (new Person()).init(toClone.args);
    	//};

	// Basically takes the json-derived associative-array and inits fields.
	// Also inits other useful fields.
	this.init =  function(args) {
		this.uuid         = args["p_uuid"]; 
		this.statusSahana = args["opt_status"]; 
		this.name         = args["full_name"]; 
		this.gender       = args["gender"]; 
		this.yearsOld     = args["years_old"]; 
		this.age          = args["age"]; 
		this.statusSahanaUpdated = args["statusSahanaUpdated"]; 
		this.statusTriage = args["statusTriage"]; 
		this.id           = args["id"]; 
		this.peds         = args["peds"]; 
		this.location     = args["last_seen"]; 
		this.comments     = args["comments"]; 
		this.updated      = args["updated"]; 
		this.image        = null;
		this.imageUrl     = args["imageUrl"]; 
		this.imageHeight  = parseInt(args["imageHeight"]); 
		this.imageWidth   = parseInt(args["imageWidth"]); 
		this.imageShow    = true;
		this.x            = -999999;
		this.y            = -999999;
		this.wipe         = false; 
      		// store args for later use? easier cloning? kinda useless now.
		//this.args = args;
	};
}
  
