Record Birth Data UK.fh_lua

--[[
@Title: Record Birth Data (UK and Ireland)
@Type: Source-driven Data Entry
@Subtype: "Civil Registration Certificate"
@Author: Calico Pie
@Contributor: Helen Wright
@Version: 1.7
@Keywords: 
@LastUpdated: November 2021
@GH  #24 #37 #54 #66 #76 #88 #112 #119
@Description:
This plugin allows the entry of details from a birth certificate and creates records for individuals named if needed, as well as recording residence, occupation birth and death facts. 

Supports UK and Ireland Birth certificates

England and Wales

Scotland (not 1855)

Isle of Man (you should create an Isle of Man region)

Channel Islands (you should create a Channel Islands region)

Ireland

Northern Ireland (you should create a Northern Ireland region)
]]

fhInitialise(7, 0, 0)
fh = require 'fhUtils'
fh.setIupDefaults()

stringx.import()

-- Local Globals
local form, templateName, templateDefault
local sRegionName
local sPluginName = fhGetContextInfo 'CI_PLUGIN_NAME'
local s = {} -- Autofill table
local pCite, iRegion, iYear -- Citation Object
local tUpdatedFields = {} -- Added and updated fields
local cells = {} -- Main Dialog sections

--- Builds dialog and drives process.
function main()

	-- ------------------------------------------------------------Load citation and associated fields
	pCite = fh.loadPreparedCitation()

	if not pCite.result then
		fh.getParam(sPluginName, pCite.err)
		return
	end
	-- Ensure all needed fields have been completed
	if
		not (
			pCite:checkRequired(
				'EN-REGION',
				'EN-TYPE',
				'NM-PRINCIPAL',
				'DT-DATE',
				'PL-LOCATION'
			)
		)
	then
		fh.getParam(
			sPluginName,
			'Not all required fields are set,\nplease ensure you have entered type, date, location and principal. '
		)
		return
	end
	if pCite:getValue 'EN-TYPE' ~= 'Birth' then
		fh.getParam(sPluginName, 'Only Birth is supported by this plugin. ')
		return
	end
	-- Get form and load values from Citation
	sRegionName = pCite:getValue 'EN-REGION'
	local masterForms = loadMasterForms()
	if not masterForms[sRegionName] then
		fh.getParam(sPluginName, 'Sorry ' .. sRegionName .. ' not supported.')
		return
	end

	form = tablex.deepcopy(masterForms[sRegionName]['sections'])
	templateName = masterForms[sRegionName]['templateName']
	templateDefault = masterForms[sRegionName]['templateDefault']

	form.principal.fields[1].value = pCite:getValue 'NM-PRINCIPAL'

	dtEventDateString = pCite:getDisplayValue 'DT-DATE'
	dtEventDate = pCite:getValue 'DT-DATE'

	-- ------------------------------------------------------------ Get currently selected person
	local ptrPrincipal = fh.getCurrentIndividual()
	if ptrPrincipal:IsNotNull() then
		form.principal.fields[field(form.principal.fields, 'RECORD')].value =
			ptrPrincipal:Clone()
		changePrincipal(ptrPrincipal, true)
	end
	-- ------------------------------------------------------------ Create Dialog
	for k, v in pairs(form) do
		grid = iup.gridbox {
			numdiv = 2,
			cgaplin = '1',
			cgapcol = '1',
			margin = '4x4',
			expand = 'YES',
		}
		for l, f in ipairs(v.fields) do
			if f.label then
				local label = string.rep(' ', f.label:len()) .. ' '
				local value = '                                       '
				if f.gridDisplay or v.gridDisplay then
					label = f.label .. ':'
					value = fh.getParamValueForDisplay(f, true)
					if value == f.label then
						value = utils.choose(f.value == true, 'Yes', 'No')
					end
				end
				f.gridLabel = iup.label {
					title = label,
					size = '80',
					expand = 'HORIZONTAL',
				}
				iup.Append(grid, f.gridLabel)
				f.iupgrid = iup.label { title = value, expand = 'YES' }
				iup.Append(grid, f.iupgrid)
			end
		end
		v.button = iup.button { title = 'Edit', active = 'NO' }
		if v.active then
			v.button.active = 'YES'
		end
		v.button.action = function()
			doEdit(k, v.title, v.seq)
		end
		cells[v.seq] = iup.vbox {
			EXPANDCHILDREN = 'YES',
			EXPAND = 'YES',
			iup.frame {
				title = v.title,
				EXPANDCHILDREN = 'YES',
				EXPAND = 'YES',
				iup.vbox {
					EXPANDCHILDREN = 'YES',
					EXPAND = 'YES',
					v.button,
					grid,
				},
			},
		}
	end

	local placeList = fh.createPlaceList()
	s['PLAC'] = placeList
	s['OCCU'] = {} -- TODO
	local addressList = {}

	txtMessage = iup.label {
		title = ' Hint: please edit the Principal section to enable the other sections',
	}

	btnOk = iup.button { title = 'OK', padding = '20x4', expand = 'HORIZONTAL' }

	function btnOk.action()
		if form.principal.valid then
			local sVenue = pCite:getValue 'TX-CHURCH'
			if not sVenue then
				sVenue = pCite:getValue 'AD-ADDRESS'
			end
			processBirth(pCite:getValue 'PL-LOCATION', sVenue)
			return iup.CLOSE
		else
			fhMessageBox 'Information has not been entered on both Principal and Spouse'
		end
	end
	btnCancel = iup.button {
		title = 'Cancel',
		padding = '4x4',
		expand = 'HORIZONTAL',
	}

	function btnCancel.action()
		return iup.CLOSE
	end

	local sTitle = 'Birth Entry: ' .. fhGetDisplayText(pCite.source)
	dlg = iup.dialog {
		title = sTitle,
		minsize = '1000',
		iup.vbox {
			EXPANDCHILDREN = 'YES',
			EXPAND = 'YES',

			iup.gridbox {
				numdiv = 2,
				cgaplin = '1',
				cgapcol = '1',
				margin = '4x4',
				expand = 'YES',
				EXPANDCHILDREN = 'YES',
				table.unpack(cells),
			},
			iup.hbox {
				margin = '4x4',
				expand = 'NO',
				btnOk,
				btnCancel,
				fh.helpButton 'record-birth-data-uk',
				txtMessage,
			},
		},
	}
	iup.SetAttribute(dlg, 'NATIVEPARENT', fhGetContextInfo 'CI_PARENT_HWND') -- Set the parent window handle  iup.SetHandle("main", dlg)
	iup.SetGlobal('PARENTDIALOG', 'main')

	iup.Popup(dlg)
	iup.Destroy(dlg)
