Add GRO Source.fh_lua

--[[
@Title: Add GRO Source
@Author: Jane Taubman
@LastUpdated: 26 Feb 2019
@Version: 1.3
@Description: Add A GRO Index Source to an Event and optionally create the event and or set the fields.
Records the Selected Source in a Parameter file for each Project. If run without a project the source record will 
need to be selected each time.
1.1 Prevent error, when not able to use Project folder to store settings.
1.2 Add options to record Quality and Entry Date
1.3 Add option for 3 sources and the entry of Mothers maiden name and Age on Citation
]]
function main()
require("iuplua")
if fhGetAppVersion() > 5 then
   fhSetStringEncoding("UTF-8")
   iup.SetGlobal("UTF8MODE","YES")
   iup.SetGlobal("UTF8MODE_FILE","NO")
end

-- Set up Defaults
local period = {'Q1 Jan-Feb-Mar','Q2 Apr-May-Jun','Q3 Jul-Aug-Sep','Q4 Oct-Nov-Dec','January','February','March','April','May','June','July','August',
'September','October','November','December'}
local strPeriod = table.concat(period,'|')..'|'
local shortperiod = {'Q1','Q2','Q3','Q4','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'}
local PromptDialogStr =
[[%t
GRO Index Type: %l|Birth|Marriage|Death|
Year: %i
Quarter: %l|{strPeriod}
Registration District: %s
Reference: %s
Mothers Maiden Name (birth only): %s
Age at Death (death only): %s
Set Entry Date: %b
Set Quality: %l|None|Unreliable|Questionable|Secondary Evidence|Primary Evidence|'
Birth Source Number %i
Marriage Source Number %i
Death Source Number %i
]]
PromptDialogStr = PromptDialogStr:gsub('{strPeriod}',strPeriod)
-- Get Source from Last Time
parmfile = fhGetPluginDataFileName()
local pqual = 0
local pdate = 0

if file_exists(parmfile) then
    dofile(parmfile)

end
if psourceb == nil then 
	 fhMessageBox('Please select up to 3 sources, in the order Birth, Marriage,Death')
    -- Get Source Record to use.
    ptrList = fhPromptUserForRecordSel('SOUR',3)
    if #ptrList == 0 then
        fhMessageBox('Source Not Selected Click Ok to End')
        return
    else
        psourceb = fhGetRecordId(ptrList[1])
			if ptrList[2] then psourcem = fhGetRecordId(ptrList[2]) else psourcem = fhGetRecordId(ptrList[1]) end
			if ptrList[3] then psourced = fhGetRecordId(ptrList[3]) else psourced = fhGetRecordId(ptrList[1]) end
    end
end
ptype = 0
pqtr = 0
pdistrict = ''
pref,  pmother, page = '','',''
pyear = 0
events = {'BIRT','MARR','DEAT'}
GROType = {'Birth','Marriage','Death'}
tblA = {'Unreliable','Questionable','Secondary Evidence','Primary Evidence',''}
dtDate = fhNewDate()
-- Get Current Record if Available
ptrList = fhGetCurrentRecordSel('INDI')
if #ptrList == 1 then
    strName = 'Current Record:'..fhGetItemText(ptrList[1],'~.NAME'):gsub('%%','%%%%')..' ('..fhCallBuiltInFunction('LifeDates',ptrList[1])..')'
else
    strName = 'No record selected'
end
-- Get GRO Information
ret, ptype,pyear, pqtr,pdistrict,pref,pmother,page,pdate,pqual,psourceb, psourcem, psourced =
iup.GetParam("Add GRO Entry", param_action,
strName..PromptDialogStr,
ptype,pyear, pqtr,pdistrict,pref,pmother,page,pdate,pqual,psourceb, psourcem, psourced)
-- Check for Cancel
if not(ret) then
    return
end
-- Set Variables
event = ptype + 1
qtr = period[pqtr + 1]
ptrSource = fhNewItemPtr()
if event == 1 then psourceno = psourceb end
if event == 2 then psourceno = psourcem end
if event == 3 then psourceno = psourced end

ptrSource:MoveToRecordById('SOUR',psourceno)
if ptrSource:IsNull() then
    error('Source Not Found')
end
-- Record Source Record ID
if fhGetContextInfo('CI_APP_MODE') == 'Project Mode' then
    out = assert(io.open(parmfile, "wb"))
    out:write('psourceb = '..psourceb..'\n')
    out:write('psourcem = '..psourcem..'\n')
    out:write('psourced = '..psourced..'\n')
    out:write('psourceno = '..psourceno..'\n')

    out:write('pdate = '..pdate..'\n')
    out:write('pqual = '..pqual..'\n')
    assert(out:close())
end
-- Allocate to Current Record
if (ptype == 1) then
    ptrList = fhGetCurrentRecordSel('FAM')
    if #ptrList == 0 then
        ptrList = fhGetCurrentRecordSel('INDI')
        if #ptrList == 1 then
            ptrList = getFamS(ptrList[1])
        end
    end
    if #ptrList ~= 1 then
        ptrList = fhPromptUserForRecordSel('FAM',1)
    end
else
    ptrList = fhGetCurrentRecordSel('INDI')
    if #ptrList ~= 1 then
        ptrList = fhPromptUserForRecordSel('INDI',1)
    end
end
if #ptrList == 0 then
    error("No Record Selected - Process Aborted")
