/* XfaMiLy historian 2.0 - copyright patrick brennan 2003 */

/* This section declares the global variables used */

var a, b, c, d, e, f, g, h, i, j, k, m, n, o, x, w
var buffer, bdate, ddate
var newWin
var xml_doc
var node_list
var pindex, findex, mindex, spindex
var posbox, negbox, nullbox
var cindex = new Array()
var child = new Array()
var TreeArray = new Array()
var TreeArray_2 = new Array()
var BinTree = new Array()

var update = new Date(document.lastModified)
var theMonth = update.getMonth() + 1
var theDate = update.getDate()
var theYear = update.getFullYear()
document.writeln("<span style='position:absolute; left:10px; top:35px; font-size:8pt; font-family:verdana, helvetica, arial, sans-serif; color:navy'>last updated<br\/>" + theDate + "/" + theMonth + "/" + theYear + "</span>")

document.write("<div align='center'><span class='main'>powered by </span><span class='navy'>X</span><span class='red'>fa</span><span class='navy'>M</span><span class='red'>i</span><span class='navy'>L</span><span class='red'>y&nbsp;Historian<span style='font-size:10pt'><sup>&#174;</sup></span></span><br><br></div>")

document.write("<p class='main'>Choose an individual from the select box below to display a form containing their genealogical information and links to their parents' and children's records. The form also provides the facility to display their descendants in a folding-tree format</p>")

/* This function creates a person object with 15 key attributes*/

function person(index, id, fullname, birthdate, deathdate, marriagedate, father, mother, spouse, notes, gender){
this.index = index
this.id = id
this.fullname = fullname
this.dob = birthdate
this.dod = deathdate
this.dom = marriagedate
this.father = father
this.mother = mother
this.spouse = spouse
this.notes = notes
this.gender = gender
this.parent = "unknown"
this.children = 0
this.level = ""
this.dates = ""
}


/* This function loads the genealogical file */

function openFile(){
//file = "wedtree.xml"
var moz = (typeof document.implementation != 'undefined') && (typeof document.implementation.createDocument != 'undefined');
var ie  = (typeof window.ActiveXObject != 'undefined')
if (moz) {
xml_doc = document.implementation.createDocument("", "", null)
xml_doc.onload = readFileMoz
}
else if (ie) {
xml_doc = new ActiveXObject("Microsoft.XMLDOM")
xml_doc.onreadystatechange = function() {
if (xml_doc.readyState == 4) setTimeout(readFileIE,0)
}
}
xml_doc.load(file)
displayMenu()
}

/* This function walks the document tree to extract node information. Because Mozilla and IE handle whitespace nodes differently there needs to be two separate functions. */

/* Note: - a duplicate array is created - the contents of this one are modified whenever a family tree is displayed  */