end
-- --------------------------------------------------------------- doEdit
--- Called from the Edit buttons to update the sections
-- @param sType string, section name from form table
-- @param sTitle string Name of dialog
-- @param seq  number, sequence number of section
function doEdit(sType, sTitle, seq)
	local fields = form[sType].fields
	if sType == 'principal' then
		local oldRecord =
			form[sType]['fields'][field(fields, 'RECORD')].value:Clone()
		local oldFamily = form[sType]['fields'][field(fields, 'FAMILY')]

		if oldFamily.value then
			oldFamily = oldFamily.value:Clone()
		else
			oldFamily = fhNewItemPtr()
		end
		local r = fh.getParam(
			'Enter ' .. sTitle,
			nil,
			fields,
			{ 'OK', 'Cancel', fh.helpButton 'record-marriage-data-uk-principal' },
			s
		)
		if r.ok then
			form[sType].valid = true
			-- enable all Edit buttons
			for k, v in pairs(form) do
				v.button.active = 'YES'
			end
			-- To Do Ripple all fields

			if
				not (oldRecord:IsSame(r.results['RECORD']))
				or not (oldFamily:IsSame(r.results['FAMILY']))
			then
				changePrincipal(r.results['RECORD'])
			end
		end
	else
		local r = fh.getParam(
			'Enter ' .. sTitle,
			nil,
			fields,
			{ 'OK', 'Cancel' },
			s
		)
		if r.ok then
			form[sType].valid = true
			form[sType].gridDisplay = true
		end
	end
	updateGrid()
end
-- --------------------------------------------------------------- changePrincipal
--- Update other section/grid boxes when the Principal record is changed
-- @param ptrPrincipal fhItemPointer for the Principal person on the certifcate
-- @param init  boolean, true on first run.

function changePrincipal(ptrPrincipal, init)
	local f = form['principal'].fields
	if ptrPrincipal:IsNotNull() then
		if init then
			-- first time load or new Record selected

			local values, prompts = updateFamList(ptrPrincipal, 'FamilyAsChild')
			f[field(f, 'FAMILY')].values = values
			f[field(f, 'FAMILY')].prompts = prompts
			f[field(f, 'FAMILY')].value = values[1]

			f[field(f, 'ACTION')].value = 'select'
			f[field(f, 'FAMILY')].protect = false
			f[field(f, 'RECORD')].protect = false
		end

		f[field(f, 'SEX')].value = fhGetItemText(ptrPrincipal, '~.SEX')
		-- f[field(f,'SEX')].protect = true

		local ptrFam = f[field(f, 'FAMILY')].value
		if ptrFam:IsNotNull() then
			-- Set up Father of Principal if they exist
			local ptrF = fhGetItemPtr(ptrFam, '~.HUSB>')
			if ptrF:IsNotNull() then
				local s = form['father'].fields
				s[field(s, 'NAME')].value = fh.editableName(
					fhGetItemText(ptrF, '~.NAME:STORED')
				)
				s[field(s, 'RECORD')].value = ptrF:Clone()
				s[field(s, 'RECORD')].protect = true
				s[field(s, 'ACTION')].value = 'select'
				s[field(s, 'ACTION')].protect = true
			end
			-- Set up Mother of Principal if they exist
			local ptrF = fhGetItemPtr(ptrFam, '~.WIFE>')
			if ptrF:IsNotNull() then
				local s = form['mother'].fields
				s[field(s, 'NAME')].value = fh.editableName(
					fhGetItemText(ptrF, '~.NAME:STORED')
				)
				s[field(s, 'RECORD')].value = ptrF:Clone()
				s[field(s, 'RECORD')].protect = true
				s[field(s, 'ACTION')].value = 'select'
				s[field(s, 'ACTION')].protect = true
			end
		else
			resetSection 'father'
			resetSection 'mother'
		end
	else
		resetSection 'father'
		resetSection 'mother'
	end
