/* (c) Sam Gratrix */


// The Birth, Baptism, Marriage and Death classes have similar code, so often Cert will be uses as a generic
// reference to these four classes, mainly to aid diffing. Yes, I could be more clever about code reuse, but
// I think given the suble differences that crop up, diffing will do for now.


// ===========================================================================================================
// CertEntry and CertLook used to map a persons id to an entry in the CertSet and CertGroup. This is so that
// we can look up other people mentioned in the certificate.

function DeathEntry(id, group, type)
{
	this.id    = id;
	this.group = group;
	this.type  = type;
}


// -----------------------------------------------------------------------------------------------------------

DeathEntry.prototype.debug = function()
{
	return 'DeathEntry: id = ' + this.id + ', group = ' + this.group + ', type = ' + this.type + '. ';
}


// ===========================================================================================================
// CertSet - Collection of Certs objects. Access functions take a person id and automatically do a lookup for
// the actual cert. Assumes that each person can only exist in the cert set once. Each entry in the group
// is an array so that mutiple Certs can be attributed to a persons id.

function DeathSet()
{
	this.group_length = 0;
	this.group        = new Array();

	this.look_length  = 0;
	this.look         = new Array();

	for(var i=0; i<arguments.length; i++)
	{
		if(typeof(arguments[i]) != 'undefined')
		{
			this.add(arguments[i]);
		}
	}
}


// -----------------------------------------------------------------------------------------------------------

DeathSet.prototype.add = function(cert)
{
	// If a new id is enountered, then make a new group.

	if(typeof(this.group[cert.id]) == 'undefined')
	{
		this.group[cert.id] = new Array();

		this.group_length++;
	}

	// Add the object to the appropiate group.

	var g = this.group[cert.id].push(cert) - 1;

	// Now create lookup information for fast querying.

	var people = cert.people;

//	if(people == '') return;

	if(people.main.id != '')
	{
		if(typeof(this.look[people.main.id]) == 'undefined')
		{
			this.look[people.main.id] = new Array();

			this.look_length++;
		}

		this.look[people.main.id].push(new DeathEntry(cert.id, g, 0));
	}

	if(!cert.full) return;

	if(cert.full && people.reg.id != '')
	{
		if(typeof(this.look[people.reg.id]) == 'undefined')
		{
			this.look[people.reg.id] = new Array();

			this.look_length++;
		}

		this.look[people.reg.id].push(new DeathEntry(cert.id, g, 1));
	}
}


// -----------------------------------------------------------------------------------------------------------
// For index only inforamtion. This is a shead load of index info, so we construct the Cert here rahter than
// as inline code to save on download. This is a "synthetic certifficate" in that it is automatically
// generated from index information. Conseqently it looks a bit back to front!

DeathSet.prototype.tack = function(id, references)
{
	// If this person is already in the indexes then generate an alert.

	if(this.get(id, 1).length) alert('Death index issue for ' + id);

	var rs = new DeathReferenceSet(references);

	// Deduce some information from the index

	var d = new TDate(0,0,0);
	var w = '';
	var n = '';
	var s = '';
	var a = 0;

	for(var i=0; i<rs.refs.length; i++)
	{
		var ref = rs.refs[i];

		if(d.stamp < ref.date.stamp)
		{
			d = ref.date;

			w = d.nice() + ' ' + ref.office + ' ' + ref.district;
			n = ref.firsts;
			s = ref.surname;
			a = ref.age;
		}
	}

	var cert = new Death(
		id,
		rs,
		new DeathLocation('','',''),
		new DeathPeople(
			new DeathCol('',w,n+' '+s,'',a,'','','','',''),
			new DeathMain(id,n,s,'',a,'','',d,new Address('','','','','','')),
			0),
		'Generated from ' + (rs.refs.length == 1 ? 'the' : rs.refs.length) + ' index reference' + (rs.refs.length == 1 ? '' : 's') + ' so use only as a guide.'
		);

	cert.full = 0;

	this.add(cert);
}


// -----------------------------------------------------------------------------------------------------------
// Returns a filtered and sorted CertLook object which tells you where the person is in the certificates.
// Use .length to determine if there are any results.
//
// To Do: Ordering.

DeathSet.prototype.get = function(person_id, simple)
{
	var look = this.look[person_id];

	var filter = new Array();

	if(typeof(look) != 'undefined')
	{
		for(var i=0; i<look.length; i++)
		{
			if(simple && look[i].type != 0)
			{
				continue;
			}

			var add = 1;

			for(var j=0; j<filter.length; j++)
			{
				if( (filter[j].id != look[i].id) || (filter[j].group != look[i].group) )
				{
					continue;
				}

				add = 0;

				break;
			}

			if(add)
			{
				filter.push(look[i]);
			}
		}
	}

	return filter;
}