function readFileMoz(){
node_list = xml_doc.getElementsByTagName("person")
for (i = 0; i <= node_list.length-1; i++){
b = node_list[i].attributes[0].nodeValue
c = node_list[i].childNodes[1].childNodes[0].nodeValue
d = node_list[i].childNodes[3].childNodes[0].nodeValue
e = node_list[i].childNodes[5].childNodes[0].nodeValue
f = node_list[i].childNodes[7].childNodes[0].nodeValue
g = node_list[i].childNodes[9].childNodes[0].nodeValue
h = node_list[i].childNodes[11].childNodes[0].nodeValue
m = node_list[i].childNodes[13].childNodes[0].nodeValue
n = node_list[i].childNodes[15].childNodes[0].nodeValue
o = node_list[i].childNodes[17].childNodes[0].nodeValue
TreeArray[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray_2[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray[i].dates = getDates(TreeArray[i])
}
window.status = "This genealogy contains " + TreeArray.length + " persons"
sortRecords()
}

/* This is the corresponding function for Internet Explorer */

function readFileIE(){
node_list = xml_doc.getElementsByTagName("person")
for (i = 0; i <= node_list.length-1; i++){
b = node_list[i].attributes[0].nodeValue
c = node_list[i].childNodes[0].childNodes[0].nodeValue
d = node_list[i].childNodes[1].childNodes[0].nodeValue
e = node_list[i].childNodes[2].childNodes[0].nodeValue
f = node_list[i].childNodes[3].childNodes[0].nodeValue
g = node_list[i].childNodes[4].childNodes[0].nodeValue
h = node_list[i].childNodes[5].childNodes[0].nodeValue
m = node_list[i].childNodes[6].childNodes[0].nodeValue
n = node_list[i].childNodes[7].childNodes[0].nodeValue
o = node_list[i].childNodes[8].childNodes[0].nodeValue
TreeArray[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray_2[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray[i].dates = getDates(TreeArray[i])
}
window.status = "This genealogy contains " + TreeArray.length + " persons"
sortRecords()
}

/* This function uses bubble sorting to sort the TreeArray objects alphabetically according to their first name - not currently used */

/*function sortRecords(){
for (i = 0; i <= TreeArray.length-1; i++){
for (j = 1; j <= TreeArray.length-1; j++){
if (TreeArray[j-1].fullname.charAt(0) > TreeArray[j].fullname.charAt(0)){
buffer = TreeArray[j]
TreeArray[j] = TreeArray[j-1]
TreeArray[j-1] = buffer
}}}
displayMenu()
}*/

/* This function gives the option of sorting according to date of birth  */

function sortRecords(){
for (i = 0; i <= TreeArray.length-1; i++){
for (j = 1; j <= TreeArray.length-1; j++){
if (TreeArray[j-1].dob.substring(TreeArray[j-1].dob.length-4, TreeArray[j-1].dob.length) > TreeArray[j].dob.substring(TreeArray[j].dob.length-4, TreeArray[j].dob.length)){
buffer = TreeArray[j]
TreeArray[j] = TreeArray[j-1]
TreeArray[j-1] = buffer
}}}
displayMenu()
}

/* This function creates the select box menu of individual records */

function displayMenu(){
content = ""
content += "<select id='select8' onchange=viewDisplay(this.selectedIndex-1)>"
content += "<option selected='selected'>Select an individual</option>"
for (i = 0; i <= TreeArray.length-1; i++){
content += "<option>" + TreeArray[i].fullname + " " + TreeArray[i].dates + "</option>"
}
content += "</select><br><br>"
document.getElementById('output1').style.display = "block"
document.getElementById('output1').innerHTML = content
}

/*This function displays an individuals record when they are selected */

function viewDisplay(x){
document.getElementById('select8').selectedIndex = 0
pindex = x
for (i = 0; i <= child.length-1; i++){
child[i] = ""
}
var j = 0
for (i = 0; i <= TreeArray.length-1; i++){
if (TreeArray[i].id == TreeArray[x].father){
var father = TreeArray[i].fullname
findex = i}
if (TreeArray[i].id == TreeArray[x].mother){
var mother = TreeArray[i].fullname
mindex = i}
if (TreeArray[i].id == TreeArray[x].spouse){
var spouse = TreeArray[i].fullname
spindex = i}

if (TreeArray[i].father == TreeArray[x].id || TreeArray[i].mother == TreeArray[x].id){
child[j] = TreeArray[i].fullname
cindex[j] = i
j++}
}

content =""
content += "<table width='100%'>"
content += "<tr><td class='main'>Name: <span class='bold'>" + TreeArray[x].fullname + "</span></td>"
content += (father) ? "<td class='main'>Father: <span class='link' onclick='viewDisplay(findex)'>" + father + "</span></td>" : "<td class='main'>Father: unknown</td>"
content += (mother) ?"<td class='main'>Mother: <span class='link' onclick='viewDisplay(mindex)'>" + mother + "</span></td></tr>" : "<td class='main'>Mother: unknown</td></tr>"
content += "<tr><td class='main'>Date of birth: " + TreeArray[x].dob + "</td>"
content += "<td class='main'>Date of death: " + TreeArray[x].dod + "</td></tr>"

content += (spouse) ?"<tr><td class='main'>Spouse: <span class='link' onclick='viewDisplay(spindex)'>" + spouse + "</td>" : "<tr><td class='main'>Spouse: unknown</td>"
content += "<td class='main'>Date of marriage: " +  TreeArray[x].dom + "</span></td>"
for (i = 0; i <= child.length-1 ; i++){
content += (child[i]) ?"<tr><td class='main'>Child " + (i+1) + ": <span class='link' id='" + cindex[i] + "' onclick='viewDisplay(this.id)'>" + child[i] + "</td></tr>" : ""
}
content += "<tr><td class='main' width='400px'>Notes:<br><span>" + TreeArray[x].notes + "</span></td></tr>"
content += "<tr><td class='main'><button style='border:1px solid black; width:150px; color:navy; cursor:pointer; cursor:hand' id='" + TreeArray[x].id + "' onclick='showTree_1(this.id)'>Display descendants</button></td></tr>"
content += "<tr><td class='main'><button style='border:1px solid black; width:150px; color:navy; cursor:pointer; cursor:hand' id='" + TreeArray[x].id + "' onclick='showBinTree(" + x + ")'>Display ancestors</button></td></tr>"
content += "</table>"
content += "<br>"

document.getElementById('output2').style.display = "block"
document.getElementById('output2').innerHTML = content
}

function showBinTree(x){
BinTree[0] = TreeArray[x]
j = 2
k = 1
//while (j <= TreeArray.length-1){
while (j <= 256){
for (m = j-1; m <= 2*(j-1); m= m+2){
if (BinTree[m-k] != null){
BinTree[m] = findParent(BinTree[m-k].father)
}
if (BinTree[m-k] != null){
BinTree[m+1] = findParent(BinTree[m-k].mother)
}
k++
}
j = j*2
}
writeBinTree()
}

function findParent(x){
for (i = 0; i <= TreeArray.length-1; i++){
if (TreeArray[i].id == x){
return (TreeArray[i])
}}
return false
}

function writeBinTree(){
var array_size = BinTree.length+1
content = ""
content += "<style type='text/css'>body {background:#faffd2} h1 {text-align:center; margin-top:0px; margin-bottom:5px; color:#f1ae02; font-weight:normal; font-size:20pt; font-family: verdana, helvetica, arial} td {background:#ffffff; text-align:center; font-weight:normal; font-size:8pt; font-family: verdana, helvetica, arial;  border-style:solid; border-color:red; border-width:1} table {border-collapse:collapse;  border:solid 1px; border-color:red} button {font-weight:bold; font-size:10pt; font-family: verdana, helvetica, arial; border:1px solid black; color:navy}</style>"
content += "<h1>Ancestors of " + BinTree[0].fullname + "</h1><br>"
content += "<div align='center'><button onclick='self.close()'>Close Window</button></div><br><br>"
content += "<div align='center'><table>"
var i = 2
while (i <= array_size){
content += "<tr>"
for (var j = i-i/2 ; j < i; j++){
if (BinTree[j-1].fullname != null){
content += "<td colspan='" + array_size/i + "')>" + BinTree[j-1].fullname + "</td>"
}else{
content += "<td colspan='" + array_size/i + "')></td>"
}
}
i = i*2
content += "</tr>"
}
content += "</table></div>"
var newWin = window.open("", "", "height=550px, width=750px scrollbars resizable=yes")
newWin.document.write(content)
newWin.document.close()
newWin.moveTo(0,0)
}


/*This function resets TreeArray_2 to its original status */

function showTree_1(x){
if (newWin){
newWin.close()
newWin = null
}
if (navigator.appName != "Netscape"){
node_list = xml_doc.getElementsByTagName("person")
for (i = 0; i <= node_list.length-1; i++){
b = node_list[i].attributes[0].nodeValue
c = node_list[i].childNodes[0].childNodes[0].nodeValue
d = node_list[i].childNodes[1].childNodes[0].nodeValue
e = node_list[i].childNodes[2].childNodes[0].nodeValue
f = node_list[i].childNodes[3].childNodes[0].nodeValue
g = node_list[i].childNodes[4].childNodes[0].nodeValue
h = node_list[i].childNodes[5].childNodes[0].nodeValue
m = node_list[i].childNodes[6].childNodes[0].nodeValue
n = node_list[i].childNodes[7].childNodes[0].nodeValue
o = node_list[i].childNodes[8].childNodes[0].nodeValue
TreeArray_2[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray_2[i].dates = getDates(TreeArray_2[i])
}}
else{
node_list = xml_doc.getElementsByTagName("person")
for (i = 0; i <= node_list.length-1; i++){
b = node_list[i].attributes[0].nodeValue
c = node_list[i].childNodes[1].childNodes[0].nodeValue
d = node_list[i].childNodes[3].childNodes[0].nodeValue
e = node_list[i].childNodes[5].childNodes[0].nodeValue
f = node_list[i].childNodes[7].childNodes[0].nodeValue
g = node_list[i].childNodes[9].childNodes[0].nodeValue
h = node_list[i].childNodes[11].childNodes[0].nodeValue
m = node_list[i].childNodes[13].childNodes[0].nodeValue
n = node_list[i].childNodes[15].childNodes[0].nodeValue
o = node_list[i].childNodes[17].childNodes[0].nodeValue
TreeArray_2[i] = new person(i, b, c, d, e, f, g, h, m, n, o)
TreeArray_2[i].dates = getDates(TreeArray_2[i])
}}
showTree_2(x)
}

/* This function exchanges the selected person with TreeArray_2[0] */

function showTree_2(x){
for (i = 0; i <= TreeArray_2.length-1; i++){
if (TreeArray_2[i].id == x){
buffer = TreeArray_2[i]
TreeArray_2[i] = TreeArray_2[0]
TreeArray_2[0] = buffer
showTree_3()
}}}

/* This function sorts the array and assembles the tree, inserting children immediately after their parents*/

function showTree_3(){
for (i = TreeArray_2.length-2; i >= 1; i--){
for (j = TreeArray_2.length-2; j >= 1; j--){
if (TreeArray_2[j].dob.substring(TreeArray_2[j].dob.length-4, TreeArray_2[j].dob.length) < TreeArray_2[j+1].dob.substring(TreeArray_2[j+1].dob.length-4, TreeArray_2[j+1].dob.length)){
buffer = TreeArray_2[j]
TreeArray_2[j] = TreeArray_2[j+1]
TreeArray_2[j+1] = buffer
}}}

for (i = 0; i <= TreeArray_2.length-1; i++){
for (j = 0; j <= TreeArray_2.length-1; j++){
if (TreeArray_2[j].id == TreeArray_2[i].spouse){
TreeArray_2[i].spouse = TreeArray_2[j].fullname
}}}
TreeArray_2[0].level = 0
TreeArray_2[0].parent = TreeArray_2[0].father
for (i = 0; i <= TreeArray_2.length-1; i++){
for (j = i+1; j <= TreeArray_2.length-1; j++){
if (TreeArray_2[j].father == TreeArray_2[i].id){
TreeArray_2[i].children = "1"
TreeArray_2[j].parent = TreeArray_2[j].father
TreeArray_2[j].level = TreeArray_2[i].level +1
buffer = TreeArray_2[j]
for (k = j-1; k >= i+1; k--){
TreeArray_2[k+1] = TreeArray_2[k]
}
TreeArray_2[i+1] = buffer
}
else if (TreeArray_2[j].mother == TreeArray_2[i].id){
TreeArray_2[i].children = "1"
TreeArray_2[j].parent = TreeArray_2[j].mother
TreeArray_2[j].level = TreeArray_2[i].level +1
buffer = TreeArray_2[j]
for (k = j-1; k >= i+1; k--){
TreeArray_2[k+1] = TreeArray_2[k]
}
TreeArray_2[i+1] = buffer
}}}
if (TreeArray_2[0].children == "0"){alert("This person has no descendants"); return false}
showTree_4()
}

/* This function opens a new window and writes the HTML and javascript for the folding family tree */

function showTree_4(){
newWin = window.open("", "newWin", "height=500, width=650, resizable, scrollbars")
var content = ""
content += "<html><head><style type='text/css'>body {background:#faffd2} h1 {text-align:center; margin-top:0px; margin-bottom:5px; color:#f1ae02; font-weight:normal; font-size:20pt; font-family: verdana, helvetica, arial} button {font-weight:bold; font-size:10pt; font-family: verdana, helvetica, arial; border:1px solid black; color:navy}</style></head><body>"
content += "<h1>Descendants of " + TreeArray_2[0].fullname + "</h1><br>"
content += "<div align='center'><button onclick='self.close()'>Close Window</button></div><br/><br/></body></html>"
newWin.document.write(content)
newElem = newWin.document.createElement("span")
newElem.id = TreeArray_2[0].id
newElem.style.position = "relative"
newElem.style.fontWeight = "bold"
newElem.style.fontSize = "12pt"
newElem.style.fontFamily = "verdana, helvetica, arial, sans-serif"
newElem.style.color = "navy"
newElem.level = "level0"
newText = newWin.document.createTextNode(" " + TreeArray_2[0].fullname)
newElem.appendChild(newText)
newElem1 = newWin.document.createElement("span")
newElem1.className = "date"
newText1 = newWin.document.createTextNode(" " + TreeArray_2[0].dates)
newElem1.appendChild(newText1)
newElem.appendChild(newElem1)
newWin.document.documentElement.childNodes[1].appendChild(newElem)
for (i = 1; i <= TreeArray_2.length-1 ; i++){
if (newWin.document.getElementById(TreeArray_2[i].parent)){
newImg = newWin.document.createElement("img")
newImg.id = "img" + TreeArray_2[i].id
newImg.src = TreeArray_2[i].children == 0 ? "../../images/nullbox.gif" : "../../images/posbox.gif"
newImg.style.cursor = "default"
newElem = newWin.document.createElement("span")
newElem.id = TreeArray_2[i].id
newElem.style.position = "relative"
newElem.style.display = newWin.document.getElementById(TreeArray_2[i].parent).level == "level0" ? "block" : "none"
newElem.style.left = "50px"
newElem.style.fontWeight = "normal"
newElem.style.fontSize = "10pt"
newElem.style.fontFamily = "verdana, helvetica, arial, sans-serif"
newElem.style.color = TreeArray_2[i].level % 2 == 0 ? "navy" : "purple"
newText = newWin.document.createTextNode(" " + TreeArray_2[i].fullname)
newElem.appendChild(newImg)
newElem.appendChild(newText)
newWin.document.getElementById(TreeArray_2[i].parent).appendChild(newElem)
newElem1 = newWin.document.createElement("span")
newElem1.className = "date"
newElem1.level = newWin.document.getElementById(TreeArray_2[i].parent).level
newText1 = newWin.document.createTextNode(" " + TreeArray_2[i].dates)
newElem1.appendChild(newText1)
newElem.appendChild(newElem1)
navigator.appName == "Netscape" ? newImg.setAttribute("onclick", "opener.toggleDisplayMoz(this)") : newImg.onclick = toggleDisplayIE
}}
newWin.moveTo(0,0)
newWin.document.close()
} 


/* This section preloads the images for the tree display */

posbox = new Image
posbox.src = "../../images/posbox.gif"
negbox = new Image
negbox.src = "../../images/negbox.gif"
nullbox = new Image
nullbox.src = "../../images/nullbox.gif"

/* The following functions toggle the visibility of the elements and swap the images in response to mouse clicks for Internet Explorer and Mozilla respectively */

function toggleDisplayIE(){
x = newWin.event.srcElement
if(x.src==nullbox.src)
{return false}
if(x.src==posbox.src)
{x.src=negbox.src}
else{x.src=posbox.src}
for (var i = 3; i <= x.parentNode.childNodes.length-1; i++){
x.parentNode.childNodes[i].style.display == "block" ? x.parentNode.childNodes[i].style.display = "none" : x.parentNode.childNodes[i].style.display = "block"
}}

function toggleDisplayMoz(x){
if(x.src==nullbox.src)
{return false}
if(x.src==posbox.src)
{x.src=negbox.src}
else{x.src=posbox.src}
for (i = 3; i <= x.parentNode.childNodes.length-1; i++){
x.parentNode.childNodes[i].style.display == "block" ? x.parentNode.childNodes[i].style.display = "none" : x.parentNode.childNodes[i].style.display = "block"
}}

/* This function extracts the year elements from the dob and dod attributes */

function getDates(x){
bdate = x.dob != "" ? x.dob.substring(x.dob.length-4, x.dob.length) : "? "
ddate = x.dod != "" ? x.dod.substring(x.dod.length-4, x.dod.length) : "? "
x.dates = (bdate + " - " + ddate)
return x.dates
}

function reset(){
TreeArray = null
TreeArray_2 = null
TreeArray = new Array()
TreeArray_2 = new Array()
}
