/* (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 BirthEntry(id, group, type)
{
	this.id    = id;
	this.group = group;
	this.type  = type;
}


// -----------------------------------------------------------------------------------------------------------

BirthEntry.prototype.debug = function()
{
	return 'BirthEntry: 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 BirthSet()
{
	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]);
		}
	}
}


// -----------------------------------------------------------------------------------------------------------

BirthSet.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.child.id != '')
	{
		if(typeof(this.look[people.child.id]) == 'undefined')
		{
			this.look[people.child.id] = new Array();

			this.look_length++;
		}

		this.look[people.child.id].push(new BirthEntry(cert.id, g, 0));
	}

	if(!cert.full) return;

	if(people.dad.id != '')
	{
		if(typeof(this.look[people.dad.id]) == 'undefined')
		{
			this.look[people.dad.id] = new Array();

			this.look_length++;
		}

		this.look[people.dad.id].push(new BirthEntry(cert.id, g, 1));
	}

	if(people.mum.id != '')
	{
		if(typeof(this.look[people.mum.id]) == 'undefined')
		{
			this.look[people.mum.id] = new Array();

			this.look_length++;
		}

		this.look[people.mum.id].push(new BirthEntry(cert.id, g, 2));
	}

	if(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 BirthEntry(cert.id, g, 3));
	}
}


// -----------------------------------------------------------------------------------------------------------
// 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!

BirthSet.prototype.tack = function(id, references)
{
	// If this person is already in the indexes then generate an alert.

	if(this.get(id, 1).length) alert('Birth index issue for ' + id);

	var rs = new BirthReferenceSet(references);

	// Deduce some information from the index

	var d = new TDate(0,0,0);
	var w = '';
	var n = '';
	var s = '';

	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;
		}
	}

	var cert = new Birth(
		id,
		rs,
		new BirthLocation('','',''),
		new BirthPeople(
			new BirthCol('',w,n+' '+s,'','','','','','','',''),
			new BirthChild(id,n,s,'','',d,new Address('','','','','','')),
			0,0,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.

BirthSet.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.

BirthSet.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.

BirthSet.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;
}


// -----------------------------------------------------------------------------------------------------------

BirthSet.prototype.dump = function()
{
	var html = '';

	for(var id in this.group)
	{
		html += this.group[id].display();
	}

	return html;
}


// -----------------------------------------------------------------------------------------------------------

BirthSet.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 Birth(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.

Birth.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="certbirth">';
		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;
}


// -----------------------------------------------------------------------------------------------------------

Birth.prototype.history = function(person_type)
{
    var rel = ' ';

	if(person_type == 1 || person_type == 2)
	{
		     if(this.people.child.sex == 'M') { var event = 'Son Born'; var rel = 'son '; }
		else if(this.people.child.sex == 'F') { var event = 'Dau Born'; var rel = 'daughter '; }
		else                                  { var event = 'Baby'; }
	}
	else
	{
		var event = 'Born';
	}

	switch(person_type)
	{
	case 0 :


		var fi = this.full ? 'Baby of ' + this.people.dad.first.split(' ')[0] + ' &amp; ' + this.people.mum.first.split(' ')[0]
		                   : '<i>* generated from index *</i>';

		var histroy = new Array(
						   this.people.child.date,
						   event,
						   this.people.child.address.nice(),
						   this.people.child.first + ' ' + this.people.child.last,
						   'Baby',
						   '',
						   '',
						   0,
						   fi,
						   '',
						   '<a>');
		break;

	case 1 :

		var histroy = new Array(
						   this.people.child.date,
						   event,
						   this.people.child.address.nice(),
						   this.people.dad.first + ' ' + this.people.dad.last,
						   'Father',
						   '',
						   '',
						   0,
						   'Birth of ' + rel + this.people.child.first.split(' ')[0],
						   this.people.dad.occ,
						   '<a>');
		break;

	case 2 :

		var histroy = new Array(
						   this.people.child.date,
						   event,
						   this.people.child.address.nice(),
						   this.people.mum.first + ' ' + this.people.mum.last + ' nee ' + this.people.mum.maiden,
						   'Mother',
						   '',
						   '',
						   0,
						   'Birth of ' + rel + this.people.child.first.split(' ')[0],
						   '',
						   '<a>');
		break;

	case 3 :

		var histroy = new Array(
						   this.people.reg.date,
						   event,
						   this.people.reg.address.nice(),
						   this.people.reg.first + ' ' + this.people.reg.last,
						   this.people.reg.rel,
						   '',
						   '',
						   0,
						   'Birth of ' + this.people.child.first.split(' ')[0], // \todo maybe add rel if we ever use this
						   '',
						   '<a>');
		break;
	}

	return histroy;
}


// ===========================================================================================================
// CertReferenceGroup - Typically a person can be found in both the local records and the general records.

function BirthReferenceSet(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;
		}
	}
}


// -----------------------------------------------------------------------------------------------------------

BirthReferenceSet.prototype.display = function()
{
	var html = '';

	html += '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certbirth"><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 Birth</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="popcertbirth(\'' + 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.child.address.full() + '\')" border="0" width="22" height="12" src="../images/os.gif" title="Add To Map"></td>';
	}

	html += '</tr></table>';

	return html;
}

BirthReferenceSet.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 BirthReferenceTypes = new Array('LRO', 'GRO');

function BirthReference(type, source, year, quater, firsts, surname, 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.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;
}


// -----------------------------------------------------------------------------------------------------------

BirthReference.prototype.display = function()
{
	var html = '';

	if(this.source      != '') html += this.source      + ': ';

    html += BirthReferenceTypes[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.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 BirthLocation(reg, sub, loc)
{
	this.up = 0;

	this.reg = reg;
	this.sub = sub;
	this.loc = loc;
}


// -----------------------------------------------------------------------------------------------------------

BirthLocation.prototype.display = function()
{
	var html  = '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certbirth"><tr valign="top">';

	html += '<th class="adr3" width="117">Registration District</th><td class="adr3">'+this.reg+'</td>';
	html += '<th class="adr5" width="147">Birth 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 BirthCol(no, wwb, nif, sex, nsf, nsm, oof, sdr, wr, sr, nea)
{
	this.no  = no;
	this.wwb = wwb;
	this.nif = nif;
	this.sex = sex;
	this.nsf = nsf;
	this.nsm = nsm;
	this.oof = oof;
	this.sdr = sdr;
	this.wr  = wr;
	this.sr  = sr;
	this.nea = nea;
}


// ===========================================================================================================
// CertChild, CertDad, CertMum, CertReg - Processed data, use for everything else.

function BirthChild(id, first, last, sex, no, date, address)
{
	this.id      = id;
	this.first   = first;
	this.last    = last;
	this.sex     = sex;
	this.no      = no;
	this.date    = date;
	this.address = address;
}

function BirthDad(id, first, last, occ)
{
	this.id      = id;
	this.first   = first;
	this.last    = last;
	this.occ     = occ;
}

function BirthMum(id, first, last, maiden)
{
	this.id      = id;
	this.first   = first;
	this.last    = last;
	this.maiden  = maiden;
}

function BirthReg(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 BirthPeople(columns, child, dad, mum, reg)
{
	this.up = 0;

	this.columns = columns;
	this.child   = child;
	this.dad     = dad;
	this.mum     = mum;
	this.reg     = reg;
}


// -----------------------------------------------------------------------------------------------------------

BirthPeople.prototype.display = function(person_id)
{
	var html = '';

	html += '<table border="0" cellspacing="0" cellpadding="0" width="100%" class="certbirth"><tr valign="top">';
	html += '<th>No.</th>';
	html += '<th class="adr4">When and<br>Where<br>Born</th>';
	html += '<th class="adr4">Name,<br>If Any</th>';
	html += '<th class="adr4">Sex</th>';
	html += '<th class="adr4">Name,<br>Surname<br>of Father</th>';
	html += '<th class="adr4">Name, Surname,<br>Maiden Surname<br>of Mother</th>';
	html += '<th class="adr4">Occupation<br>of Father</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>';
	html += '<th class="adr4">Name Entered<br>After<br>Registration</th></tr><tr>';

	var c0 = ''; var c1 = ''; if(person_id == this.child.id) { c0 = '<span class="certmatch">'; c1 = '</span>'; }
	var d0 = ''; var d1 = ''; if(person_id ==   this.dad.id) { d0 = '<span class="certmatch">'; d1 = '</span>'; }
	var m0 = ''; var m1 = ''; if(person_id ==   this.mum.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">' + c0 + this.columns.wwb + c1 + '</td>';
	html += '<td class="adr4"><a href="#" onclick=\'paste_update("' + this.child.id + '");\' title="' + this.child.id + '">' + c0 + this.columns.nif + c1 + '</a></td>';
	html += '<td class="adr4">' + c0 + this.columns.sex + c1 + '</td>';
	html += '<td class="adr4"><a href="#" onclick=\'paste_update("' + this.dad.id + '");\' title="' + this.dad.id + '">' + d0 + this.columns.nsf + d1 + '</a></td>';
	html += '<td class="adr4"><a href="#" onclick=\'paste_update("' + this.mum.id + '");\' title="' + this.mum.id + '">' + m0 + this.columns.nsm + m1 + '</a></td>';
	html += '<td class="adr4">' + d0 + this.columns.oof + d1 + '</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 += '<td class="adr4">' + c0 + this.columns.nea + c1 + '</td>';
	html += '</tr></table>';

	return html;
}