end
ptrEvent = fhNewItemPtr()
ptrField = fhNewItemPtr()

ptrEvent:MoveTo(ptrList[1],'~.'..events[event])
if ptrEvent:IsNull() then
    -- Create Event
    ptrEvent = fhCreateItem(events[event],ptrList[1])
end
ptrField:MoveTo(ptrEvent,'~.DATE')
if ptrField:IsNull() then
    ptrField = fhCreateItem('DATE',ptrEvent)
end
dtDate = fhGetValueAsDate(ptrField)
if dtDate:IsNull() then
    
    dtDate:SetValueAsText(shortperiod[pqtr + 1]..' '..pyear)
    fhSetValueAsDate(ptrField,dtDate)
end
ptrField:MoveTo(ptrEvent,'~.PLAC')
if ptrField:IsNull() then
    ptrField = fhCreateItem('PLAC',ptrEvent)
end

if fhGetValueAsText(ptrField) == '' then
	 pdistrict = promptPlace(pdistrict)
    fhSetValueAsText(ptrField,pdistrict)
	-- If Place was added,  add "Registration District" as the Address field
	ptrField:MoveTo(ptrEvent,'~.ADDR')
	if ptrField:IsNull() then
   	 ptrField = fhCreateItem('ADDR',ptrEvent)
	end
	if fhGetValueAsText(ptrField) == '' then
   	 fhSetValueAsText(ptrField,'Registration District')
	end
end
-- For Death Add age if entered

if event == 3 and page:len() > 0 then
ptrField:MoveTo(ptrEvent,'~.AGE')
if ptrField:IsNull() then
    ptrField = fhCreateItem('AGE',ptrEvent)
    fhSetValueAsText(ptrField,page)
end
end
-- Add Source
ptrCite = fhCreateItem('SOUR',ptrEvent)
fhSetValueAsLink(ptrCite,ptrSource)
ptrField = fhCreateItem('PAGE',ptrCite)
sourcepage = GROType[event]..' '..qtr..' '..pyear..' '..pdistrict..' '..pref
if event == 1 and pmother:len() > 1 then
	sourcepage = sourcepage..' Mothers Maiden Name: '..pmother
end
if event == 3 and page:len() > 0 then
	sourcepage = sourcepage..' Age: '..page
end

fhSetValueAsText(ptrField,sourcepage)
if pdate == 1 then
    -- Record Entry Date
    eDate = fhCallBuiltInFunction('today')
    eDate2 = fhNewDate()
    eDate2:SetSimpleDate(eDate)
    -- .SOUR[1].DATA.DATE
    ptrData = fhCreateItem('DATA',ptrCite)
    ptrDate = fhCreateItem('DATE',ptrData)
    fhSetValueAsDate(ptrDate,eDate2)
end
if pqual > 0 then
    -- SOUR[1].QUAY
    ptrQuay = fhCreateItem('QUAY',ptrCite)
    fhSetValueAsText(ptrQuay,tblA[pqual])
end
-- Check Data
ptrField:MoveTo(ptrEvent,'~.DATE')
strResult = fhCallBuiltInFunction('GetDataWarning',ptrField,1)
if strResult ~= '' then
    strButton = fhMessageBox(strResult..'\nDo you wish to undo the entry','MB_YESNO','MB_ICONEXCLAMATION')
    if strButton == "Yes" then
        error('Data Validation Failed')
    end
end
end

function file_exists(name)
    local f=io.open(name,"r")
    if f~=nil then io.close(f) return true
    else
        return false
    end
end

function getFamS(ptr)
    local famsList = {}
    local ptrFam = fhNewItemPtr()
    local ptrFamR = fhNewItemPtr()
    ptrFam:MoveTo(ptr,'~.FAMS')
    while ptrFam:IsNotNull() do
        ptrFamR = fhGetValueAsLink(ptrFam)
        table.insert(famsList,ptrFamR:Clone())
        ptrFam:MoveNext('SAME_TAG')
    end
    return famsList
end

function placelist(sSearch)
    local places = {}
    sSearch = sSearch:lower()
    pi = fhNewItemPtr() -- declare pointer
    pi:MoveToFirstRecord("_PLAC") -- and set to the first record.
    iCount = 0
    while pi:IsNotNull() do
        local placename = fhGetDisplayText(pi)
        local lowerplace = placename:lower()
        if lowerplace:find(sSearch) then
            iCount = iCount + 1
            
            places[iCount] = placename
        end
        pi:MoveNext()
    end
    table.sort(places)
    return places
end

function promptPlace(pdist)
    PlacePromptDialogStr =
[[Please select a place from the list or%t 
use the entry box to enter a Place name%t
Place name: %s
Place: %l|Use Place Above|!PLACES!|
]]
    local places = placelist(pdist)
    pplaces = table.concat(places, "|")
    pplaces = pplaces:gsub('%%','%%%%')
    PlacePromptDialogStr = PlacePromptDialogStr:gsub('!PLACES!',pplaces)
    ret, pdist,pplace =
    iup.GetParam("Select Placename", param_action,
    PlacePromptDialogStr,
    pdist,0)
    -- Check for Cancel
    if not(ret) then
        return pdist
    end
    if pplace > 1 then
        pdist = places[pplace]
    end
    return pdist
end
---------------------------------------------------------------Main Code
main()

Source:Add-GRO-Source-2.fh_lua