// -----------------------------------------------------------------------------------------------------------
// Display all the certificates related to the person.
//
// TO DO: Allow passing of filter control.

DeathSet.prototype.display = function(person_id, simple)
{
	var filter = this.get(person_id, simple);

	var html = '';

	for(var i=0; i<filter.length; i++)
	{
		var entry = filter[i];

		var group = this.group[entry.id];

		var cert  = group[entry.group];

		html += cert.display(person_id);
	}

	delete filter;

	return html;
}


// -----------------------------------------------------------------------------------------------------------
// Get history data for use in the summary lines of the Person display.
//
// TO DO: Allow passing of filter control.

DeathSet.prototype.history = function(person_id)
{
	var filter = this.get(person_id);

	var histroy = new Array();

	for(var i=0; i<filter.length; i++)
	{
		var entry  = filter[i];

		var cert   = this.group[entry.id][entry.group];

		histroy.push(cert.history(entry.type));
	}

	delete filter;

	return histroy;
}


// -----------------------------------------------------------------------------------------------------------

DeathSet.prototype.dump = function()
{
	var html = '';

	for(var id in this.group)
	{
		html += this.group[id].display();
	}

	return html;
}


// -----------------------------------------------------------------------------------------------------------

DeathSet.prototype.report = function()
{
	return(this.group_length);
}


// ===========================================================================================================
// Cert. A regular cert is full, if however, it have been fudged from an index then it's not full.

function Death(id, reference, location, people, note)
{
	this.id           = id;

	this.full         = 1;
	this.reference    = reference;
	this.location     = location;
	this.people       = people;
	this.note         = note;

	// Reverse references

	this.reference.up = this;
	this.location.up  = this;
	this.people.up    = this;
}


// -----------------------------------------------------------------------------------------------------------
// When a cert is displayed we may wish to alter the view given who we are displaying it for. That is, we can
// display a cert choosing to highlight the 'main' person, or any other people such are relations, etc.

Death.prototype.display = function(person_id)
{
	var html = '';

	html += '<table border="0" cellspacing="1" cellpadding="0" width="748" class="bor1"><tr><td>';
	html += '<table border="0" cellspacing="0" cellpadding="0" width="100%">';

	html += '<tr><td>' + this.reference.display() + '</td></tr>';

	if(this.full)
	{
		html += '<tr><td>' + this.location.display() + '</td></tr>';
	}

	html += '<tr><td>' + this.people.display(person_id) + '</td></tr>';

	var ref_notes = this.reference.notes();

	if(this.note.length || ref_notes.length)
	{
		html += '<tr><td><table border="0" cellspacing="0" cellpadding="0" width="100%" class="certdeath">';
		html += '<tr><th class="adr6">My Notes</th><td class="adr6" width="100%">' + this.note;

		if(this.note.length && ref_notes.length) html += '<br/>';

		html += ref_notes + '</td></tr></table></td></tr>';
	}

	html += '</table></td></tr></table>';

	return html;
}


// -----------------------------------------------------------------------------------------------------------

Death.prototype.history = function(person_type)
{
	// dad		1
	// mum		2
	// widow	3  (ie wife)
	// widower	4  (ie husband)
	// son		5
	// daughter	6

	switch(person_type)
	{
	case 0 :

		var relc = ['', 'father ', 'mother ', 'wife ', 'husband ', 'son ', 'daughter '];

		var fi = this.full ? 'Informed by ' + relc[this.people.reg.relc] + ' ' + this.people.reg.first.split(' ')[0]
		                   : '<i>* generated from index *</i>';

		var histroy = new Array(
						   this.people.main.date,
						   'Death',
						   this.people.main.address.nice(),
						   this.people.main.first + ' ' + this.people.main.last,
						   'Deceased',
						   '',
						   this.people.main.age,
						   0,
						   fi,
						   this.people.main.occ,
						   '<a>');
		break;

	case 1 :

		// For inverse relation of {dad, mum}      === child,  use sex to resolve to {son, daughter}.
        // For inverse relation of {son, daughter} === parent, use sex to resolve to {father, mother}.

		// \todo Sould I do this at construction time?

		var rel = '';

		switch(this.people.reg.relc)
		{
			case 1 :
			case 2 : rel = (this.people.main.sex == 'M') ? 'son '    : (this.people.main.sex == 'F') ? 'daughter ' : 'child ' ; break;
			case 3 : rel = 'husband '; break;
			case 4 : rel = 'wife '; break;
			case 5 :
			case 6 : rel = (this.people.main.sex == 'M') ? 'father ' : (this.people.main.sex == 'F') ? 'mother '   : 'parent '; break;
		}

		var histroy = new Array(
						   this.people.reg.date,
						   'Death Reg',
						   this.people.reg.address.nice(),
						   this.people.reg.first + ' ' + this.people.reg.last,
						   this.people.reg.rel,
						   '',
						   '',
						   0,
						   'Death of ' + rel + this.people.main.first.split(' ')[0],
						   '',
						   '<a>');
		break;
	}

	return histroy;
}