end

-- --------------------------------------------------------------- resetSection
--- Reset the section values from the master form
-- @param formSection string section index
function resetSection(formSection)
	for k, v in ipairs(form[formSection]['fields']) do
		for m, u in pairs(v) do
			form[formSection]['fields'][k][m] = u
		end
	end
	updateGrid()
end

-- --------------------------------------------------------------- updateGrid
--- Update All Grid Fields from table
function updateGrid()
	for sType, sSection in pairs(form) do
		for l, f in ipairs(sSection.fields) do
			local label = ' '
			local value = ' '
			if f.gridDisplay or form[sType].gridDisplay then
				label = f.label
				value = fh.getParamValueForDisplay(f, true)
				if value == f.label then
					value = utils.choose(f.value == true, 'Yes', 'No')
				end
			end
			if f.gridLabel then
				f.gridLabel.title = label
			end
			if f.iupgrid then
				f.iupgrid.title = value
			end
		end
	end
end

function processBirth(sPlace, sAddress, sCelebrant)
	local fields = {}
	local data = {}
	for k, s in pairs(form) do
		data[k] = {}
		for i, f in ipairs(s.fields) do
			data[k][f.tag] = { value = f.value, type = f.type, dr = f.df }
		end
	end

	-- Create needed Individual Records
	for _, f in pairs(data) do
		if f.ACTION and f.ACTION.value == 'create' then
			local sex
			if f.SEX and f.SEX.value then
				sex = f.SEX.value
			end
			local ptr = fh.createIndi(f.NAME.value, sex)
			addCitation(ptr, 'Created')
			local ptrName = fhGetItemPtr(ptr, '~.NAME')
			addCitation(ptrName, 'Cited')
			f.RECORD.value:MoveTo(ptr)
		end
	end

	local ptrfamC = processParents(
		data.father.RECORD.value,
		data.mother.RECORD.value,
		data.principal.RECORD.value
	)

	local eventDate = pCite:getValue 'DT-DATE'
	local sPlace = pCite:getValue 'PL-LOCATION'
	local sAddress = pCite:getValue 'AD-ADDRESS'
	-- Create / Update Birth Event
	local ptrBirth = fhGetItemPtr(data.principal.RECORD.value, '~.BIRT')
	local sAction = ''
	if ptrBirth:IsNotNull() then
		ptrBirth, sAction = fh.createUpdateFact(
			data.principal.RECORD.value,
			'BIRT',
			'Birth',
			sPlace,
			eventDate,
			sAddress
		)
		if ptrBirth then
			addCitation(ptrBirth, sAction)
		end
	else
		ptrBirth = fh.createFact(
			data.principal.RECORD.value,
			'BIRT',
			sPlace,
			eventDate,
			sAddress
		)
		if ptrBirth then
			addCitation(ptrBirth, 'Added')
		end
	end
	for k, f in pairs(data) do
		if ptrBirth and k == 'informant' then
			if f.RELATIONSHIP.value == 'Father' then
				f.RECORD.value:MoveTo(data.father.RECORD.value)
				f.ACTION.value = data.father.ACTION.value
			end
			if f.RELATIONSHIP.value == 'Mother' then
				f.RECORD.value:MoveTo(data.mother.RECORD.value)
				f.ACTION.value = data.mother.ACTION.value
			end
			if f.ACTION.value == 'name' and fh.isSet(f.NAME.value) then
				fh.addWitness(ptrBirth, f.NAME.value, 'Informant')
			elseif fh.isSet(f.RECORD.value) then
				fh.addWitness(ptrBirth, f.RECORD.value, 'Informant')
			end
		end
		if f.RECORD and fh.isSet(f.RECORD.value) then
			if f.OCCU and f.OCCU.value:len() > 0 then
				local ptrFact
				if f.DECEASED and f.DECEASED.value then
					ptrFact = fh.createFact(
						f.RECORD.value,
						'OCCU',
						nil,
						beforeDate(eventDate),
						nil,
						f.OCCU.value
					)
				else
					ptrFact = fh.createFact(
						f.RECORD.value,
						'OCCU',
						nil,
						eventDate,
						nil,
						f.OCCU.value
					)
				end
				if ptrFact then
					addCitation(ptrFact, 'Added')
				end
			end
			if f.DECEASED and f.DECEASED.value then
				local ptrFact = fhGetItemPtr(f.RECORD.value, '~.DEAT')
				local sAction = 'Added'
				local deathdate = utils.choose(
					data.reg.DATE.value:IsNull(),
					beforeDate(eventDate),
					beforeDate(data.reg.DATE.value)
				)
				if ptrFact:IsNotNull() then
					ptrFact, sAction = fh.createUpdateFact(
						f.RECORD.value,
						'DEAT',
						'Death',
						nil,
						deathdate,
						nil
					)
				else
					ptrFact = fh.createFact(f.RECORD.value, 'DEAT', nil, deathdate, nil)
				end
				if ptrFact then addCitation(ptrFact, sAction) end
			end
			if f.PLAC and f.PLAC.value:len() > 0 then
				local ptrFact, sAction = fh.createFact(
					f.RECORD.value,
					'RESI',
					f.PLAC.value,
					eventDate,
					f.ADDR.value
				)
				if ptrFact then
					addCitation(ptrFact, 'Added')
				end
			end
			if
				f.MARRIAGEDATE
				and not (f.MARRIAGEDATE.value:IsNull())
				and not (ptrfamC:IsNull())
			then --create marriage event
				processMarriage(
					ptrfamC,
					f.MARRIAGEPLACE.value,
					f.MARRIAGEADDRESS.value,
					f.MARRIAGEDATE.value
				)
			end
			if
				k == 'mother'
				and f.RECORD.value:IsNotNull()
				and fh.isSet(f.MAIDEN_NAME.value)
			then
				local surname = fh.getSurname(
					fhGetItemText(f.RECORD.value, '~.NAME:STORED')
				)
				local maiden = fh.getSurname(f.MAIDEN_NAME.value)
				if surname:upper() ~= maiden:upper() then
					if
						fh.yes(
							'Update Mothers Surname from '
								.. surname:upper()
								.. ' to '
								.. maiden:upper()
						)
					then
						local mothersName = fhGetItemText(f.RECORD.value, '~.NAME:STORED')
						mothersName = stringx.replace(
							mothersName,
							'/' .. surname .. '/',
							'/' .. maiden .. '/'
						)
						local ptrName = fhGetItemPtr(f.RECORD.value, '~.NAME')
						if ptrName:IsNotNull() then
							fhSetValueAsText(ptrName, mothersName)
							if f.ACTION and f.ACTION.value ~= 'create' then
								addCitation(ptrName, 'Updated')
							end
						end
					end
				end
			end
		end
	end

	--  local fields = {}
	for k, s in pairs(form) do
		for i, f in ipairs(s.fields) do
			local inx = string.upper(k .. '.' .. tostring(f.tag))
			fields[inx] = fh.getParamValueForDisplay(f)

			if f.tag == 'NAME' and data[k].RECORD then
				local ptr = data[k].RECORD.value
				if ptr:IsNotNull() then
					-- Add record link
					fields[inx] = fh.richTextRecordLink(ptr, fields[inx])
				end
			end
		end
	end
	if fields['INFORMANT.RELATIONSHIP'] == 'Other' then
		fields['INFORMANT.RELATIONSHIP'] = fields['INFORMANT.OTHER']
	end

	-- Add prefix if the maiden name field has a value
	if fields['MOTHER.MAIDEN_NAME']:strip() ~= '' then
		if sRegionName == 'Scotland' then
			fields['MOTHER.MAIDEN_NAME'] = 'Maiden name\n'
				.. fields['MOTHER.MAIDEN_NAME']
		else
			fields['MOTHER.MAIDEN_NAME'] = 'formerly\n'
				.. fields['MOTHER.MAIDEN_NAME']
		end
	end
	--Add prefix if residence of one or other parent is defined
	if fields['MOTHER.ADDR']:strip() ~= '' then
		fields['MOTHER.ADDR'] = 'at ' .. fields['MOTHER.ADDR']
	elseif fields['MOTHER.PLAC']:strip() ~= '' then
		fields['MOTHER.PLAC'] = 'at ' .. fields['MOTHER.PLAC']
	end
	if fields['FATHER.ADDR']:strip() ~= '' then
		fields['FATHER.ADDR'] = 'at ' .. fields['FATHER.ADDR']
	elseif fields['FATHER.PLAC']:strip() ~= '' then
		fields['FATHER.PLAC'] = 'at ' .. fields['FATHER.PLAC']
	end
	if fields['FATHER.DECEASED']:strip() ~= '' then
		fields['FATHER.OCCU'] = fields['FATHER.OCCU'] .. ' (deceased)'
	end
	if fields['MOTHER.DECEASED']:strip() ~= '' then
		fields['MOTHER.OCCU'] = fields['MOTHER.OCCU'] .. ' (deceased)'
	end

	if sRegionName == 'Scotland' then
		fields['PRINCIPAL.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
		fields['BIRTH.DAY'] = dtEventDate:GetDisplayText 'DAY'
		fields['BIRTH.MONTH'] = dtEventDate:GetDisplayText 'MONTH_NAME'
		fields['BIRTH.YEAR'] = dtEventDate:GetDisplayText 'YEAR'
		if not form.reg.fields[7].value:IsNull() then
			fields['REG.YEAR'] = form.reg.fields[7].value:GetDisplayText 'YEAR'
			fields['REG.DAY'] = form.reg.fields[7].value:GetDisplayText 'DAY'
			fields['REG.MONTH'] = form.reg.fields[7].value:GetDisplayText 'MONTH_NAME'
		end
		if fields['REG.DISTRICT']:strip() ~= '' then -- add prefix to Registration district
			fields['REG.DISTRICT'] = 'at ' .. fields['REG.DISTRICT']
		end
		if not form.mother.fields[6].value:IsNull() then
			fields['MOTHER.MARRIAGEYEAR'] =
				form.mother.fields[6].value:GetDisplayText 'YEAR'
			fields['MOTHER.MARRIAGEDAY'] =
				form.mother.fields[6].value:GetDisplayText 'DAY'
			fields['MOTHER.MARRIAGEMONTH'] =
				form.mother.fields[6].value:GetDisplayText 'MONTH_NAME'
		end
	end

	sText = fh.formatTextFromSource(templateName, templateDefault, pCite, fields)
	fh.createTextFromSource(pCite, sText, 'source')

	fh.outputUpdatedFields(tUpdatedFields, pCite)
end

function beforeDate(dt)
	local newDate = fhNewDate()
	if dt:IsNull() then
		return
	end
	dp = dt:GetDatePt1()
	if dp:IsNull() then
		return
	end
	newDate:SetRange('before', dp)
	return newDate
end

function addCitation(ptr, action)
	local action = action or ''
	table.insert(tUpdatedFields, { ptr:Clone(), action })
	pCite:appendCitation(ptr)
end

function processParents(ptrFather, ptrMother, ptrChild)
	local ptrFamC = fhNewItemPtr()
	local ptrFam = fhNewItemPtr()
	local ptrHusb = fhNewItemPtr()
	local ptrWife = fhNewItemPtr()
	local bFamc = false
	ptrFamC:MoveTo(ptrChild, '~.FAMC')
	while ptrFamC:IsNotNull() do
		ptrHusb:MoveTo(ptrFamC, '~>HUSB>')
		ptrWife:MoveTo(ptrFamC, '~>WIFE>')
		if
			ptrHusb:IsSame(ptrFather)
			and (ptrWife:IsSame(ptrMother) or ptrWife:IsNull())
		then
			ptrFam:MoveTo(ptrFamC, '~>')
			bFamc = true
		elseif
			ptrWife:IsSame(ptrMother)
			and (ptrHusb:IsSame(ptrFather) or ptrHusb:IsNull())
		then
			ptrFam:MoveTo(ptrFamC, '~>')
			bFamc = true
		end
		ptrFamC:MoveNext 'SAME_TAG'
	end
	-- Check if selected people already married
	if not bFamc then
		local ptrChk = fhGetItemPtr(ptrFather, '~.FAMS')
		local ptrWifeChk = fhNewItemPtr()
		while ptrChk:IsNotNull() do
			ptrWifeChk:MoveTo(ptrChk, '~>WIFE>')
			if ptrWifeChk:IsSame(ptrMother) then
				ptrFam:MoveTo(ptrChk, '~>')
			end
			ptrChk:MoveNext 'SAME_TAG'
		end
		if ptrFam:IsNotNull() then
			fh.addFamilyAsChild(ptrChild, ptrFam)
		end
	end
	if ptrFather:IsNotNull() or ptrMother:IsNotNull() then
		if ptrFam:IsNull() then
			ptrFam = fh.createFamilyAsChild(ptrChild)
			addCitation(ptrFam, 'Created')
		end
		if fhGetItemPtr(ptrFam, '~.HUSB>'):IsNull() and ptrFather:IsNotNull() then
			fh.addFamilyAsSpouse(ptrFather, ptrFam)
		end
		if fhGetItemPtr(ptrFam, '~.WIFE>'):IsNull() and ptrMother:IsNotNull() then
			fh.addFamilyAsSpouse(ptrMother, ptrFam)
		end
	end
	return ptrFam
end
function processMarriage(ptrFam, sPlace, sAddress, ptrDate)
	if ptrFam:IsNotNull() then
		local ptrMARR = fhGetItemPtr(ptrFam, '~.MARR')
		local sAction
		if ptrMARR:IsNotNull() then
			ptrMARR, sAction = fh.createUpdateFact(
				ptrFam,
				'MARR',
				'Marriage',
				sPlace,
				ptrDate,
				sAddress
			)
			if ptrMarr then
				addCitation(ptrMARR, sAction)
			end
		else
			ptrMARR = fh.createFact(ptrFam, 'MARR', sPlace, ptrDate, sAddress)
			if ptrMarr then
				addCitation(ptrMARR, 'Added')
			end
		end
	end
end
function ptrDescription(ptr)
	local strDesc = ''
	local strTag = fhGetTag(ptr)
	if not (fhHasParentItem(ptr)) then
		strDesc = 'Record (' .. fhGetTag(ptr) .. ')'
	else
		local strTitle = string.match(fhGetDisplayText(ptr), '([%a%w%s]*):')
		if not strTitle then
			strTitle = string.match(fhGetDisplayText(ptr), '(%a*)')
		end
		strDesc = strTitle .. ' (' .. strTag .. ')'
	end
	return strDesc
end

function selectOrCreate(value)
	if value == 'select' then
		return false, 1
	else
		return true, 0
	end
end

function selectOrCreatePrincipal()
	if value == 'select' then
		return false, 1
	else
		-- data.principal.SEX.protect = false
		return true, 0
	end
end

function updateFamList(ptr)
	local ptrs = { fhNewItemPtr() }
	local prompts = { 'New Family As Child' }
	if fh.isSet(ptr) then
		local famList = fh.familyList(ptr, 'FamilyAsChild')
		for i, tFam in ipairs(famList) do
			table.insert(ptrs, tFam.ptr)
			table.insert(prompts, tFam.label)
		end
	end
	return ptrs, prompts
end

function field(fields, tag)
	local i
	for i, v in ipairs(fields) do
		if tag == v.tag then
			return i
		end
	end
end

function updateAddressList(...)
	args = { ... }
	print ',,,'
end

function loadMasterForms()
	ptrFamily = fhNewItemPtr()
	local masterForms = {}
	masterForms['England and Wales'] = {
		templateName = 'Birth Certificate (England and Wales).ftf',
		templateDefault = [[Birth certificate {NM-PRINCIPAL} {DT-DATE}

Certified Copy of an entry of Birth given at {REG.LOCATION} Registration District {REG.DISTRICT} in sub-district of {REG.SUB} in the county of {REG.PLAC}



 When and Where born | Name if any | Sex | Name and surname of Father | Name, Surname and maiden name of Mother | Occupation of Father | Signature, description and residence of informant | When Registered | Signature of Registrar | Name entered after registration 
 {DT-DATE}

{AD-ADDRESS}
{PL-LOCATION} | {PRINCIPAL.NAME} | {PRINCIPAL.SEX} | {FATHER.NAME} | {MOTHER.NAME}
{MOTHER.OCCU}
{MOTHER.ADDR}
{MOTHER.PLAC}
{MOTHER.MAIDEN_NAME} | {FATHER.OCCU}
{FATHER.ADDR}
{FATHER.PLAC} | {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}
{INFORMANT.ADDR}
{INFORMANT.PLAC} | {REG.DATE} | {REG.NAME} | {REG.AFTER} 

]],
		sections = {
			reg = {
				fields = {
					{
						tag = 'LOCATION',
						type = 'STRING',
						label = 'Registry',
						value = 'General Register Office',
					},
					{
						tag = 'DISTRICT',
						type = 'STRING',
						label = 'District',
						value = '',
					},
					{
						tag = 'SUB',
						type = 'STRING',
						label = 'Sub-District',
						value = '',
					},
					{ tag = 'PLAC', type = 'STRING', label = 'County of', value = '' },
					{
						tag = 'NAME',
						type = 'STRING',
						label = 'Registrars Name',
						value = '',
					},
					{
						tag = 'AFTER',
						type = 'STRING',
						label = 'Name Entered After Registration',
						value = '',
					},
					{
						tag = 'DATE',
						type = 'DATE',
						label = 'Registration Date',
						value = fhNewDate(),
					},
				},
				title = 'Registration Information',
				label = 'principal',
				seq = 1,
				active = true,
			},
			principal = {
				fields = {
					{
						tag = 'NAME',
						label = 'Name',
						type = 'STRING',
						dr = 'NAME',
						value = pCite:getValue 'NM-PRINCIPAL',
						minlength = 1,
						protect = true,
					},
					{
						tag = 'ACTION',
						label = 'Add principal as',
						type = 'LIST',
						value = 'create',
						values = { 'create', 'select' },
						prompts = { 'Create New Record', 'Use Existing Record' },
						child = 'RECORD',
						childUpdate = function(...)
							return selectOrCreate(...)
						end,
					},
					{
						tag = 'RECORD',
						label = 'Record',
						type = 'RECORD',
						dr = 'PTR',
						value = fhNewItemPtr(),
						protect = true,
						child = 'FAMILY',
						childUpdate = function(...)
							return updateFamList(...)
						end,
					},
					{
						tag = 'FAMILY',
						label = 'Family',
						type = 'LIST',
						value = ptrFamily,
						values = { ptrFamily },
						prompts = { 'New Family as Child' },
					},
					{
						tag = 'SEX',
						type = 'LIST',
						label = 'Sex',
						dr = 'SEX',
						value = 'Male',
						values = { 'Male', 'Female', 'Unknown' },
					},
					{ tag = 'BIRT', dr = 'BIRT' },
				},
				title = 'Principal',
				label = 'principal',
				seq = 2,
				active = true,
				gridDisplay = true,
			},
			father = {
				fields = {
					{
						tag = 'NAME',
						label = 'Name',
						type = 'STRING',
						dr = 'NAME',
						value = '',
						minlength = 1,
						gridDisplay = true,
					},
					{
						tag = 'ACTION',
						label = 'Add father as',
						type = 'LIST',
						value = 'name',
						values = { 'name', 'create', 'select' },
						prompts = {
							'Name Only',
							'Create New Record',
							'Use Existing Record',
						},
						child = 'RECORD',
						childUpdate = selectOrCreate,
					},
					{
						tag = 'RECORD',
						label = 'Record',
						type = 'RECORD',
						recordtype = 'INDI',
						value = fhNewItemPtr(),
						protect = true,
					},
					{
						tag = 'OCCU',
						dr = 'OCCU',
						type = 'STRING',
						label = 'Occupation',
						value = '',
					},
					{
						tag = 'DECEASED',
						type = 'BOOLEAN',
						label = 'Deceased',
						value = false,
					},
					{
						tag = 'PLAC',
						type = 'STRING',
						label = 'Residence Place',
						dr = 'RESI.PLAC',
						value = '',
						child = 'ADDR',
						childUpdate = function(place)
							return fh.createAddressList(place)
						end,
					},
					{
						tag = 'ADDR',
						type = 'STRING',
						label = 'Residence Address',
						dr = 'RESI.ADDR',
						value = '',
					},
					{ tag = 'SEX', value = 'Male' },
				},
				title = 'Father of principal',
				seq = 3,
			},
			mother = {
				fields = {
					{
						tag = 'NAME',
						label = 'Name',
						type = 'STRING',
						dr = 'NAME',
						value = '',
						minlength = 1,
						gridDisplay = true,
					},
					{
						tag = 'MAIDEN_NAME',
						label = 'Maiden Surname',
						type = 'STRING',
						value = '',
						gridDisplay = true,
					},

					{
						tag = 'ACTION',
						label = 'Add mother as',
						type = 'LIST',
						value = 'create',
						values = { 'name', 'create', 'select' },
						prompts = {
							'Name Only',
							'Create New Record',
							'Use Existing Record',
						},
						child = 'RECORD',
						childUpdate = selectOrCreate,
					},
					{
						tag = 'RECORD',
						label = 'Record',
						type = 'RECORD',
						recordtype = 'INDI',
						value = fhNewItemPtr(),
						protect = true,
					},
					{
						tag = 'OCCU',
						dr = 'OCCU',
						type = 'STRING',
						label = 'Occupation',
						value = '',
					},
					{
						tag = 'DECEASED',
						type = 'BOOLEAN',
						label = 'Deceased',
						value = false,
					},
					{
						tag = 'PLAC',
						type = 'STRING',
						label = 'Residence Place',
						dr = 'RESI.PLAC',
						value = '',
						child = 'ADDR',
						childUpdate = function(place)
							return fh.createAddressList(place)
						end,
					},
					{
						tag = 'ADDR',
						type = 'STRING',
						label = 'Residence Address',
						dr = 'RESI.ADDR',
						value = '',
					},
					{ tag = 'SEX', value = 'Female' },
				},
				title = 'Mother of principal',
				seq = 4,
			},
			informant = {
				fields = {
					{
						tag = 'NAME',
						label = 'Name',
						type = 'STRING',
						dr = 'NAME',
						value = '',
						minlength = 1,
					},
					{
						tag = 'RELATIONSHIP',
						label = 'Relationship',
						type = 'LIST',
						value = '',
						values = { 'Father', 'Mother', 'Other' },
						minlength = 1,
					},
					{
						tag = 'OTHER',
						label = 'Relationship (Other)',
						type = 'STRING',
						value = '',
					},
					{
						tag = 'ACTION',
						label = 'Add informant as',
						type = 'LIST',
						value = 'name',
						values = { 'name', 'create', 'select' },
						prompts = {
							'Name Only/Parent',
							'Create New Record',
							'Use Existing Record',
						},
						child = 'RECORD',
						childUpdate = selectOrCreate,
					},
					{
						tag = 'RECORD',
						label = 'Record',
						type = 'RECORD',
						recordtype = 'INDI',
						value = fhNewItemPtr(),
						protect = true,
					},
					{
						tag = 'PLAC',
						type = 'STRING',
						label = 'Residence Place',
						dr = 'RESI.PLAC',
						value = '',
						child = 'ADDR',
						childUpdate = function(place)
							return fh.createAddressList(place)
						end,
					},
					{
						tag = 'ADDR',
						type = 'STRING',
						label = 'Residence Address',
						dr = 'RESI.ADDR',
						value = '',
					},
				},
				title = 'Informant',
				seq = 5,
			},
		},
	}
	masterForms['Scotland'] = tablex.deepcopy(masterForms['England and Wales'])
	masterForms['Scotland']['templateName'] = 'Birth Certificate (Scotland).ftf'
	masterForms['Scotland']['templateDefault'] =
		[[Birth {NM-PRINCIPAL} {DT-DATE}


 Surname and name (if given)
Name if altered after registration| When and Where born with hour of birth| Sex| Name, surname, and rank or profession of father | Name, and maiden surname
 of mother
Date and place of marriage| Signature, qualification and residence of informant, 
if out of the house in which the birth occurred| When and where registered and signature of registrar
 {PRINCIPAL.NAME}

{REG.AFTER}| {BIRTH.YEAR}
{BIRTH.MONTH}
{BIRTH.DAY}
{PRINCIPAL.TIME}

{AD-ADDRESS}
{PL-LOCATION}| {PRINCIPAL.SEX}| {FATHER.NAME}

{FATHER.OCCU}| {MOTHER.NAME}
{MOTHER.MAIDEN_NAME}

{MOTHER.MARRIAGEYEAR}
{MOTHER.MARRIAGEMONTH}
{MOTHER.MARRIAGEDAY}

{MOTHER.MARRIAGEPLACE}| {INFORMANT.NAME}
{INFORMANT.RELATIONSHIP}

{INFORMANT.ADDR}
{INFORMANT.PLAC}| {REG.YEAR}
{REG.MONTH}
{REG.DAY}

{REG.DISTRICT}

{REG.NAME}


The above particulars are extracted from a Register of births for the Parish of {REG.DISTRICT}
in the County of {REG.PLAC}

Given under the Seal of the {REG.LOCATION}
]]
	masterForms['Scotland']['sections']['reg']['fields'][1] = {
		tag = 'LOCATION',
		type = 'STRING',
		label = 'Registry',
		value = 'Registrar General for Scotland',
	}
	table.insert(
		masterForms['Scotland']['sections']['principal']['fields'],
		6,
		{ tag = 'TIME', type = 'STRING', label = 'Birth time', value = '' }
	)
	table.insert(
		masterForms['Scotland']['sections']['mother']['fields'],
		6,
		{
			tag = 'MARRIAGEDATE',
			type = 'DATE',
			label = 'Marriage Date',
			value = fhNewDate(),
		}
	)
	table.insert(
		masterForms['Scotland']['sections']['mother']['fields'],
		7,
		{
			tag = 'MARRIAGEPLACE',
			type = 'STRING',
			label = 'Marriage Place',
			value = '',
		}
	)
	table.insert(
		masterForms['Scotland']['sections']['mother']['fields'],
		8,
		{
			tag = 'MARRIAGEADDRESS',
			type = 'STRING',
			label = 'Marriage Address',
			value = '',
		}
	)

	masterForms['Ireland'] = tablex.deepcopy(masterForms['England and Wales'])
	masterForms['Ireland']['templateName'] = 'Birth Certificate (Ireland).ftf'
	--fields and template assumed same as E&W

	masterForms['Northern Ireland'] = tablex.deepcopy(
		masterForms['England and Wales']
	)
	masterForms['Northern Ireland']['templateName'] =
		'Birth Certificate (Northern Ireland).ftf'
	masterForms['Northern Ireland']['sections']['reg']['fields'][1] = {
		tag = 'LOCATION',
		type = 'STRING',
		label = 'Registry',
		value = 'General Register Office (Northern Ireland)',
	}
	--other fields and template assumed same as E&W

	masterForms['Isle of Man'] = tablex.deepcopy(masterForms['England and Wales'])
	masterForms['Isle of Man']['templateName'] =
		'Birth Certificate (Isle of Man).ftf'
	masterForms['Isle of Man']['sections']['reg']['fields'][1] = {
		tag = 'LOCATION',
		type = 'STRING',
		label = 'Registry',
		value = 'Civil Registry',
	}
	--other fields and template assumed same as E&W

	masterForms['Channel Islands'] = tablex.deepcopy(
		masterForms['England and Wales']
	)
	masterForms['Channel Islands']['templateName'] =
		'Birth Certificate (Channel Islands).ftf'
	masterForms['Channel Islands']['sections']['reg']['fields'][1] = {
		tag = 'LOCATION',
		type = 'LIST',
		label = 'Registry',
		value = '',
		values = {
			'The Superintendent Registrar',
			'HM Greffier',
			'The Greffier',
			'The Greffe',
		},
	}
	return masterForms
end

-------------------------------------------------------------------------------------------------------- Start Plugin
main()

Source:Record-Birth-Data-UK-5.fh_lua