// ===========================================================================================================
// CertReferenceGroup - Typically a person can be found in both the local records and the general records.

function DeathReferenceSet(array)
{
	this.up  = 0;

	this.refs    = array;
	this.country = '';
	this.year    = 0;

    // To do - sort into lro, then gro order.

	// Grab a country and year

	for(var i=0; i<this.refs.length; i++)
	{
		if(this.refs[i].type == 0) // lro
		{
			this.country = this.refs[i].country;
			this.year    = this.refs[i].year;

			if(this.year > 0) return;
		}
	}

	for(var i=0; i<this.refs.length; i++)
	{
		if(this.refs[i].type == 1) // gro
		{
			this.country = this.refs[i].country;
			this.year    = this.refs[i].year;

			if(this.year > 0) return;
		}
	}
}


// -----------------------------------------------------------------------------------------------------------

DeathReferenceSet.prototype.display = function()
{
	var html = '';

	html += '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certdeath"><tr valign="center">';
	html += '<td valign="center" class="adr3x">';
	html += '<img border=0 width=23 height=15 align="absmiddle" src="../images/' + this.country + '.gif" alt="">';
	html += '<b> ' + (this.year > 0 ? this.year + ' ' : '') + (this.up.full ? 'Entry' : 'Index') + ' of Death</b></td>';
	html += '<th class="adr5">Source</th><td class="adr3nr" width="100%">';

	for(var i=0; i<this.refs.length; i++)
	{
		if(i) html += '<br>';

		html += (i+1) + '. ' + this.refs[i].display();
	}

	html += '</td>';

	if(this.up.full)
	{
		if(tree_private == 1)
		{
			html += '<td class="adr3"><img onclick="popcertdeath(\'' + this.up.id + '\')" border="0" width="20" height="16" src="../images/ff_image.gif" title="Open Image"></td>';
		}

		html += '<td class="adr3"><img onclick="map_search_mark_center(\'' + this.up.people.main.address.full() + '\')" border="0" width="22" height="12" src="../images/os.gif" title="Add To Map"></td>';
	}

	html += '</tr></table>';

	return html;
}

DeathReferenceSet.prototype.notes = function()
{
	var html = '';

	for(var i=0; i<this.refs.length; i++)
	{
		if(this.refs[i].note.length)
		{
			if(html.length) html += '<br/>';

			html += 'Source ' + (i+1) + '. ' + 	this.refs[i].note;
		}
	}

	return html;
}


// ===========================================================================================================
// CertReference - Not all entries need to be use, whichever are appropriate to the LRO, GRO, etc.

var DeathReferenceTypes = new Array('LRO', 'GRO');

function DeathReference(type, source, year, quater, firsts, surname, age, country, office, subdistrict, register, county, district, vol, page, region, ref, note)
{
	this.year        = year;
	this.quater      = quater;

	var q = quater.toLowerCase();
	    q = (q == 'mar' ? '-1' : (q == 'jun' ? '-2' : (q == 'sep' ? '-3' : (q == 'dec' ? '-4' : 0)))) ;
	this.date        = new TDate(parseInt(year), q, 0);

	this.type        = type;
	this.source      = source;
	this.firsts      = firsts;
	this.surname     = surname;
	this.age         = age;
	this.country     = country;
	this.office      = office;
	this.subdistrict = subdistrict;
	this.register    = register;
	this.county      = county;
	this.district    = district;
	this.vol         = vol;
	this.page        = page;
	this.region      = region;
	this.ref         = ref;
	this.note        = note;
}


// -----------------------------------------------------------------------------------------------------------

DeathReference.prototype.display = function()
{
	var html = '';

	if(this.source      != '') html += this.source      + ': ';

    html += DeathReferenceTypes[this.type] + ' - ';

	if(this.country     != '') html += this.country     + ' - ';
	if(this.quater      != '') html += this.quater      + ' - ';
	if(this.year        != '') html += this.year        + ' - ';
	if(this.firsts      != '') html += this.firsts      + ' - ';
	if(this.surname     != '') html += this.surname     + ' - ';
	if(this.age         != '') html += this.age         + ' - ';
	if(this.office      != '') html += this.office      + ' - ';
	if(this.subdistrict != '') html += this.subdistrict + ' - ';
	if(this.register    != '') html += this.register    + ' - ';
	if(this.county      != '') html += this.county      + ' - ';
	if(this.district    != '') html += this.district    + ' - ';
	if(this.vol         != '') html += this.vol         + ' - ';
	if(this.page        != '') html += this.page        + ' - ';
	if(this.region      != '') html += this.region      + ' - ';
	if(this.ref         != '') html += this.ref         + ' - ';

    var l = html.length - 3; if(l < 0) len = 0;

	return html.substr(0, l);
}


// ===========================================================================================================
// CertLocation - This is just the stuff from the boxes at the top of the cert form. It is not really used for
// anything other than display. For the proper address of the person you should really use the Address class.
// For proper cert location data it should be redervied from CertReference. CertLocation is just as it is
// transcribed.

function DeathLocation(reg, sub, loc)
{
	this.up = 0;

	this.reg = reg;
	this.sub = sub;
	this.loc = loc;
}


// -----------------------------------------------------------------------------------------------------------

DeathLocation.prototype.display = function()
{
	var html  = '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certdeath"><tr valign="top">';

	html += '<th class="adr3" width="117">Registration District</th><td class="adr3">'+this.reg+'</td>';
	html += '<th class="adr5" width="147">Death in the Sub-District of</th><td class="adr3">'+this.sub+'</td>';
	html += '<th class="adr5" width="39">In the</th><td class="adr3">'+this.loc+'</td></tr></table>';

	return html;
}


// ===========================================================================================================
// CertCol - As written on the certifficate, use for display on cert.

function DeathCol(no, wwd, ns, sex, age, occ, cod, sdr, wr, sr)
{
	this.no  = no;
	this.wwd = wwd;
	this.ns  = ns;
	this.sex = sex;
	this.age = age;
	this.occ = occ;
	this.cod = cod;
	this.sdr = sdr;
	this.wr  = wr;
	this.sr  = sr;
}


// ===========================================================================================================
// CertChild, CertDad, CertMum, CertReg - Processed data, use for everything else.

function DeathMain(id, first, last, sex, age, occ, no, date, address)
{
	this.id      = id;
	this.first   = first;
	this.last    = last;
	this.sex     = sex;
	this.age     = age;
	this.occ     = occ;
	this.no      = no;
	this.date    = date;
	this.address = address;
}

function DeathReg(id, first, last, rel, relc, date, address)
{
	this.id      = id;
	this.first   = first;
	this.last    = last;
	this.rel     = rel;
	this.relc    = relc;
	this.date    = date;
	this.address = address;
}


// ===========================================================================================================
// CertPeople - Collects the above.

function DeathPeople(columns, main, reg)
{
	this.up = 0;

	this.columns = columns;
	this.main    = main;
	this.reg     = reg;
}


// -----------------------------------------------------------------------------------------------------------

DeathPeople.prototype.display = function(person_id)
{
	var html = '';

	html += '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certdeath"><tr valign="top">';
	html += '<th>No.</th>';
	html += '<th class="adr4">When and<br>Where Died</th>';
	html += '<th class="adr4">Name and<br>Surname</th>';
	html += '<th class="adr4">Sex</th>';
	html += '<th class="adr4">Age</th>';
	html += '<th class="adr4">Occupation</th>';
	html += '<th class="adr4">Cause of Death</th>';
	html += '<th class="adr4">Signature, Description, and<br>Residence of Informant</th>';
	html += '<th class="adr4">When<br>Registered</th>';
	html += '<th class="adr4">Signature<br>of Registrar</th></tr><tr>';

	var m0 = ''; var m1 = ''; if(person_id == this.main.id) { m0 = '<span class="certmatch">'; m1 = '</span>'; }
	var r0 = ''; var r1 = ''; if(person_id ==  this.reg.id) { r0 = '<span class="certmatch">'; r1 = '</span>'; }

	html += '<td>' + this.columns.no + '</td>';
	html += '<td class="adr4">' + m0 + this.columns.wwd + m1 + '</td>';
	html += '<td class="adr4"><a href="#" onclick=\'paste_update("' + this.main.id + '");\' title="' + this.main.id + '">' + m0 + this.columns.ns + m1 + '</a></td>';
	html += '<td class="adr4">' + m0 + this.columns.sex + m1 + '</td>';
	html += '<td class="adr4">' + m0 + this.columns.age + m1 + '</a></td>';
	html += '<td class="adr4">' + m0 + this.columns.occ + m1 + '</a></td>';
	html += '<td class="adr4">' + m0 + this.columns.cod + m1 + '</td>';
	html += '<td class="adr4"><a href="#" onclick=\'paste_update("' + this.reg.id + '");\' title="' + this.reg.id + '">' + r0 + this.columns.sdr + r1 + '</a></td>';
	html += '<td class="adr4">' + r0 + this.columns.wr + r1 + '</td>';
	html += '<td class="adr4">' + this.columns.sr + '</td>';
	html += '</tr></table>';

	return html;
}

