# Utilities2.tcl
# Copyright for URLibService (c) 1995 - 2026,
# by Gerald Banon. All rights reserved.

package provide dpi.inpe.br/banon/1998/08.02.08.56 2.1

# ----------------------------------------------------------------------
# DirectoryInfo
# Return the content size in bytes and the number of files of a directory and all its content 

if {[info tclversion] <= 8.3} {
	proc DirectoryInfo {dir {size 0} {numberOfFiles 0}} {
		set pwd [pwd]
		if ![file isdirectory $dir] {return "0 0"}
		if [catch {cd $dir} err] {
			puts stderr $err
			return
		}
#		set fileList [glob -nocomplain .* *]
#		set fileList [lrange $fileList 2 end]	;# drop . ..
		set fileList [glob -nocomplain -- * .?*]
		set index [lsearch -exact $fileList {..}]
		set fileList [lreplace $fileList $index $index]
		foreach file $fileList {
			catch {set size [expr $size + [file size $file]]} ;# sometimes (UNIX) file size doesn't work (ex: file size .#ltab.doc)
# problem with a file named:
# ~$unzip.doc
# we get the message:
# user "$unzip.doc" doesn't exist
# when running [file isdirectory $file]
# with $file == ~$unzip.doc
#
# this problem occurs with 8.0 and not with 8.3
# for that reason we put a catch
#			if [file isdirectory $file]
			if [catch {file isdirectory $file} isdirectory] {
				continue	;# ignore such file name
			}
#
			if $isdirectory {
				foreach {size numberOfFiles} [DirectoryInfo [file join $dir $file] $size $numberOfFiles] {break}
			} else {
				incr numberOfFiles
			}
		}
		cd $pwd
		return "$size $numberOfFiles"
	}
} else {
	proc DirectoryInfo {dir {size 0} {numberOfFiles 0}} {
		
		set pwd [pwd]
		if ![file isdirectory $dir] {return "0 0"}
		if [catch {cd $dir} err] {
			puts stderr $err
			return
		}
#		set fileList [glob -nocomplain *]	;# commented by GJFB on 2018-03-10
		set fileList [ComputeFileList]	;# added by GJFB on 2018-03-10 - to capture the hidden files of Linux as well - ComputeFileList was modified by GJFB on 2018-12-04 to exclude the file name .htaccess and .htaccess2
		if [string equal {utf-8} [encoding system]] {	;# same code as in DirectorySize
# try iso8859-1 - solves the accent problem in gprb0705, col/urlib.net/www/2012/01.31.12.33/doc contains a file which name (AvaliaçãoRadiograficaSilhuetaCardiacaYorkshireTerrier.pdf) was iso coded - added by GJFB on 2015-01-09
			set fileList2 {}
			foreach file $fileList {
				if [file exists $file] {lappend fileList2 $file}
			}
			encoding system iso8859-1
#			set fileList [glob -nocomplain *]	;# commented by GJFB on 2018-03-10
			set fileList [ComputeFileList]	;# added by GJFB on 2018-03-10 - to capture the hidden files of Linux as well - ComputeFileList was modified by GJFB on 2018-12-04 to exclude the file name .htaccess and .htaccess2
			set fileList3 {}
			foreach file $fileList {
				if [file exists $file] {lappend fileList3 $file}
			}
if 0 {
# commented by GJFB on 2021-01-17 - doesn't work in plutao, col/dpi.inpe.br/plutao/2012/11.28.17.36/doc contains a file which exists with different names (polizel_caracterização.pdf polizel_caracterizaÃ§Ã£o.pdf) in both encoding systems
			set fileList [concat $fileList2 $fileList3]
			encoding system utf-8
			set fileList [lsort -unique $fileList]
} else {
# added by GJFB on 2021-01-17
			encoding system utf-8
			if {[llength $fileList2] > [llength $fileList3]} {
				set fileList $fileList2
			} else {
				set fileList $fileList3
# => polizel_caracterizaÃ§Ã£o.pdf
			}
}
		} 
		foreach file $fileList {
			catch {set size [expr $size + [file size $file]]} ;# sometimes (UNIX) file size doesn't work (ex: file size .#ltab.doc)
# problem with a file named:
# ~$unzip.doc
# we get the message:
# user "$unzip.doc" doesn't exist
# when running [file isdirectory $file]
# with $file == ~$unzip.doc
#
# this problem occurs with 8.0 and not with 8.3
# for that reason we put a catch
#			if [file isdirectory $file]
			if [catch {file isdirectory $file} isdirectory] {
				continue	;# ignore such file name
			}
#
			if $isdirectory {
				foreach {size numberOfFiles} [DirectoryInfo [file join $dir $file] $size $numberOfFiles] {break}
			} else {
				incr numberOfFiles
			}
		}
		cd $pwd
		return "$size $numberOfFiles"
	}
}
if 0 {		
# testing
	source utilities1.tcl	;# ComputeFileList
	source utilities2.tcl
#	puts [DirectoryInfo c:/lixo]
#	puts [DirectoryInfo cgi]
#	puts [DirectoryInfo {c:/gerald/URLib 2/col/dpi.inpe.br/banon-pc2@1905/2005/06.30.19.31/doc}]
#	puts [DirectoryInfo {c:/users/geral/URLib 2/col/urlib.net/www/2012/05.14.22.52/doc}]
	puts [DirectoryInfo {c:/users/geral/URLib 2/col/iconet.com.br/banon/2004/10.01.18.19/doc}]
	puts [DirectoryInfo {/mnt/dados1/URLibLattes/col/dpi.inpe.br/plutao/2012/11.28.17.36/doc}]
}
# DirectoryInfo - end
# ----------------------------------------------------------------------
# FindFile
# inspired from Example 9-11
# Finding a file by name.
# Return the the file path

proc FindFile {filePathName startDir fileName} {
	upvar $filePathName filePath
	if [file exists [file join $startDir $fileName]] {
		set filePath [file join $startDir $fileName]
		return -code return
	}
	foreach file [glob -nocomplain [file join $startDir *]] {
		if [file isdirectory $file] {
			FindFile filePath [file join $startDir $file] \
				$fileName
		}
	}
}

# set filePath ""
# FindFile filePath C:/ netscape.exe
# puts $filePath
# => C:/Program Files/Netscape/Communicator/Program/netscape.exe

# FindFile - end
# ----------------------------------------------------------------------
# DirectoryNewer
# Return 1 if the directory content is newer than the referenceTime
# content
# referenceTime format is %Y:%m.%d.%H.%M.%S
# works with gmt

if {[info tclversion] <= 8.3} {
	proc DirectoryNewer {dir referenceTime} {
		global tcl_platform
		set pwd [pwd]
		if ![file isdirectory $dir] {return 1}
		if [catch {cd $dir} err] {
			puts stderr $err
			return
		}
		if {$tcl_platform(platform) == "unix"} {
			set mtime [clock format [file mtime $dir] -format %Y:%m.%d.%H.%M.%S] -gmt 1
		} else {
# set mtime to 0 because of UNZIP limitation for other platform
			set mtime 0
		}
		if {[string compare $mtime $referenceTime] > 0} {
			cd $pwd
			return 1
		}	
#		set fileList [glob -nocomplain .* *]
#		set fileList [lrange $fileList 2 end]	;# drop . ..
		set fileList [glob -nocomplain -- * .?*]
		set index [lsearch -exact $fileList {..}]
		set fileList [lreplace $fileList $index $index]
		foreach file $fileList {
			if [file isdirectory $file] {
				if [DirectoryNewer [file join $dir $file] \
					$referenceTime] {
					cd $pwd
					return 1
				}
			} else {
				set mtime [clock format [file mtime $file] -format %Y:%m.%d.%H.%M.%S] -gmt 1
				if {[string compare $mtime $referenceTime] > 0} {
					cd $pwd
					return 1
				}
			}	
		}
		cd $pwd
		return 0
	}
} else {
	proc DirectoryNewer {dir referenceTime} {
		global tcl_platform
		set pwd [pwd]
		if ![file isdirectory $dir] {return 1}
		if [catch {cd $dir} err] {
			puts stderr $err
			return
		}
		if {$tcl_platform(platform) == "unix"} {
			set mtime [clock format [file mtime $dir] -format %Y:%m.%d.%H.%M.%S] -gmt 1
		} else {
# set mtime to 0 because of UNZIP limitation for other platform
			set mtime 0
		}
		if {[string compare $mtime $referenceTime] > 0} {
			cd $pwd
			return 1
		}	
		set fileList [glob -nocomplain *]
		foreach file $fileList {
			if [file isdirectory $file] {
				if [DirectoryNewer [file join $dir $file] \
					$referenceTime] {
					cd $pwd
					return 1
				}
			} else {
				set mtime [clock format [file mtime $file] -format %Y:%m.%d.%H.%M.%S] -gmt 1
				if {[string compare $mtime $referenceTime] > 0} {
					cd $pwd
					return 1
				}
			}	
		}
		cd $pwd
		return 0
	}
}

# puts [clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]
# puts [DirectoryNewer \
c:/usuario/gerald/URLib/col/dpi.inpe.br/banon/1999/12.15.21.29/doc \
1999:01.28.16.44.39] 
# puts [DirectoryNewer \
c:/usuario/gerald/URLib/col/dpi.inpe.br/banon/1999/12.15.21.29/doc \
1999:12.27.22.33.01] 

# DirectoryNewer - end
# ----------------------------------------------------------------------
# Warning

proc Warning {program string {var1 {}} {var2 {}}} {
# runs with start
	upvar #0 {Text::URLibService} title
	toplevel .warning -borderwidth 10
	wm title .warning $title
	wm resizable .warning 1 0
	set bg [.warning cget -bg]
	set t [text .warning.text -wrap word -fg black \
		-relief flat -bg $bg]
	set font [lindex [lindex [$t configure -font] end] 0]
	$t configure -font {$font 10}
	pack $t -fill x	;# now -tabs is working properly
# insert dialog
#	eval [list ${program}ExtraDialog $t $string $var1 $var2]
	${program}ExtraDialog $t $string $var1 $var2
	ComputeGeometry .warning $t 2.8c .8c
	return .warning
}

# Warning - end
# ----------------------------------------------------------------------
# ProcessKeyForDialog

proc ProcessKeyForDialog {button underline key} {
# runs with start
	global returnDialog
	set ib [llength $button]	;# number of buttons
	incr ib -1
	set button0 [lindex $button 0] 
	upvar #0 Text::$button0 textButton0
	set underline0 [lindex $underline 0] 
	if {$underline0 >= 0} {
		set letter [string index $textButton0 $underline0]
		if [regexp -nocase $letter $key] {
			set returnDialog 0
			return
		}
	}
	if $ib {
		set button1 [lindex $button 1]
		upvar #0 Text::$button1 textButton1 
		set underline1 [lindex $underline 1] 
		if {$underline1 >= 0} {
			set letter [string index $textButton1 $underline1]
			if [regexp -nocase $letter $key] {
				set returnDialog 1
				return
			}
		}
	}
}

# ProcessKeyForDialog - end
# ----------------------------------------------------------------------
# DisplayText
# Example:
# DisplayText $entryWidget $entryName $varName .xxrepository #dddddd 1 0
#
# $entryName == spPreference or ddDirectory - used with the reload button
# $entryName == {} - not specified when the reload button is not used
# $varName == dd(result1)
# $w == .ddhelp or .xxdirectory
# $bg == #ffffcc
# create is 0 or 1; 0 means to don't create widget
# (just update if it exists) - used by the SetBackGround procedure,
# 1 means to create
# fill is 0 or 1; 0 means to don't fill widget
# (just to create it if it doesn't exist and create == 1) - used by the
# PerformCheck procedure (the fill will happen later through the
# call to the CompleteEntry procedure),
# 1 means to fill
# canvas values are 0 or 1
# 0 means to don't use canvas (just to pack Scrolled_Text)
# 1 means to use canvas
# close value is the close buttom name (Close or Cancel)
# reload value is the reload buttom name (Reload or OK)
# Examples:
# puts [list $entryWidget $entryName $varName $w $bg] 
# => .dd {} dd(ok) .ddhelp #ffffcc
# => .window.main.dd {} dd(ok) .ddhelp #ffffcc
# => .window.main.dd.rep.h1.h2.v2.entry.entry ddRepository dd(result2) .xxrepository #dddddd
#
# DisplayText .window.main.bc.rep.h2.entry.entry bcRepository bc(result1) .xxrepository #dddddd 1 1

proc DisplayText {
	entryWidget entryName varName win bg
	{create {1}} {fill {1}} {close {Close}}
	{reload {Check}} {canvas {0}} {rep {}} {metadataRep {}}
	{ref 1} {n 1} {buttonCursorState {}} {referenceType {}}
} {
# runs with start
	DisableButtons
	global w
	global bcChoice
	if [winfo exists $w.main.bc.button.reload.reload] {
		if {[string compare .bchelp $win] != 0} {
			$w.main.bc.button.reload.reload config -state disabled
			$w.main.bc.rep.label.lb1.lb1 config -fg #999999
			$w.main.bc.rep.label.lb2.lb2 config -fg #999999
			$w.main.bc.rep.label.lb3.lb3 config -fg #999999
			$w.main.bc.rep.label.lb4.lb4 config -fg #999999
#			$w.main.bc.button.reload.reload config -fg #000000	;# set back to black before computing if it should be red
			$w.main.bc.button.edit.edit config -state disabled
		}
	}
	
# puts $win
	if [winfo exists $win] {
		wm deiconify $win
		$win.f.t configure -state normal
#		$win.f.t delete 1.0 end
		$win.button.close.close config -state disabled
		$win.button.reload.reload config -state disabled
		set bclose $win.button.close
		set breload $win.button.reload
	} else {
		if !$create {
			ControlBCButtonState $entryWidget $entryName $varName
			EnableButtons
			return
		}
		toplevel $win
		set W [winfo width .window]
		set H [winfo height .window]
		if {1024 <= [winfo screenwidth .]} {
			set width 421
		} else {
			set width 317
		}
		wm geometry $win ${width}x$H+[expr $W + 7]+0
		if [regexp {help} $win] {set word Help}
		if {$win == ".xxdirectory"} {set word Check}
		if {$win == ".xxrepository"} {set word Check}
#		if {$win == ".bcmetadata"} {set word Edit}
#		if {$win == ".ddmetadata"} {set word Edit}
		if [regexp {metadata} $win] {set word Edit}
		upvar #0 "Text::URLibService - $word" varText

		if $canvas {
			global homePath
#			global referRepository	;# commented by GJFB on 2013-02-17
#			global ${referRepository}::conversionTable	;# commented by GJFB on 2013-02-17
			Load $homePath/col/$metadataRep/doc/@metadata.refer fileContent
			set localMetadataList [ConvertRefer2MetadataList $fileContent $metadataRep 0]
# puts $localMetadataList
			array set localMetadataArray $localMetadataList
			set currentType $localMetadataArray($metadataRep-0,referencetype)
			if [string equal {} $referenceType] {
				set referenceType $currentType
			}
			set extension " $ref/$n - $referenceType"
		} else {
			set rep {}
			set metadataRep {}
			set extension {}
		}

		wm title $win "$varText$extension"
		if [regexp {help} $win] {
			set word word
		} else {
			set word none
		}

		if $canvas {
			regexp {^..} $varName xx	;# dd
			frame $win.f
			frame $win.f.f1
			canvas $win.f.f1.canvas -width 10 -height 10 \
				-yscrollcommand [list $win.f.f1.yscroll set]
			scrollbar $win.f.f1.yscroll -orient vertical \
				-command [list $win.f.f1.canvas yview]

			pack $win.f.f1.yscroll -side right -fill y
			pack $win.f.f1.canvas -side left -fill both -expand true

			frame $win.f.sp1 -height .3c	;# extra space

			frame $win.f.f2 -borderwidth 2 -relief groove

			set width .88	;# inch
			set height 1.08	;# cm
			set bcChoice update

# update
			frame $win.f.f2.r1 -width [format "%si" $width] -height [format "%sc" $height]
			pack propagate $win.f.f2.r1 false
			pack $win.f.f2.r1 -side left
			radiobutton $win.f.f2.r1.1 -variable bcChoice -value update -cursor hand2
			ConfigText $win.f.f2.r1.1 {update}
			pack $win.f.f2.r1.1 -fill both -expand true

# add
			frame $win.f.f2.r2 -width [format "%si" $width] -height [format "%sc" $height]
			pack propagate $win.f.f2.r2 false
			pack $win.f.f2.r2 -side left
			radiobutton $win.f.f2.r2.1 -variable bcChoice -value add -cursor hand2
			ConfigText $win.f.f2.r2.1 {add}
			pack $win.f.f2.r2.1 -fill both -expand true

# remove
			frame $win.f.f2.r3 -width [format "%si" $width] -height [format "%sc" $height]
			pack propagate $win.f.f2.r3 false
			pack $win.f.f2.r3 -side left
			radiobutton $win.f.f2.r3.1 -variable bcChoice -value remove -cursor hand2
			ConfigText $win.f.f2.r3.1 {remove}
			pack $win.f.f2.r3.1 -fill both -expand true

			frame $win.f.sp2 -height .05c	;# extra space

			pack $win.f.f1 -side top -fill both -expand true
			if [string equal bc $xx] {
				pack $win.f.sp1 -side top
				pack $win.f.f2 -side top
				pack $win.f.sp2 -side top
			}

		} else {
			Scrolled_Text $win.f -wrap $word \
				-bg $bg -fg black -cursor double_arrow \
				-relief raised -borderwidth 2 -padx .2c -pady .2c
		}

# Buttons
# puts "$win $reload $close"
# => .xxmetadata1 OK Cancel
		frame $win.sp -height .04c ;# extra space
		set width 2.2
		set height .6
		set b [frame $win.button -width 5c -height .6c]
# Close Button
		set bclose [frame $b.close -width [format "%sc" $width] \
			-height [format "%sc" $height]]
		button $bclose.close \
			-command [list CloseDisplayText $entryWidget $entryName $varName $win \
				$rep $n $buttonCursorState] \
			-cursor hand2 -state disabled
		ConfigText $bclose.close $close
# Close Button - end
# Reload Button
		set breload [frame $b.reload -width [format "%sc" $width] \
			-height [format "%sc" $height]]
		button $breload.reload \
			-command [list ReloadDisplayText $entryWidget $entryName $varName $win \
				$rep $metadataRep $n $buttonCursorState $referenceType] \
			-cursor hand2 -state disabled
		ConfigText $breload.reload $reload
# Reload Button - end
		pack propagate $b false
		pack propagate $bclose false
		pack propagate $breload false

		if [regexp metadata $win] {
			pack $breload -side left
			pack $bclose -side right
		} elseif [regexp {xxdirectory|xxrepository} $win] {
# xx directory or xxrepository
			pack $breload -side left
			pack $bclose -side top
		} else {
			pack $bclose -side top
		}

		pack $bclose.close -fill both
		pack $breload.reload -fill both
		pack $b -side bottom -pady .2c
		pack $win.sp -side top	;# extra space
# Buttons - end
		pack $win.f -fill y -expand true
		bind $win <1> "ProcessButton1 $entryWidget"
	}
	if $canvas {
		Scrolled_EntrySet $win.f.f1.canvas $varName localMetadataArray \
		$metadataRep $currentType $referenceType \
		[ReturnReferModel $referenceType]
		$bclose.close configure -state normal
		$breload.reload config -state normal 
	} else {
# Fill Text
		if !$fill {
			ControlBCButtonState $entryWidget $entryName $varName
			EnableButtons
			return
		}
		regexp {.(...)(.*)} $win m first last	;# ddh elp
		set programName [string toupper $first]$last
		$programName $entryWidget $entryName $varName	;# DDHelp or XXDirectory or ...
# Fill Text - end
	}
	raise $win
#	$win.button.close.close configure -state normal
	if [regexp help $win] {
		$bclose.close configure -state normal
	}
}

# DisplayText - end
# ----------------------------------------------------------------------
# CloseDisplayText
# Examples:
# CloseDisplayText .window.main.bc.rep.h2.entry.entry bcRepository bc(result1) .xxmetadata1 dpi.inpe.br/banon/1999/09.12.15.10 1 {normal disabled {}}
# CloseDisplayText .window.main.dd.rep.h1.h2.v2.entry.entry ddRepository dd(result2) .xxmetadata1 {} 1 {{} {} {}}

proc CloseDisplayText {
	entryWidget entryName varName win 
	rep numberOfMetadata buttonCursorState
} {
	global editMetadataState
	
# puts [list $entryWidget $entryName $varName $win $rep $numberOfMetadata $buttonCursorState]
	if [regexp {^\.xxmetadata} $win] {
		upvar #0 $varName var
		$win.button.reload.reload config -state disabled
		$win.button.close.close config -state disabled
		regexp {^..} $varName xx	;# dd
		for {set i 1} {$i <= $numberOfMetadata} {incr i} {
			if [string equal $win .xxmetadata$i] {continue} 
			if [winfo exists .xxmetadata$i] {
				destroy $win
				return
			}
		}
# no more Edit Metadata Window exists
		if $editMetadataState {PerformCheck $entryWidget $entryName $varName}
		if ![string equal {} $rep] {
			RestoreBCButtons $entryName
		}
		UnsetWaitingState $entryWidget $xx $buttonCursorState
	}
	if [regexp {^\.bchelp|^\.xxmetadata} $win] {
		ControlBCButtonState $entryWidget $entryName $varName
	}
	destroy $win
	if ![regexp {^\.sphelp} $win] {	;# added by GJFB on 2021-11-07 - closing Help window should not change the state of the buttons
		EnableButtons
	}	
}

# CloseDisplayText - end
# ----------------------------------------------------------------------
# ReloadDisplayText

proc ReloadDisplayText {
	entryWidget entryName varName win 
	rep metadataRep numberOfMetadata buttonCursorState referenceType
} {
	global homePath
	global editMetadataState
	global bcChoice
	global log
	global multipleLineReferFieldNamePattern
	global authorFieldNameList
	global fieldAttributeTable

	if [regexp {^\.xxdirectory|^\.xxrepository} $win] {
#		PerformCheck $entryWidget $entryName $varName	;# reload
		PerformCheck $entryWidget $entryName $varName 0	;# check
	}
	if [regexp {^\.xxmetadata} $win] {
		upvar #0 $varName var
		set editMetadataState 1
		$win.button.reload.reload config -state disabled
		$win.button.close.close config -state disabled
		regexp {^..} $varName xx	;# dd
		foreach field [ReturnReferModel $referenceType 1] {
			set fieldName [lindex $field 0]	;# %A
			set field1 [lindex $field 1]	;# author
# drop some fields
#			if {[string compare {%@parentrepositories} $fieldName] == 0} {continue}
			if {[info exists fieldAttributeTable($field1,5)] && $fieldAttributeTable($field1,5)} {continue}
#			if [regexp {^%A|^%E|^%Y|^%\?|^%@group|^%@affiliation|^%@electronicmailaddress} $fieldName] #
			if [regexp $multipleLineReferFieldNamePattern $fieldName] {
# multiple line fields
#				set fieldValue [string trim [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]
				set fieldValue [string trimright [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]	;# uncommented by GJFB on 2012-04-21 - trim below for empty fieldValue doesn't exempt this trimright
#				set fieldValue [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end]	;# commented by GJFB on 2012-04-21
#				ProcessAuthorField fieldList $fieldName $fieldValue
				if {[lsearch $authorFieldNameList $field1] != -1} {
# author editor...
					ProcessAuthorField fieldList $fieldName $fieldValue
				} else {
# program receiver resumeid orcid group affiliation secondarymark...
# puts "$fieldName = $fieldValue"
# puts 1-$fieldList
					ProcessMultipleLineField fieldList $fieldName $fieldValue
# puts 2-$fieldList
				}
			} elseif {[regexp {^%T|^%1} $fieldName]} {
				set fieldValue [string trim [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]
#				regsub -all {\$([^ ])} $fieldValue {$ \1} fieldValue	;# cr$30 -> cr$ 30	;# commented by GJFB on 2018-06-14 - now 30 (in $30) is no more treated as a tcl variable when displayed (see EscapeUntrustedData)
				ProcessTitleField fieldList $fieldName $fieldValue
			} elseif {[regexp {^%K} $fieldName]} {
				set fieldValue [string trim [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]
				ProcessKeywordsField fieldList $fieldName $fieldValue
			} elseif {[regexp {^%X} $fieldName]} {
				set fieldValue [string trim [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]
#				regsub -all {\$([^ ])} $fieldValue {$ \1} fieldValue	;# cr$30 -> cr$ 30	;# commented by GJFB on 2018-06-14 - now 30 (in $30) is no more treated as a tcl variable when displayed (see EscapeUntrustedData)
				ProcessAbstractField fieldList $fieldName $fieldValue
			} elseif {[regexp {^%0} $fieldName]} {
				lappend fieldList [list $fieldName $referenceType]
			} elseif {[regexp {^%2} $fieldName]} {
				lappend fieldList [list $fieldName $metadataRep]
			} elseif {[regexp {^%4} $fieldName]} {
				lappend fieldList [list $fieldName $rep]
			} else {
				set fieldValue [string trim [$win.f.f1.canvas.f.entry$fieldName.text.t get 1.0 end] \n]
				if [string equal {} $fieldValue] {continue}
				lappend fieldList [list $fieldName $fieldValue]
			}
		}
# puts $fieldList
#		set fileContent [join $fieldList \n]
		foreach field $fieldList {
			set fieldName [lindex $field 0]
			if [regexp $multipleLineReferFieldNamePattern $fieldName] {
# multiple line fields
				foreach fieldValue [lindex $field 1] {
					append fileContent [string trim "$fieldName $fieldValue"]\n	;# trim is useful when fieldValue is empty
				}
			} else {
				append fileContent [string trim [join $field]]\n	;# trim is useful when fieldValue is empty
			}
		}
	
# puts $fileContent
# puts --$metadataRep--

# update
		if {[info exists bcChoice] && [string equal update $bcChoice]} {
			Store fileContent $homePath/col/$metadataRep/doc/@metadata.refer
		}
# add
		if {[info exists bcChoice] && [string equal add $bcChoice]} {
			Store fileContent $homePath/clipboard/@metadata.refer
			CreateRepMetadataRep directory $homePath/col/$metadataRep/doc/
		}
# remove
		if {[info exists bcChoice] && [string equal remove $bcChoice]} {
# Compute the log
			LogInsert [list [list Insert $log end {new line}]] 1 0	;# blk line
			LogInsert [list [list Insert $log end \
				{deleting repository <$var1> ...} \
				{} $metadataRep] \
				[list TagAdd $log fixed9 \
				{<$var1>} -forward $metadataRep]] 0 0
			LogInsert [list [list Insert $log insert {new line}]] 0 1
# Compute the log - end

			CleanCollection $metadataRep
			
			set metadata2List [Eval GetMetadata $metadataRep-*]	;# extract from the global array: metadataArray
#			Eval RemoveMetadata $metadata2List 1	;# metadata2List must not be too big, otherwise Eval doesn't return - commented by GJFB on 2020-08-18
			Eval RemoveMetadata2 $metadata2List 1	;# added by GJFB on 2020-08-18

# Update file service/metadataRepositoryList
# added by GJFB on 2015-12-15 in order to have the names of the metadata repositories in the proper original repository - useful when one need to rescue a metadata repository from backup
			set metadataRepList [FindMetadataRepList $rep $entryWidget $varName]
# puts --$metadataRepList--
			set fileContent [join $metadataRepList \n]
			StoreService fileContent $rep metadataRepositoryList 0 1
# Update file service/metadataRepositoryList - end

# Compute the log
			LogInsert [list [list Insert $log end {new line}]] 1 0	;# blk line
			LogInsert [list [list Insert $log end \
				{repository <$var1> deleted} \
				{} $metadataRep] \
				[list TagAdd $log fixed9 \
				{<$var1>} -forward $metadataRep]] 0 0
			LogInsert [list [list Insert $log insert {new line}]] 0 1
# Compute the log - end
		}

#		if [info exists bcChoice] {unset bcChoice}	;# bcChoice is used by CreateRepMetadataRep - commented by GJFB on 2015-12-19 - leaves the radio buttons undefined when editing metadata
		set bcChoice update	;# bcChoice is used by CreateRepMetadataRep - set the default again - added by GJFB on 2015-12-19

		for {set i 1} {$i <= $numberOfMetadata} {incr i} {  
			if {[string compare $win .xxmetadata$i] == 0} {continue} 
			if [winfo exists .xxmetadata$i] {
				destroy $win
				return
			}
		}
# no more Edit Metadata Window exists
# >>> PerformCheck
		if ![string equal dd $xx] {PerformCheck $entryWidget $entryName $varName}
		if ![string equal {} $rep] {
			RestoreBCButtons $entryName
		}
		UnsetWaitingState $entryWidget $xx $buttonCursorState
		destroy $win
	}
}

# ReloadDisplayText - end
# ----------------------------------------------------------------------
# Scrolled_EntrySet

proc Scrolled_EntrySet {canvas varName arrayName metadataRep currentType referenceType fieldList} {
	global homePath
	global referRepository
	global ${referRepository}::conversionTable
	global tcl_platform
	global mirrorLanguageConversionTable
	global multipleLineReferFieldNamePattern
	global multipleLineReferFieldNamePatternForCreator
	global fieldAttributeTable

	upvar $arrayName localMetadataArray

	# Create one frame to hold everything
	# and position it on the canvas
	set f [frame $canvas.f -bd 0]
	$canvas create window 0 0 -anchor nw -window $f
	# Create and grid the labeled entries
	if {$tcl_platform(platform) == "windows"} {
		set width 50
	} elseif {$tcl_platform(os) == "SunOS"} {
		set width 36
	} else {
		set width 50
	}
	regexp {^..} $varName xx	;# dd
	if {[string compare bc $xx] == 0} {
		set height 6
	} else {
		set height 7
	}

# puts $fieldList
	foreach field $fieldList {
		set fieldName [lindex $field 0]	;# %A
		set label [lindex $field 1]	;# author
# drop some fields
#		if {[string compare {%@parentrepositories} $fieldName] == 0} {continue}
		if {[info exists fieldAttributeTable($label,5)] && $fieldAttributeTable($label,5)} {continue}
		set entry [frame $f.entry$fieldName -bd 2]
		label $entry.label -text $mirrorLanguageConversionTable($label)
		set scrolledText [Scrolled_Text $entry.text -width $width -height $height \
			-wrap word -padx 4 -bg #FFFFFF]
		grid $entry -sticky news
		grid $entry.label
		grid $entry.text
		if [info exists conversionTable($currentType,$fieldName)] {
			if [info exists localMetadataArray($metadataRep-0,$conversionTable($currentType,$fieldName))] {
				set fieldValue $localMetadataArray($metadataRep-0,$conversionTable($currentType,$fieldName))
			} else {
				set fieldValue {}
			}
		} else {
			set fieldValue {}
		}
#		if [regexp {^%A|^%E|^%Y|^%\?|^%@group|^%@affiliation|^%@electronicmailaddress} $fieldName] #
		if [regexp $multipleLineReferFieldNamePattern $fieldName] {
# multiple line fields
#			if [regexp {^%@group|^%@affiliation|^%@electronicmailaddress} $fieldName] #
			if ![regexp $multipleLineReferFieldNamePatternForCreator $fieldName] {
				set fieldValue [MultipleRegsub {,*$} $fieldValue {}] ;# drop trailing comma
			} else {
				set fieldValue [MultipleRegsub {(,.+),$|^([^ ]+),$} $fieldValue {\1\2}] ;# drop trailing comma
# xx, xx, -> xx, xx	(\1)
# xx xx, -> xx xx,
# xx, -> xx			(\2)
			}
			set fieldValue [join $fieldValue \n]
		}
		$scrolledText insert insert $fieldValue
	}

	set fieldName [lindex [lindex $fieldList 0] 0]
	set child $f.entry$fieldName

	# Wait for the window to become visible and then
	# set up the scroll region based on
	# the requested size of the frame, and set 
	# the scroll increment based on the
	# requested height of the widgets

	tkwait visibility $child
	set bbox [grid bbox $f 0 0]
	set incr [lindex $bbox 3]
	set width [winfo reqwidth $f]
	set height [winfo reqheight $f]
	$canvas config -scrollregion "0 0 $width $height"
	$canvas config -yscrollincrement $incr
#	set max [llength $fieldList]
#	if {$max > 10} {
#		set max 10
#	}
#	set height [expr $incr * $max]
#	$canvas config -width $width -height $height
	$canvas config -width $width
}

# Scrolled_EntrySet - end
# ----------------------------------------------------------------------
# Scrolled_Text
# Adapted form Example 27-1
# Text with one or two scrollbars.
#

proc Scrolled_Text {f args} {
# runs with start
	frame $f -borderwidth 2 -relief groove
	eval {text $f.t \
		-xscrollcommand [list $f.xscroll set] \
		-yscrollcommand [list $f.yscroll set]} $args
	scrollbar $f.xscroll -orient horizontal \
		-command [list $f.t xview]
	scrollbar $f.yscroll -orient vertical \
		-command [list $f.t yview]
	grid $f.t $f.yscroll -sticky news
	if ![regexp {help|entry} $f] {grid $f.xscroll -sticky news}
	grid rowconfigure $f 0 -weight 1
	grid columnconfigure $f 0 -weight 1
	return $f.t
}

# Scrolled_Text - end
# ----------------------------------------------------------------------
# Selector
# example:
# set aWhich [Selector $f.dir.h1.h2.v2 ddDirectory dd 1]
# flag == 1 <==> pack the check box
# flag == 0 <==> doesn't pack the check box

proc Selector {parent entryName varName index {listName {}} {flag {1}}} {
# runs with start
#	global environmentArray
	global typeTable	;# defined in DDDialog for example
	global w
#	upvar #0 ${varName}Search search
	upvar #0 $entryName xxEntry
	set type $typeTable($xxEntry)
#	regexp {\.[^.]*\.[^.]*} $parent parentLabel	;# .dd.dir
	regexp "(.*\.$varName\.\[^.\]*)" $parent m parentLabel	;# .dd.dir
	set side .6c	;# button size
	set side2 1.15c
	set a [frame $parent.entry -borderwidth 2 -bg gray \
		-relief sunken -height $side]
	frame $a.button1 -width $side -height $side
	frame $a.button2 -width $side -height $side
	frame $a.button3 -width $side -height $side
	frame $a.button4 -width $side -height $side
	frame $a.button5 -width $side -height $side
	frame $a.button6 -width $side -height $side
	button $a.button1.1 -text < \
		-font {-family courier -size 11 -weight normal} \
		-cursor hand2
#	if $search {$a.button1.1 configure -state disabled}
	menubutton $a.button2.2 -text > \
		-font {-family courier -size 11 -weight normal} \
		-cursor hand2 -relief raised -menu $a.button2.2.menu
	menubutton $a.button3.3 \
		-font {-size 9 -weight normal} \
		-cursor hand2 -relief raised -menu $a.button3.3.menu
	ConfigText $a.button3.3 S
	button $a.button4.4 -cursor hand2 \
		-font {-size 9 -weight normal}	;# Remove/Check
#		-font {times 9 roman}
	if [regexp {\.ent\.} $type] {
		ConfigText $a.button4.4 Remove
	} else {
		ConfigText $a.button4.4 C
	}
	button $a.button5.5 -cursor hand2 \
		-font {-size 9 -weight normal}	;# Reverse
	button $a.button6.6 -cursor hand2 \
		-font {-size 9 -weight normal}	;# Find
	if [regexp {\.rep\.} $type] {
		set bg [$w cget -bg]
		set nc [NewColor $w $bg]
		ConfigText $a.button5.5 Reverse
#		upvar #0 ${varName}Reverse$index reverse
		upvar #0 ${varName}Reverse reverse
		if $reverse {
# repository first
			$a.button5.5 configure -bg $nc
			$a.button6.6 configure -state disabled
		} else {
# key first
			$a.button5.5 configure -bg $bg
		}
		ConfigText $a.button6.6 Find
		upvar #0 ${varName}Search search
		if $search {
			$a.button6.6 configure -bg $nc
		} else {
			$a.button6.6 configure -bg $bg
		}
	}
	entry $a.entry -textvariable ${varName}(result$index) \
		-relief flat \
		-font {courier 9 roman}
# SET THE ENTRY
	SetEntry $a ${xxEntry}Entry $varName result$index
# SET THE ENTRY - end
# Close the window entry
	if [regexp {\.dir\.|\.rep\.} $parent] {
		upvar #0 ${varName}Choice$index choice
		if ![regexp {^dir|^rep} $choice] {
			DisableEntry $a ${varName}(result$index)
		}
	}
# Close the window entry - end
	menu $a.button2.2.menu -tearoff 0 \
		-font {courier 9 roman}
	menu $a.button3.3.menu -tearoff 1 \
		-font {courier 9 roman}
	$a.button1.1 configure \
		-command "ReduceEntry $a $entryName \
			${varName}(result$index)"
	if [regexp {\.ent\.} $type] {
		$a.button4.4 configure \
			-command "RemoveEntry $a $entryName \
				${varName}(result$index)"
	} else {
		$a.button4.4 configure -command "PerformCheck $a.entry \
				$entryName ${varName}(result$index) 0"
	}
	$a.button5.5 configure \
		-command "ReverseEntry $a $entryName $varName $index"
	$a.button6.6 configure \
		-command "SearchEntry $a $entryName $varName $index"
	pack propagate $a false
	pack $a.button1 -side left
	pack propagate $a.button1 false
	pack $a.button3 -side left
	pack propagate $a.button3 false
	pack $a.button2 -side left
	pack propagate $a.button2 false
	pack $a.entry -side left
	if $flag {
		pack $a.button4 -side right
		pack propagate $a.button4 false
	}
	if [regexp {\.rep\.} $type] {
		pack $a.button5 -side right
		pack $a.button6 -side right
		pack propagate $a.button5 false
		pack propagate $a.button6 false
	}
	pack $a.button1.1 -fill both
	pack $a.button2.2 -fill both
	pack $a.entry -fill both -expand true
	pack $a.button3.3 -fill both
	pack $a.button4.4 -fill both
	pack $a.button5.5 -fill both
	pack $a.button6.6 -fill both
	pack $a -side bottom -fill x -pady .47c
#	bind $a.entry <Key> \
		"CompleteEntry %W $entryName ${varName}(result$index) \
			{$listName} %A; break"
	bind $a.entry <Key> \
		"CompleteEntry %W $entryName ${varName}(result$index) \
			%A; break"
	bindtags $a.entry [list Entry $a.entry all]
	label $parentLabel.lb1 -bg #ffffcc -relief solid -borderwidth 1
	ConfigText $parentLabel.lb1 " Backward "
	label $parentLabel.lb2 -bg #ffffcc -relief solid -borderwidth 1
	ConfigText $parentLabel.lb2 " Forward "
	label $parentLabel.lb3 -bg #ffffcc -relief solid -borderwidth 1
	ConfigText $parentLabel.lb3 \
		" Select One of The Most Recent Entries "
	label $parentLabel.lb4 -bg #ffffcc -relief solid -borderwidth 1
	if [regexp {\.ent\.} $type] {
		ConfigText $parentLabel.lb4 " Remove the Current Entry "
	} else {
		ConfigText $parentLabel.lb4 " Check "
	}
	label $parentLabel.lb5 -bg #ffffcc -relief solid -borderwidth 1
	ConfigText $parentLabel.lb5 \
		" Reverse "
	label $parentLabel.lb6 -bg #ffffcc -relief solid -borderwidth 1
	ConfigText $parentLabel.lb6 \
		" Find "
	bind $a.button1 <Enter> \
		"DisplayMessage $parentLabel.lb1 $a nw 0 1 0 3"
	bind $a.button1 <Leave> "DeleteMessage"
	bind $a.button1.1 <Button> "DeleteMessage"
	bind $a.button2 <Enter> \
		"DisplayMessage $parentLabel.lb2 $a nw 0 1 $side2 3"
	bind $a.button2 <Leave> "DeleteMessage"
#	bind $a.button2.2 <Button> "DeleteMessage"
	bind $a.button3 <Enter> \
		"DisplayMessage $parentLabel.lb3 $a nw 0 1 $side 3"
	bind $a.button3 <Leave> "DeleteMessage"
#	bind $a.button3.3 <Button> "DeleteMessage"
	bind $a.button3.3 <Button> "CancelSearch $a $entryName \
		${varName}(result$index)"
	bind $a.button4 <Enter> \
		"DisplayMessage $parentLabel.lb4 $a ne 1 1 0 3"
	bind $a.button4 <Leave> "DeleteMessage"
	bind $a.button4.4 <Button> "DeleteMessage"
	bind $a.button5 <Enter> \
		"DisplayMessage $parentLabel.lb5 $a ne 1 1 -$side 3"
	bind $a.button5 <Leave> "DeleteMessage"
	bind $a.button5.5 <Button> "DeleteMessage"
	bind $a.button6 <Enter> \
		"DisplayMessage $parentLabel.lb6 $a ne 1 1 -$side2 3"
	bind $a.button6 <Leave> "DeleteMessage"
	bind $a.button6.6 <Button> "DeleteMessage"
#	regexp {\.([^.]*\.[^.]*)} $a m prefix	;# dd.dir
	regexp ".*\.($varName\.\[^.\]*)" $a m prefix	;# dd.dir
	bind $a.button1.1 <ButtonRelease-1> \
		"CallFocus $a; SetPostMenu ${prefix}PostMenu"
#	bind $a.button1.1 <Double-1> "ReduceEntry $a $entryName ${varName}(result$index) 1"
	bind $a.button1.1 <ButtonPress-3> "ReduceEntry $a $entryName ${varName}(result$index) 1"
	bind $a.button2.2 <ButtonPress-1> "CallFocus $a"
	bind $a.button2.2 <ButtonRelease-1> \
	"SetPostMenu ${prefix}PostMenu; SetPostponeReduceEntry ${prefix}PostponeReduceEntry"
#	bind $a.button3.3 <ButtonPress-1> "CallFocus $a"	;# doesn't work
#	bind $a.button3.3 <ButtonRelease-1> "CallFocus $a; SetPostponeReduceEntry ${prefix}PostponeReduceEntry"
	bind $a.button3.3 <ButtonRelease-1> "SelectPreviousEntries $a $prefix"
	bind $a.button3.3 <ButtonPress-3> "GetPreviousEntry $a $entryName $type \
					${varName}(result$index) $listName"
	bind $a.button4.4 <ButtonRelease-1> "CallFocus $a"
# puts [bindtags $a.button2.2]
# => $a.button2.2 Menubutton .dd all
# we need to change the order otherwise dd.dirPostMenu is set to
# 0 after to be set to 1
	set win .$varName	;# .dd
	bindtags $a.button2.2 [list $win Menubutton $a.button2.2 all]
#	bindtags $a.button3.3 [list $win Menubutton $a.button3.3 all]
	return $a
}

proc SetPostMenu {varName} {
	upvar #0 $varName var
	set var 1
}

proc SetPostponeReduceEntry {varName} {
	upvar #0 $varName var
	set var 1
}

proc SelectPreviousEntries {a prefix} {
#	if [winfo exists .window.main.bc.button.reload.reload] {
#		.window.main.bc.button.reload.reload config -fg #000000
#		.window.main.bc.rep.label.lb1.lb1 config -fg #999999
#		.window.main.bc.rep.label.lb2.lb2 config -fg #999999
#		.window.main.bc.rep.label.lb3.lb3 config -fg #999999
#		.window.main.bc.rep.label.lb4.lb4 config -fg #999999
#	}
	CallFocus $a
	SetPostponeReduceEntry ${prefix}PostponeReduceEntry
}

# Example:
# GetPreviousEntry .window.main.bc.rep.h2.entry bcRepository .rep. bc(result1) keyRepositoryList

proc GetPreviousEntry {widget entryName type varName listName} {
	global environmentArray
	global w
	if [winfo exists .window.main.bc.button.reload.reload] {
		.window.main.bc.button.reload.reload config -fg #000000
		.window.main.bc.rep.label.lb1.lb1 config -fg #999999
		.window.main.bc.rep.label.lb2.lb2 config -fg #999999
		.window.main.bc.rep.label.lb3.lb3 config -fg #999999
		.window.main.bc.rep.label.lb4.lb4 config -fg #999999
	}
	set bgColor [lindex [$widget.entry config -bg] end]
	if {$bgColor == "#ffccff"} {
# is magenta
		set name ${entryName}PreviousMagentaEntry
		if ![info exists environmentArray($name)] {return}
		regsub {(..).*} $varName {\1Reverse} reverseName	;# ddReverse
		upvar #0 $reverseName reverse
		set bg [$w cget -bg]
		set nc [NewColor $w $bg]
		if [regexp {^(.*/.*/.*/.+) .*} $environmentArray($name)] {
# repository first
			set reverse 1
			$widget.button5.5 configure -bg $nc
		} else {
			set reverse 0
			$widget.button5.5 configure -bg $bg
		}
	} elseif {$bgColor == "#ccffff"} {
# is cyan
		set name ${entryName}PreviousCyanEntry
		if ![info exists environmentArray($name)] {return}
	} else {
# otherwise
		return
	}
	UpdateEntry $widget $entryName $type $environmentArray($name) $varName $listName
	CancelSearch $widget $entryName $varName
}

# Selector - end
# ----------------------------------------------------------------------
# PerformCheck
# Example:
# PerformCheck .window.main.bc.rep.h2.entry.entry bcRepository bc(result1) 0
# display values are 0 and 1; 1 means to display the check window
# backup values are 0 and 1; 1 means to display backup warning window
# used in DeleteRepository, SelectTargetFile, ClearTargetSelection, CloseDisplayText and ReloadDisplayText

proc PerformCheck {entryWidget entryName varName {reload 1} {display 1} {backup 0}} {
# runs with start when pressing the Check (C) button 
	global environmentArray
	global homePath
	global col
	global keyRepositoryList
	global loCoInRep
#	global devLoCoInRep
	global loBiMiRep
	global URLibServiceRepository
	global samplingRepository
	global zipRepository
	global w
	global performCheckRunning
	global updateTargetFileRunning
	global dialogRunning
	global serverAddress
	global serverAddressWithIP
#	global tclRepository
	global tclPath
	global time	;# used by MultipleSubmit (it is no more true?)
	
	upvar #0 $varName var
# puts [CallTrace]
#	set fileList {}
	switch -regexp -- $entryWidget \
		{\.dir\.} {
			if [regexp {/$} $var] {
				DisplayText $entryWidget $entryName $varName .xxdirectory #dddddd
			}
			CompleteEntry $entryWidget $entryName $varName check
		} \
		{\.rep\.} {
#			set bgColor [lindex [$entryWidget config -bg] end]
#			if {$bgColor != "#ffccff"} {return}	;# not magenta
#			if ![regexp { } $var] {return}
			set performCheckRunning 1	;# used by SetCursor
			set updateTargetFileRunning 0	;# used by SetCursor
			set dialogRunning 0	;# used by SetCursor
			if !$reload {
				DisplayText $entryWidget $entryName $varName .xxrepository #dddddd 1 1
				set performCheckRunning 0
				return
			}
# rep
			if ![regexp {^(.*/.*/.*/.*) .+} $var m rep] {
				regexp {^.* (.*/.*/.*/.+)} $var m rep
			}
			if ![info exists rep] {return}

			regexp {^..} $varName xx	;# dd

			if ![file isdirectory $homePath/col/$rep] {
# the repository doesn't exist
				UpdateVariables $rep	;# updates the keyRepositoryList
				Eval UpdateVariables $rep
				SetIndicator $xx $entryWidget
				CompleteEntry $entryWidget $entryName $varName check
				return
			}

			regexp ".*\.$xx" $entryWidget win	;# .dd or .window.main.dd

# Waiting for the completion of other repository insertions
			WaitQueue
# Waiting for the completion of other repository insertions - end

# Button state and cursor
			set buttonCursorState [SetWaitingState $entryWidget $xx]
# Button state and cursor - end

# Register
#			Eval RegisterRepository $rep	;# RegisterRepositoryName need to be updated to include registration of copies (now a copy has an empty host collection value)
# Register - end

# metadataRep
			set metadataRep [Eval FindMetadataRep $rep]

# Capture
			if [file exists $homePath/col/$rep/service/notCaptured] {
				Load $homePath/col/$rep/service/notCaptured remoteSiteStamp
				set message [Eval TransferCopyright $rep $metadataRep $remoteSiteStamp administrator]
				if [string equal {} $message] {
# captured
					.window.main.bc.button.reload.reload config -state disabled
					.window.main.bc.button.reload.reload config -fg #000000
					.window.main.bc.rep.label.lb4.lb4 config -fg #999999
				} else {
					UnsetWaitingState $entryWidget $xx $buttonCursorState
					CompleteEntry $entryWidget $entryName $varName check
					LeaveQueue [pid]
					set performCheckRunning 0
					set log "PerformCheck: $message"
					puts $log
					Store log $homePath/@errorLog auto 0 a
					return
				}
			}
# Capture - end

# UPDATE METADATA
			set metadataList {}	;# for add
			set metadata2List {}	;# for remove

# Try to complete the copyright transfer
			if [file exists $homePath/col/$rep/service/transferNotCompleted] {
				Load $homePath/col/$rep/service/transferNotCompleted remoteServerAddressWithIP	;# (A)
				
# registrationPassword
				if [LoadService $rep registrationPassword registrationPassword 1 1] {
# corrupted password
					LeaveQueue [pid]
					set log "PerformCheck: $rep has a corrupted registration password"
					puts $log
					Store log $homePath/@errorLog auto 0 a
					return
				}
				set transferableFlag 0	;# must remain 0 in A
if 0 {
# commented by GJFB on 2025-11-08
# Delete the remote host collection field value (in A)
# SUBMIT
				set message [Execute $remoteServerAddressWithIP [list UpdateHostCollectionFieldValue $rep $registrationPassword {} $transferableFlag]]
#				set message [Execute $remoteServerAddressWithIP [list UpdateHostCollectionFieldValue $rep $registrationPassword {} $transferableFlag] 0]	;# not async
# Delete the remote host collection field value - end
} else {
# added by GJFB on 2025-11-08 to preserve the host collection history for copies when transferring copyright - useful for implementating fully persistent hyperlinks
				set message transferable
}
				if [string equal {transferable} $message] {
# copyright can now be transferred again if necessary
# Create a new registration password
					regsub {0\.} [expr [SortRandomNumber]/double(233280)] {} registrationPassword
					StoreService registrationPassword $rep registrationPassword 1 1
# Create a new registration password - end
					set transferableFlag 1	;# end of transfer; must be 1 in B
					StoreService transferableFlag $rep transferableFlag 1 1
					UpdateMetadataField $metadataRep transferableflag $transferableFlag metadataList metadata2List 1
					file delete $homePath/col/$rep/service/transferNotCompleted
				}
			}
# Try to complete the copyright transfer - end

## Migrate from Version 1 to Version 2
#			Eval Migrate2 $rep
## Migrate from Version 1 to Version 2 - end

# administratorUserName
			regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName

# Get clipboard
#			set newMetadata [GetClipboard $rep]
			set newMetadata [GetClipboard $rep $administratorUserName]	;# clipboard -> metadataArray
# Get clipboard - end

# Create targetFile and reference for a metadata repository
# when creating a new repository with no metadata and this repository
# is for metadata then we need to create service/targetFile
			CreateTargetFileFile $rep $entryWidget $entryName $varName	;# startApacheServer
			CreateReferenceFile $rep
# Create targetFile and reference for a metadata repository - end

# UPDATE REPOSITORY PROPERTIES
			Eval UpdateRepositoryProperties $rep

## Create targetFile and reference for a metadata repository
			Eval UpdateMultipleGlobalVariables $rep

			if ![file isdirectory $homePath/col/$metadataRep] {
				UpdateVariables $metadataRep	;# updates the keyRepositoryList
				set metadataRep ""
			}
# the metadata for rep may have been deleted or added, so the
# keyRepositoryList must be updated
#			if {$metadataRep != ""} {
#				if [UpdateKeyRepositoryList $metadataRep] {
#					StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
#				}
#			}

			if {(![string equal {} $metadataRep] && \
			[UpdateKeyRepositoryList $metadataRep]) || \
			[UpdateKeyRepositoryList $rep]} {
#				StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
			}
			set searchMode [FindSearchMode $xx $win]
			if $searchMode {
# the selectedKeyRepositoryList must be updated in case of a search beeing displayed
				UpdateKeyRepositoryList $rep 0 ${xx}SelectedKeyRepList	;# ddSelectedKeyRepList
			}

			SetIndicator $xx $entryWidget

#			UpdateHTMLTargetFile $rep 0 $administratorUserName

#			set newer [Eval TestUpdateLastUpdate $rep $metadataRep 0]
			set newer [Eval TestUpdateLastUpdate $rep $metadataRep 0 $administratorUserName]
# puts $newer
			if $newer {
# Update metadataArray and repArray in the case of a
# Bibliography Data Base
				if [Eval TestContentType $rep {Bibliography Data Base}] {
					UpdateMetadataFromBiblioDB2 $rep 0 1
					Set saveMetadata 1
#					Eval TestUpdateLastUpdate $rep $metadataRep	;# because of the new @log file
					Eval TestUpdateLastUpdate $rep $metadataRep 1 $administratorUserName	;# because of the new @log file
				}
# Update metadataArray and repArray in the case of a
# Bibliography Data Base - end
			}

# Update environmentArray(sitesHavingReadPermission)
# Update environmentArray(sitesHavingWritePermission)
			if {$rep == "$loCoInRep"} {
				if [file exists $col/$loCoInRep/doc/@sitesHavingReadPermission.txt] {
					Load $col/$loCoInRep/doc/@sitesHavingReadPermission.txt fileContent
					set fileContent [string trim $fileContent \n]
					regsub -all "\n+" $fileContent "\n" fileContent
					set sitesHavingReadPermission [split $fileContent \n]
					set environmentArray(sitesHavingReadPermission) $sitesHavingReadPermission
					Set environmentArray(sitesHavingReadPermission) $sitesHavingReadPermission
				} else {
					if [info exists environmentArray(sitesHavingReadPermission)] {
						unset environmentArray(sitesHavingReadPermission)
					}
					if [Info exists environmentArray(sitesHavingReadPermission)] {
						Unset environmentArray(sitesHavingReadPermission)
					}
				}
				if [file exists $col/$loCoInRep/doc/@sitesHavingWritePermission.txt] {
					Load $col/$loCoInRep/doc/@sitesHavingWritePermission.txt fileContent
					set fileContent [string trim $fileContent \n]
					regsub -all "\n+" $fileContent "\n" fileContent
					set sitesHavingWritePermission [split $fileContent \n]
					set environmentArray(sitesHavingWritePermission) $sitesHavingWritePermission
					Set environmentArray(sitesHavingWritePermission) $sitesHavingWritePermission
				} else {
					if [info exists environmentArray(sitesHavingWritePermission)] {
						unset environmentArray(sitesHavingWritePermission)
					}
					if [Info exists environmentArray(sitesHavingWritePermission)] {
						Unset environmentArray(sitesHavingWritePermission)
					}
				}
# SAVE
#				StoreArray environmentArray ../auxdoc/.environmentArray.tcl
#				StoreArray environmentArray ../auxdoc/.environmentArray2.tcl	;# backup
#				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl	;# added by GJFB on 2010-08-05
				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl w list	;# added by GJFB on 2010-08-05
# SAVE - end
			}
# Update environmentArray(sitesHavingReadPermission) - end
# Update environmentArray(sitesHavingWritePermission) - end
			if [Eval TestContentType $rep {Mirror}] {
# Migration 1/4/01
				if [info exists environmentArray(${rep}siteList)] {
					unset environmentArray(${rep}siteList)
				}
# Migration 1/4/01 - end
				set index [lsearch $environmentArray(mirrorRepList) $rep]
				set environmentArray(mirrorRepList) [lreplace $environmentArray(mirrorRepList) $index $index]
				lappend environmentArray(mirrorRepList) $rep
				Set environmentArray(mirrorRepList) $environmentArray(mirrorRepList)
#				Load $homePath/col/$rep/doc/@hidedMetadataRepositoryList.txt hidedMetadataRepositoryList
#				set hidedMetadataRepositoryList [string trim $hidedMetadataRepositoryList " \n"]
#				set environmentArray($rep,hidedmetadatarepositorylist) $hidedMetadataRepositoryList
#				Set environmentArray($rep,hidedmetadatarepositorylist) $hidedMetadataRepositoryList
# SAVE
#				StoreArray environmentArray ../auxdoc/.environmentArray.tcl
#				StoreArray environmentArray ../auxdoc/.environmentArray2.tcl	;# backup
#				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl	;# added by GJFB on 2010-08-05
				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl w list	;# added by GJFB on 2010-08-05
# SAVE - end
			}
if 0 {
# update is now done in Dialog - reload should not be necessary
# Update language and textlanguage
			if [Eval TestContentType $rep {Metadata}] {
# added by GJFB on 2013-02-11 to search for the proper metadata repository based on its language and display the corresponding entry in the proper language
# useful for multiple language document to display resume or archival unit document in the proper language
				if [Info exists repositoryProperties($rep,language)] {
					set language [Get repositoryProperties($rep,language)]	
					regexp {\[(.*)\]} $language m language	;# English {[en]} -> en
					UpdateMetadataField $rep textlanguage $language metadataList metadata2List 1
				} else {
					DeleteMetadataField $rep textlanguage metadata2List 1
				}
			} else {
				if {$metadataRep != {}} {
					UpdateField $rep $metadataRep language metadataList metadata2List
				}
			}
# Update language and textlanguage - end
}

# Update contenttype
			UpdateField $rep $metadataRep contenttype metadataList metadata2List
# Update contenttype - end

# UPDATE REFERENCE TABLE
# Update childrepositories
# Update parentrepositories
			set childRepositories [UpdateCrossReferences $rep $metadataRep metadataList metadata2List]
# Update parentrepositories - end 
# Update childrepositories - end
# UPDATE REFERENCE TABLE - end

# Create environmentArray(permissionList) and environmentArray(languagePreference)
			if [Eval TestContentType $rep {Mirror}] {
#				set stopStartApacheServer [Eval CreatePermissionList $rep]
				Eval CreatePermissionList $rep
				Eval CreateEnvironmentArray	;# to update LANGUAGE_PREFERENCE
			} else {
#				set stopStartApacheServer 0
			}
# Create environmentArray(permissionList) and environmentArray(languagePreference) - end

# site
#			set site [GetServerAddress]
			set site $serverAddress
			if [Eval TestContentType $rep Metadata] {
# METADATA REPOSITORY
#				Eval UpdateReferenceFileForLoCoInRep
# Update metadata base
				Eval UpdateMetadataBase $rep metadataList metadata2List $site update
# Update metadata base - end
			}
			if [Eval TestContentType $rep {CGI Script}] {
				Eval InstallCGIScript $rep
			}
# Start apache server
			catch {Eval StartApacheServer} message
# puts --$message--
# Start apache server - end

			set metadataRepList [Eval FindAllLanguageVersions $metadataRep]

# Update metadataArray and repArray in a Mirror case
			if [Eval TestContentType $rep {Mirror}] {
#				set wordOccurrenceList [GetWordOccurrenceList $rep 30]	;# not used because it is slower than the exec version below

# update keywords
#				if [file exists $col/$loBiMiRep/doc/@wordOccurrence] #
				if [file exists $col/$rep/doc/@wordOccurrence] {
					set mtime1 [file mtime $col/$rep/doc/@wordOccurrence]
				} else {
					set mtime1 0
				}
# EXEC
#				exec $tclPath urlibScript/getWordOccurrence.tcl $rep $homePath $URLibServiceRepository $loCoInRep $serverAddress $serverAddressWithIP
				exec $tclPath urlibScript/getWordOccurrence.tcl $rep $homePath $URLibServiceRepository $loCoInRep
				Eval TestUpdateLastUpdate $rep $metadataRep 1 $administratorUserName	;# because of the new @wordOccurrence file

# update keywords
#				if [file exists $col/$loBiMiRep/doc/@wordOccurrence] #
				if [file exists $col/$rep/doc/@wordOccurrence] {
					set mtime2 [file mtime $col/$rep/doc/@wordOccurrence]
				} else {
					set mtime2 0
				}
# puts [list $mtime1 $mtime2]
				if ![string equal $mtime1 $mtime2] {
					Load $col/$rep/doc/@wordOccurrence wordOccurrenceList
					set wordList {}
					foreach item $wordOccurrenceList {
						lappend wordList [join [lreplace $item end end]]
					}
					set keyWords [join $wordList {, }].
# puts $keyWords
					if {$metadataRep != ""} {
# a metadata exists for this rep
						foreach mRep $metadataRepList {
							Load $col/$mRep/doc/@metadata.refer referMetadata
# Update metadatalastupdate field
# CREATE A NEW VERSION STAMP
# 							set seconds [DirectoryMTime $homePath/col/$mRep/doc]
			 				set seconds [clock seconds]
							set versionStamp [CreateVersionStamp $seconds $administratorUserName $referMetadata]
							Eval UpdateHistory $mRep $versionStamp
							UpdateMetadataField $mRep metadatalastupdate $versionStamp metadataList metadata2List
# Update metadatalastupdate field - end
						}
					}
				}
			}
# Update metadataArray and repArray in a Mirror case - end
# Update size and numberOfFiles
			foreach {size numberOfFiles} [ComputeInfo $rep] {break}
# puts [list $size $numberOfFiles]
			Load $homePath/col/$rep/service/size oldSize
#			if [string equal {0 Kbyte} $size] #
			if [string equal {0 KiB} $size] {
				file delete $homePath/col/$rep/service/size
				set size {}	;# used by UpdateMetadataField below (to remove size)	
			} else {
				Store size $homePath/col/$rep/service/size
			}	
			Eval UpdateRepositoryProperties $rep size
			UpdateMetadataField $metadataRep size $size metadataList metadata2List 1
			Load $homePath/col/$rep/service/numberOfFiles oldNumberOfFiles
			if [string equal {0} $numberOfFiles] {
				file delete $homePath/col/$rep/service/numberOfFiles
				set numberOfFiles {}	;# used by UpdateMetadataField below (to remove numberoffiles) 	
				catch {file delete $homePath/col/$rep/auxdoc} 	
				catch {file delete $homePath/col/$rep/source}
				if [file exists $homePath/col/$rep/service/notRegistered] {
					file delete $homePath/col/$rep/service/notRegistered
#					file delete $homePath/col/$rep/service/registrationPassword
				}	
			} else {
				Store numberOfFiles $homePath/col/$rep/service/numberOfFiles
				file mkdir $homePath/col/$rep/auxdoc
				file mkdir $homePath/col/$rep/source
			}
			Eval UpdateRepositoryProperties $rep numberoffiles
			UpdateMetadataField $metadataRep numberoffiles $numberOfFiles metadataList metadata2List 1
# numberOfFileChange
			set numberOfFileChange [expr [string compare $oldSize $size] != 0 || \
			[string compare $oldNumberOfFiles $numberOfFiles] != 0]
# Update size and numberOfFiles - end

# Update identifier
# was usefull to drop and add identifier during the identifier testing period
if 0 {
			LoadService $rep identifier identifier 1 1
			UpdateMetadataField $metadataRep identifier $identifier metadataList metadata2List 1
}
# Update identifier - end

# Update download files
			if {$metadataRep != ""} {
# a metadata exists for this rep
				if {$backup && ![file exists $homePath/col/$rep/download/sample] && \
				![Dialog {Yes No} {active disabled} {0 0} BC {register and back the document up}]} {
# backup
					if {$newer || $newMetadata || $numberOfFileChange || ![file exists $col/$rep/download/doc.zip]} {
#						Eval UpdateDownloadFilesByAdministrator $rep $childRepositories 1
						Eval UpdateDownloadFilesByAdministrator $rep 0 1
						Set saveMetadata 1
					}
# Create sampled document
					set sample [${samplingRepository}::SampleFile $rep]
					Store sample $homePath/col/$rep/download/sample binary 1
					if [string equal {} $zipRepository] {
#						set history "$samplingRepository [lindex [Get repositoryProperties($samplingRepository,history)] end]"
						set history "$samplingRepository [Eval GetVersionStamp $samplingRepository]"
					} else {
#						set history "$zipRepository [lindex [Get repositoryProperties($zipRepository,history)] end] $samplingRepository [lindex [Get repositoryProperties($samplingRepository,history)] end]"
						set history "$zipRepository [Eval GetVersionStamp $zipRepository] $samplingRepository [Eval GetVersionStamp $samplingRepository]"
					}
					Store history $homePath/col/$rep/download/history
# Create sampled document - end
				} else {
#					if {$newer || $newMetadata || $numberOfFileChange} #
					if {$newer || $newMetadata || $numberOfFileChange || ![file exists $col/$rep/download/doc.zip]} {
# puts --$childRepositories--
#						Eval UpdateDownloadFilesByAdministrator $rep $childRepositories
						Eval UpdateDownloadFilesByAdministrator $rep
						Set saveMetadata 1
					}
				}
			}
# Update download files - end

# Set agreement field
			set dir $homePath/col/$rep/agreement
			set fileList {}
			if [file isdirectory $dir] {DirectoryContent fileList $dir $dir}
			UpdateMetadataField $metadataRep agreement $fileList metadataList metadata2List
# Set agreement field - end

# Register the sampled document
			if [file exists $col/$rep/download/sample] {
#				set lastUpdate [lindex [Get repositoryProperties($rep,history)] end]
				set lastUpdate [Eval GetVersionStamp $rep]
				Load $col/$rep/download/sample sample binary
				binary scan $sample c* sampleC
				set command [list list RegisterSampledDocument $rep $lastUpdate $sampleC]
# MULTIPLE SUBMIT
				set sampledDocumentDBServerAddress [Eval GetSampledDocumentDBServerAddress]
#				set time [MultipleExecute 150.163.8.245:1905 $command 1]	;# for testing
				set time [MultipleExecute [list $sampledDocumentDBServerAddress] $command 1]
				if {[string compare {} $time] != 0} {Store time $col/$rep/download/time}
			}
# Register the sampled document - end

# SAVE
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
#			Eval StoreArray referenceTable ../auxdoc/.referenceTable.tcl
			Eval SaveRepositoryProperties
			Eval SaveReferenceTable
# puts saved
# SAVE - end
# UPDATE METADATA
# puts $metadata2List
# puts $metadataList
if 0 {
# commented by GJFB on 2020-08-18
			Eval RemoveMetadata $metadata2List
			Eval AddMetadata $metadataList
} else {
			Eval UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
			if {$metadataList != {} || $metadata2List != {}} {
				Set saveMetadata 1
			}
# SAVE
			Eval SaveMetadata
			Eval UpdateRepositoryListForPost [concat $rep $metadataRepList]
# SAVE - end

# Update entry
			regsub {(..).*} $varName {\1Reverse} reverseName	;# ddReverse
			upvar #0 $reverseName reverse
			if !$reverse {
# key first
			set var [AddKey $rep/ 0]
			}
# repository first is updated by CompleteEntry below
# Update entry - end
			if $display {
				DisplayText $entryWidget $entryName $varName .xxrepository #dddddd 1 0
			}
# Button state and cursor
			UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
			CompleteEntry $entryWidget $entryName $varName check
			LeaveQueue [pid]
		}
	set performCheckRunning 0
}

# PerformCheck - end
# ----------------------------------------------------------------------
# UpdateCrossReferences
# updates referenceTable array
# updates childrepositories for metadataArray
# updates parentrepositories for metadataArray
# see similar code in CreateExtraFields

proc UpdateCrossReferences {rep metadataRep metadataListName metadata2ListName} {
# runs with start and post
	upvar $metadataListName metadataList
	upvar $metadata2ListName metadata2List

	set oldParentRepositories [Eval GetCitedRepositoryList $rep]

# UPDATE REFERENCE TABLE
	Eval UpdateReferenceTable $rep

# Update childrepositories
	set childRepositories [Eval GetCitingRepositoryList $rep]
# Drop the mRep from the childRepositories
	set metadataRepList [Eval FindAllLanguageVersions $metadataRep]
	foreach mRep $metadataRepList {
		if {[set i [lsearch -exact $childRepositories $mRep]] != -1} {
			set childRepositories [lreplace $childRepositories $i $i]
		}
	}
# Drop the mRep from the childRepositories - end
	UpdateMetadataField $metadataRep childrepositories $childRepositories metadataList metadata2List 1
# Update childrepositories - end

# Update parentrepositories
	set parentRepositories [Eval GetCitedRepositoryList $rep]
# puts [list $parentRepositories --$metadataRep--]
	UpdateMetadataField $metadataRep parentrepositories $parentRepositories metadataList metadata2List 1
# puts [list $metadataList $metadata2List]
# Update parentrepositories - end

# Process the old and new parents
	set intersection [ListIntersection oldParentRepositories parentRepositories]
	set union [lsort -unique [concat $oldParentRepositories $parentRepositories]]
	set exclusiveUnion $union
	foreach item $intersection {
		set i [lsearch -exact $exclusiveUnion $item]
		set exclusiveUnion [lreplace $exclusiveUnion $i $i]
	}
	foreach rep2 $exclusiveUnion {
		set metadataRep2 [Eval FindMetadataRep $rep2]
		set childRepositories2 [Eval GetCitingRepositoryList $rep2]
# Drop the mRep from the childRepositories2
		set metadataRepList [Eval FindAllLanguageVersions $metadataRep2]
		foreach mRep $metadataRepList {
			if {[set i [lsearch -exact $childRepositories2 $mRep]] != -1} {
				set childRepositories2 [lreplace $childRepositories2 $i $i]
			}
		}
# Drop the mRep from the childRepositories2 - end
		UpdateMetadataField $metadataRep2 childrepositories $childRepositories2 metadataList metadata2List 1
	}	
# Process the old and new parents - end

	return $childRepositories
}

# UpdateCrossReferences - end
# ----------------------------------------------------------------------
# SetWaitingState
# used by PerformCheck, Dialog and others

proc SetWaitingState {entryWidget xx} {
	global w
	if ![winfo exists $entryWidget] {return}
#	DisableButtons
	if [winfo exists .xxrepository] {
		.xxrepository.button.close.close config -state disabled
		.xxrepository.button.reload.reload config -state disabled
	}
	set reloadButtonState {}
#	set reloadButtonForeground {}
	set deleteButtonState {}
	if {[string compare bc $xx] == 0} {
		set reloadButtonState [lindex \
			[$w.main.bc.button.reload.reload config -state] end]
		$w.main.bc.button.reload.reload config -state disabled
#		set reloadButtonForeground [lindex \
			[$w.main.bc.button.reload.reload config -fg] end]
		$w.main.bc.button.reload.reload config -fg #000000	;# set back to black before computing if it should be red
		$w.main.bc.rep.label.lb1.lb1 config -fg #999999
		$w.main.bc.rep.label.lb2.lb2 config -fg #999999
		$w.main.bc.rep.label.lb3.lb3 config -fg #999999
		$w.main.bc.rep.label.lb4.lb4 config -fg #999999
		set deleteButtonState [lindex \
			[$w.main.bc.button.delete.delete config -state] end]
		$w.main.bc.button.delete.delete config -state disabled
	} elseif {[string compare dd $xx] == 0} {
		$w.main.dd.buttons.ok.ok config -state disabled
		$w.main.dd.buttons.cancel.cancel config -state disabled
		$w.main.dd.buttons.edit.edit config -state disabled
		$w.main.dd.rep.h1.h1.b1 config -state disabled
		$w.main.dd.rep.h1.h2.b2 config -state disabled
	}
	regsub {.entry$} $entryWidget {} widget
	$entryWidget configure -state disabled
	$widget.button1.1 configure -state disabled
	$widget.button3.3 configure -state disabled
	$widget.button4.4 configure -state disabled
	set button5.5State [lindex \
		[$widget.button5.5 config -state] end]
	$widget.button5.5 configure -state disabled
	$widget.button6.6 configure -state disabled
	set cursor [lindex [$w config -cursor] end]
	$w config -cursor watch
	if [winfo exists .xxrepository] {
		.xxrepository config -cursor watch
		.xxrepository.f.t config -cursor watch
	}
#	return [list $reloadButtonState $reloadButtonForeground $deleteButtonState $cursor]
	return [list $reloadButtonState $deleteButtonState ${button5.5State} $cursor]
}

# SetWaitingState - end
# ----------------------------------------------------------------------
# UnsetWaitingState
# used by PerformCheck, Dialog, CloseDisplayText and others
# Examples:
# UnsetWaitingState $entryWidget $xx $buttonCursorState
# UnsetWaitingState .window.main.bc.rep.h2.entry.entry bc {normal disabled {}}
# UnsetWaitingState .window.main.dd.rep.h1.h2.v2.entry.entry dd {{} {} {}}
# UnsetWaitingState {} {} {}

proc UnsetWaitingState {entryWidget xx parameters} {
	global w
# puts [list $entryWidget $xx $parameters]
	if ![winfo exists $entryWidget] {return}
	if [winfo exists .xxrepository] {
		.xxrepository.button.close.close configure -state normal
		.xxrepository.button.reload.reload configure -state normal
	}
#	foreach {reloadButtonState reloadButtonForeground deleteButtonState cursor} $parameters {break}
	foreach {reloadButtonState deleteButtonState button5.5State cursor} $parameters {break}
	$w config -cursor $cursor
	if {[string compare bc $xx] == 0} {
		$w.main.bc.button.reload.reload config -state $reloadButtonState
#		$w.main.bc.button.reload.reload config -fg $reloadButtonForeground
#		$w.main.bc.button.reload.reload config -fg #000000
		$w.main.bc.button.delete.delete config -state $deleteButtonState
	} elseif {[string compare dd $xx] == 0} {
		$w.main.dd.buttons.ok.ok config -state normal
		$w.main.dd.buttons.cancel.cancel config -state normal
		$w.main.dd.buttons.edit.edit config -state normal
		$w.main.dd.rep.h1.h1.b1 config -state normal
		$w.main.dd.rep.h1.h2.b2 config -state normal
		return
	}
	regsub {.entry$} $entryWidget {} widget
	$entryWidget configure -state normal
	$widget.button1.1 configure -state normal
	$widget.button3.3 configure -state normal
	$widget.button4.4 configure -state normal
	$widget.button5.5 configure -state ${button5.5State}
	$widget.button6.6 configure -state normal
	if [winfo exists .xxrepository] {
		.xxrepository config -cursor {}
		.xxrepository.f.t config -cursor double_arrow
	}
#	EnableButtons
}

# UnsetWaitingState - end
# ----------------------------------------------------------------------
# UpdateDownloadFile
# used by PerformCheck, Dialog, UpdateDownloadFilesByAdministrator and main (start)
# updates the download file if the document in rep is the original one
# or the site is a mirror site
# force value is 0 or 1
# 1 means to execute TestUpdateLastUpdate even for $rep (may create a new version stamp}
# backup values are 0 or 1
# 1 means that the current version must be registered and then back it up
# packEverything value is 0, 1 or 2
# 0 means to pack just doc, agreement, images and part of service
# 1 means to pack everything (i.e., besides doc, agreement, images and part of service, source, backup and not_sent directories)
# 2 means to pack everything except doc

proc UpdateDownloadFile {rep {force 0} {backup 0} {userName {}} {packEverything 0}} {
# runs with start and post
	global applicationName
#	set packEverything [ComputePackEverything $rep]
# set xxx $rep
# Store xxx C:/tmp/aaa auto 0 a
# set xxx [CallTrace]
# Store xxx C:/tmp/aaa auto 0 a
	if {$applicationName == "start"} {
#		Eval MakeDownloadFile $rep $packEverything $force $backup
		Eval MakeDownloadFile $rep $packEverything $force $backup $userName
	}
	if {$applicationName == "post"} {
#		MakeDownloadFile $rep $packEverything $force $backup
		MakeDownloadFile $rep $packEverything $force $backup $userName
	}
}

# UpdateDownloadFile
# ----------------------------------------------------------------------
# UpdateDownloadFilesByAdministrator
# backup values are 0 or 1
# 1 means that the current version of the document in $rep
# must be registered and then back it up
# packEverything value is 0, 1 or 2
# 0 means to pack just doc, agreement, images and part of service
# 1 means to pack everything (i.e., besides doc and part of service, source, backup and not_sent directories)
# 2 means to pack everything except doc

proc UpdateDownloadFilesByAdministrator {rep {packEverything 0} {backup 0}} {
# runs with post
	global environmentArray
	
	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName
	UpdateDownloadFile $rep 0 $backup $administratorUserName $packEverything
}

# UpdateDownloadFilesByAdministrator - end
# ----------------------------------------------------------------------
# FindCurrentDownloadPermission
# used in CreateBriefEntry, StartService, MakeDownloadFile and Cover
# returns the download permission of $rep based on:
# hostCollection given in repositoryProperties array (with post) or files in service (with start) if rep is the master
# else a mirror site of $rep

proc FindCurrentDownloadPermission {rep} {
# runs with start and post
	global repositoryProperties
	global loCoInRep
	global applicationName
	
	set documentState [GetDocumentState $rep]
# set xxx $documentState
# Store xxx C:/tmp/aaa auto 0 a
	if !$documentState {
# $rep doesn't contain the original document (the matrix) - it is a copy
		if {$applicationName == "start"} {
			LoadService $rep mirrorSites mirrorSites 1 1
		} else {
			if [info exists repositoryProperties($rep,mirrorsites)] {
				set mirrorSites $repositoryProperties($rep,mirrorsites)
			} else {
				set mirrorSites {}
			}
		}
		set documentState [expr [lsearch -exact $mirrorSites $loCoInRep] != -1]
# set xxx $documentState
# Store xxx C:/tmp/aaa auto 0 a
	}
	if $documentState {
# the last host collection or a mirror site is the current local collection (loCoInRep)
		if {$applicationName == "start"} {
			LoadService $rep downloadPermission currentDownloadPermission 0 1
			if [string equal {} $currentDownloadPermission] {
				set currentDownloadPermission [GetPermission download]
			}
		} else {
			if [info exists repositoryProperties($rep,downloadpermission)] {
				set currentDownloadPermission $repositoryProperties($rep,downloadpermission)
			} else {
# get the default permisssion
				set currentDownloadPermission [GetPermission download]
			}
		}
	} else {
# neither the last host collection nor a mirror site is the current local collection (loCoInRep)
		if {$applicationName == "start"} {
			LoadService $rep downloadRemotePermission currentDownloadPermission 1 1
			if [string equal {} $currentDownloadPermission] {
				set currentDownloadPermission "deny from all"
			}
		} else {
			if [info exists repositoryProperties($rep,downloadremotepermission)] {
				set currentDownloadPermission $repositoryProperties($rep,downloadremotepermission)
			} else {
# get the default permisssion
				set currentDownloadPermission "deny from all"
			}
		}
	}
	return $currentDownloadPermission
}

# FindCurrentDownloadPermission - end
# ----------------------------------------------------------------------
# ComputePackEverything
# returns 0 or 1
# 1 means to pack everything (doc, source, backup and not_sent)

# not used
proc ComputePackEverything2 {rep} {
# runs with start and post
	global loCoInRep

	set packEverything 0
	if ![GetDocumentState $rep] {
# the repository doesn't contain an original document (the copyright may be in a transfer stage)
		set currentDownloadPermission [FindCurrentDownloadPermission $rep]
		set downloadPermission [split $currentDownloadPermission \n]
		if [string equal [lindex $downloadPermission 0] {deny from all}] {
			if {[llength $downloadPermission] == 3} {
# the copyright is in a transfer stage
				set packEverything 1
			}
		}
	}
# puts $packEverything
	return $packEverything
}

# ComputePackEverything - end
# ----------------------------------------------------------------------
# DeleteRepository
# Example:
# DeleteRepository .window.main.bc.rep.h2.entry.entry bcRepository bc(result1)

proc DeleteRepository {entryWidget entryName varName} {
# runs with start
	global log
	global keyRepositoryList
	global loCoInRep
	global serverAddressWithIP	;# added by GJFB on 2024-01-21
	upvar #0 $varName var
# rep
	if ![regexp {^(.*/.*/.*/.*) .+} $var m rep] {
		regexp {^.* (.*/.*/.*/.+)} $var m rep
	}
	if [info exists rep] {
		if ![winfo exists .xxrepository] {
			PerformCheck $entryWidget $entryName $varName 0
		}
		if [Dialog {Yes No} {disabled active} {0 0} BC {deleting a repository} $rep] {return}
# Yes, delete
		DisableButtons
		regexp {^..} $varName xx	;# bc
		set buttonCursorState [SetWaitingState $entryWidget $xx]
# Compute the log
		LogInsert [list [list Insert $log end {new line}]] 1 0	;# blk line
		LogInsert [list [list Insert $log end \
			{deleting repository <$var1> ...} \
			{} $rep] \
			[list TagAdd $log fixed9 \
			{<$var1>} -forward $rep]] 0 0
		LogInsert [list [list Insert $log insert {new line}]] 0 1
# Compute the log - en
# metadataRepList
		set metadataRepList [FindMetadataRepList $rep $entryWidget $varName]
# DELETE
		UpdateRobotstxtFile $rep 0 0
		foreach metadataRep $metadataRepList {
			CleanCollection $metadataRep
		} 
		if [catch {CleanCollection $rep} message] {
			Dialog OK disabled -1 BC {permission denied} $message	;# added by GJFB on 2021-08-14
			UnsetWaitingState $entryWidget $xx $buttonCursorState
			return
		}
		UnsetWaitingState $entryWidget $xx $buttonCursorState
		PerformCheck $entryWidget $entryName $varName	;# PerformCheck calls CompleteEntry which calls Eval FindMetadataRep2 which calls CheckMetadataConsistency which stores the deletedRecordList in @deletedRecordList.tcl
		foreach metadataRep $metadataRepList {
#			Eval UpdateVariables $metadataRep	;# must be after PerformCheck in order to get the right keyRepositoryList
			if [Info exists referenceTable($loCoInRep,$metadataRep)] {
				Unset referenceTable($loCoInRep,$metadataRep)
			}
		}

# Remove citing item
# added by GJFB on 2024-01-21
# rep is the source (which is being deleted)
		set siteMetadataRepList [FindMetadataRepositories "citingitemlist, $rep" 0 {} {} no no 1]	;# {site rep-i} {site rep-i} ...
		foreach siteMetadataRep $siteMetadataRepList {
			foreach {site rep-i} $siteMetadataRep {break}
			SetFieldValue $site ${rep-i} {repository} 0 1
# repository is the destination (which must be updated)
			if [string equal {} $repository] {
# conflicting server addresses (see SetFieldValue)
			} else {
				Execute $serverAddressWithIP [list UpdateCitingItemList $rep $repository remove]
			}
		}
# Remove citing item - end		

#		Eval UpdateReferenceFileForLoCoInRep
#		StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl	;# time consuming
# Compute the log
		LogInsert [list [list Insert $log end {new line}]] 1 0	;# blk line
		LogInsert [list [list Insert $log end \
			{repository <$var1> deleted} \
			{} $rep] \
			[list TagAdd $log fixed9 \
			{<$var1>} -forward $rep]] 0 0
		LogInsert [list [list Insert $log insert {new line}]] 0 1
# Compute the log - end
		EnableButtons
	}
}

# DeleteRepository - end
# ----------------------------------------------------------------------
# RemoveRepository
# used within the administrator page and ProcessReview only
# sessionTime value are miliseconds - added by GJFB on 2019-01-16

# proc RemoveRepository {rep userName password} #
proc RemoveRepository {rep metadataRep userName password {sessionTime {}}} {
# runs with post
	global environmentArray
	global referenceTable
	global loCoInRep
	global loBiMiRep
	global homePath

	set permanentRepositoryList [list $loCoInRep $loBiMiRep]	;# permanent repositories - should not be removed
	if {[lsearch $permanentRepositoryList $rep] != -1} {
		return "RemoveRepository: --$rep-- is a permanent repository"
	}
		
#	if ![regexp {[^/]+/\d{4,}/\d{2}\.\d{2}\.\d{2}\.\d{2}($|\.\d{2}$|\.\d{2}\.\d{3}$)} $rep] #
	if ![regexp {^[^/]+/[^/]+/\d{4,}/\d{2}\.\d{2}\.\d{2}\.\d{2}($|\.\d{2}$|\.\d{2}\.\d{1,}$)} $rep] {
# not the repository syntax
# security issue (to avoid removing something which is not a repository)
		return "RemoveRepository: --$rep-- has not the repository syntax"
	}
	if ![regexp {^[^/]+/[^/]+/\d{4,}/\d{2}\.\d{2}\.\d{2}\.\d{2}($|\.\d{2}$|\.\d{2}\.\d{1,}$)} $metadataRep] {
# not the repository syntax
# security issue (to avoid removing something which is not a repository)
		return "RemoveRepository: --$metadataRep-- has not the repository syntax"
	}
# administratorUserName
	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName

	if ![string equal administrator $userName] {
		if [string equal $administratorUserName $userName] {
# $userName is the administrator
		} else {
# $userName is not the administrator
			return "RemoveRepository: $userName is not the administrator"
		}
	}
	if [CheckPassword $userName $password write 0 0 $sessionTime] {
		return "RemoveRepository: the password is incorrect or the user name doesn't exist" 
	}
if 0 {
	if ![file isdirectory $homePath/col/$rep] {return {}}	;# useful when there are more than one metadata repository

# metadataRepList
	set metadataRepList [FindMetadataRepList $rep]

# DELETE
	UpdateRobotstxtFile $rep 0 0
	set rep-iList {}
	foreach metadataRep $metadataRepList {
		CleanCollection $metadataRep
		UpdateVariables $metadataRep
		lappend rep-iList $metadataRep-0
	} 
	CleanCollection $rep
	UpdateVariables $rep

#	foreach metadataRep $metadataRepList {
#		if [info exists referenceTable($loCoInRep,$metadataRep)] {
#			unset referenceTable($loCoInRep,$metadataRep)
#		}
#	}
#	UpdateReferenceFileForLoCoInRep

	CheckMetadataConsistency rep-iList [llength ${rep-iList}]	;# CheckMetadataConsistency is in utilitiesStart.tcl, it stores the deletedRecordList in @deletedRecordList.tcl and calls RemoveMetadata
} else {
# new code by GJFB on 2015-12-19 - appropriate code when there are more than one metadata repository for the same data repository
# DELETE
	if [file isdirectory $homePath/col/$rep] {
		UpdateRobotstxtFile $rep 0 0
		CleanCollection $rep
		UpdateVariables $rep
	}
	CleanCollection $metadataRep
	UpdateVariables $metadataRep
	set rep-iList $metadataRep-0
	CheckMetadataConsistency rep-iList	;# CheckMetadataConsistency is in utilitiesStart.tcl, it stores the deletedRecordList in @deletedRecordList.tcl and calls RemoveMetadata
}
	return {}
}

# RemoveRepository - end
# ----------------------------------------------------------------------
# CleanCollection
# used in DeleteRepository and others

proc CleanCollection {rep} {
# runs with post and start
	global homePath
	file delete -force $homePath/col/$rep
	regexp {(.*/.*/.*)/.*} $rep m rest3
	if ![TestDirectoryContent $homePath/col/$rest3] {
# $rest3 doesn't contain files (dpi.inpe.br/banon/1997)
		file delete -force $homePath/col/$rest3
		regexp {(.*/.*)/.*} $rest3 m rest2
		if ![TestDirectoryContent $homePath/col/$rest2] {
# $rest2 doesn't contain files (dpi.inpe.br/banon)
			file delete -force $homePath/col/$rest2
			regexp {(.*)/.*} $rest2 m rest1
			if ![TestDirectoryContent $homePath/col/$rest1] {
# $rest1 doesn't contain files (dpi.inpe.br)
				file delete -force $homePath/col/$rest1
			}
		}
	}
}

# CleanCollection - end
# ----------------------------------------------------------------------
# TestDirectoryContent
# returns 0 if the directory dirPath is empty
# or contains at most the excluded files and returns 1 otherwise
# Examples:
# TestDirectoryContent $homePath/col/$rep/auxdoc
# TestDirectoryContent $homePath/col/$rep/auxdoc {cgi2/update cgi2/review}
# TestDirectoryContent $homePath/col/$rep/source {.htaccess .htaccess2}

proc TestDirectoryContent {dirPath {excludedFileList {}}} {
	set dirContent {}
	DirectoryContent dirContent $dirPath $dirPath 1
	if ![llength $dirContent] {return 0}	;# empty directory
	if {[llength $dirContent] <= [llength $excludedFileList]} {
		foreach fileName $dirContent {
# puts $fileName
			if {[lsearch -exact $excludedFileList $fileName] == -1} {return 1}
		}
		return 0
	}
	return 1
#	return [expr [llength $dirContent] != 0]
}

# puts [TestDirectoryContent C:/usuario/gerald/URLib/col/iconet.com.br/banon/2002/05.26.16.17/auxdoc]
# puts [TestDirectoryContent C:/usuario/gerald/URLib/col/iconet.com.br/banon/2002/05.26.16.17/auxdoc {cgi2/update cgi2/review}]

# TestDirectoryContent - end
# ----------------------------------------------------------------------
# CreateTargetFileFile
# Creates service/targetFile for a metadata repository
# used in PerformCheck and Dialog only

proc CreateTargetFileFile {rep entryWidget entryName varName} {
# runs with start
	global col
	global keyRepositoryList
	if [Eval TestContentType $rep Metadata] {
		if ![file exists $col/$rep/service/targetFile] {
			set targetFile metadata.cgi
			Store targetFile $col/$rep/service/targetFile
			Set repositoryProperties($rep,targetfile) metadata.cgi
			Set startApacheServer 1
			if [UpdateKeyRepositoryList $rep] {
#				StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
				Eval UpdateRepositoryListForPost $rep
			}
			CompleteEntry $entryWidget $entryName $varName check
		}
	}
}

# CreateTargetFileFile - end
# ----------------------------------------------------------------------
# CreateReferenceFile
# Creates service/reference for a metadata repository
# used in PerformCheck, Dialog and UpdateReferenceTable
# returns 0 if the reference file were created successfully, and 1 otherwise

proc CreateReferenceFile {rep} {
# runs with post and start
	global col
	
	if [Eval TestContentType $rep Metadata] {
# rep is a metadata rep
		if ![file exists $col/$rep/service/reference] {
			Load $col/$rep/doc/@metadata.refer fileContent			
			set repName [GetReferField $fileContent 4]
			if [string equal {} $repName] {
# repName not found
				return 1
			}
			if ![file isdirectory $col/$repName] {
# repName is not a repository
				return 1
			}
			set reference ../$col/col/$repName 
			Store reference $col/$rep/service/reference
			Set referenceTable($rep,$repName) 1
			Store fileContent $col/$rep/doc/@metadata.refer	;# to update mTime and to allow PerformCheck to grasp the metadata
		}
	}
	return 0
}

# CreateReferenceFile - end
# ----------------------------------------------------------------------
# GetVersionStamp

proc GetVersionStamp {rep} {
# runs with post
	global repositoryProperties
	return [lindex $repositoryProperties($rep,history) end]
}

# GetVersionStamp - end
# ----------------------------------------------------------------------
# GetLastChange
# Return the last change in the format %Y:%m.%d.%H.%M.%S
# works with gmt

proc GetLastChange {rep} {
# runs with post
	global repositoryProperties
	if [info exists repositoryProperties($rep,history)] {
		set lastChange [lindex [GetVersionStamp $rep] 0]
	} else {
		set lastChange [clock format 0 -format %Y:%m.%d.%H.%M.%S -gmt 1]
	}
	return $lastChange
}

# GetLastChange - end
# ----------------------------------------------------------------------
# ComputeInfo
# Compute the size and the number of files of the document in $rep
# # used in StartService, Migrate1, DDRoutine, UpdateLastUpdate, LoadMetadata and PerformCheck only

proc ComputeInfo {rep {dir doc}} {
# runs with start and post
	global homePath
	
	foreach {size numberOfFiles} [DirectoryInfo $homePath/col/$rep/$dir] {break}
# puts $size
	set size [expr int(ceil($size / 1024.))]	;# KiB - added by GJFB on 2018-03-09 - faster - same code as in ComputeSize
	set size "$size KiB"
# puts $size
#	set size [ComputeSize $rep $dir]	;# commented by GJFB on 2018-03-09
## puts $size
	return [list $size $numberOfFiles]
}

if 0 {
# testing
	set homePath {C:/Users/Sony/URLib 2}
#	foreach {size numberOfFiles} [ComputeInfo dpi.inpe.br/banon/1999/04.21.17.06] {break}
	foreach {size numberOfFiles} [ComputeInfo urlib.net/www/2016/07.25.01.45] {break}
#	puts $size
#	puts $numberOfFiles
}

# ComputeInfo - end
# ----------------------------------------------------------------------
# GetClipboard
# used in PerformCheck and in DDDialog
# clipboard -> metadataArray
# clipboard -> service (type - targetFile)
# returns 1 if at least one metadata for $rep was captured
# or if one new metadata was captured ($rep == {}),
# otherwise returns 0
# works with gmt

proc GetClipboard {{rep {}} {userName {}}} {
# runs with start
#	global col
	global homePath
#	global saveMetadata	;# post
#	global metadataArray
#	global startApacheServer
	global serverAddress
	catch {selection get -selection CLIPBOARD} clipboard
	if [regexp {^%0 } $clipboard] {
		clipboard clear
# >> clipboard variable contains the metadata from the clipboard
	} elseif {![string equal {} [set clipboard [LoadReference 1]]]} {
# puts $clipboard
# >> clipboard variable contains the metadata from the clipboard directory (Isis case)
	} else {
		if {$rep == {}} {return 0}
		set metadataRep [Eval FindMetadataRep $rep]
		if ![file isdirectory $homePath/col/$metadataRep] {
			UpdateVariables $metadataRep	;# updates the keyRepositoryList
			set metadataRep {}
		}
		if {$metadataRep == {}} {
# no metadata found
			return 0
		}
		set clipboard {}
		set return 1
		foreach mRep [Eval FindAllLanguageVersions $metadataRep] {
			set lastChange1 [Eval GetLastChange $mRep]
			if ![file isdirectory $homePath/col/$mRep] {continue}	;# usefull when removing a metadata repository (ReloadDisplayText)
			set seconds [DirectoryMTime $homePath/col/$mRep/doc]
#			set seconds [Eval RepositoryMTime $mRep $homePath]
			set lastChange2 [clock format $seconds -format %Y:%m.%d.%H.%M.%S -gmt 1]
			if {$lastChange1 == "$lastChange2"} {
				continue
			}
			Load $homePath/col/$mRep/doc/@metadata.refer fileContent
			set clipboard [concat $clipboard $fileContent]
			set return 0
		}
# set xxx $return
# Store xxx C:/tmp/aaa auto 0 a
# puts $return
		if $return {return 0}	;# no metadata changes
# >> clipboard variable contains the metadata from the modified @metadata.refer file(s)
	}
# Load data from the clipboard and update metadataArray and repArray
#	set metadataList [LoadMetadata 0 $clipboard {} 1]	;# for add
# set xxx $clipboard
# Store xxx C:/tmp/aaa auto 0 a
#	set metadataList [LoadMetadata $clipboard]	;# for add
	set metadataList [LoadMetadata $clipboard {} $userName]	;# for add
	set metadata2List {}	;# for remove
# set xxx --$metadataList--
# Store xxx C:/tmp/aaa auto 0 a
# retorna vazio ....
	if {$rep == {}} {
		set return 1
	} else {
		set return 0
	}
# site
	set site $serverAddress

	array set metadataImport $metadataList
	set indices [array names metadataImport *-0,referencetype]
	foreach index $indices {
# add
		regexp {^(.*)-0} $index m metadataRep
# Update citationkey
		set citationkey [CreateCitationKey metadataImport $metadataRep-0 1]
		UpdateMetadataField $metadataRep citationkey $citationkey metadataList metadata2List
# Update citationkey - end
		set metadataList [concat $metadataList [Eval CreateExtraFields $metadataRep $site]]
# remove
		set metadata2List [concat $metadata2List [Eval GetMetadata $metadataRep-*]]
		set repName $metadataImport($metadataRep-0,repository)
		if {$repName == "$rep"} {set return 1}
	}
# puts $metadata2List
# puts $metadataList

if 0 {
# commented by GJFB on 2020-08-18
	Eval RemoveMetadata $metadata2List
	Eval AddMetadata $metadataList
} else {
	Eval UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
	Set saveMetadata 1
# Load data from the clipboard and update metadataArray and repArray - end
	return $return
}

# GetClipboard - end
# ----------------------------------------------------------------------
# UpdateHistory

proc UpdateHistory {rep versionStamp} {
# runs with post
	global col
	global repositoryProperties

# set xxx [list $rep $versionStamp]
# Store xxx C:/tmp/bbb.txt auto 0 a
# set xxx [CallTrace]
# Store xxx C:/tmp/bbb.txt auto 0 a
	lappend repositoryProperties($rep,history) $versionStamp
#	set numberOfVersions [llength $repositoryProperties($rep,history)]
#	if {$numberOfVersions > 5} {
#		set repositoryProperties($rep,history) [lreplace $repositoryProperties($rep,history) 0 0]
#	}
	Store repositoryProperties($rep,history) $col/$rep/service/history
}

# UpdateHistory - end
# ----------------------------------------------------------------------
# UpdateReferenceFileForLoCoInRep
# update $loCoInRep/service/reference

# not used 
proc UpdateReferenceFileForLoCoInRep2 {} {
# runs from post
	return	;# switchs off UpdateReferenceFileForLoCoInRep
	global referenceTable
	global col
	global loCoInRep
	if ![info exists loCoInRep] {return}	;# installation time
	set indices [array names referenceTable $loCoInRep,*]
	set reference {}
	foreach index $indices {
		regsub {.*,} $index {} calledRep
		lappend reference ../$col/col/$calledRep
	}
	set reference [join $reference \n]
	Store reference $col/$loCoInRep/service/reference
}

# UpdateReferenceFileForLoCoInRep - end
# ----------------------------------------------------------------------
# CallFocus

proc CallFocus {widget} {
# runs with start
	upvar focus focus
	regexp {\.[^.]*} $widget win	;# .dd or .window
	set focus [focus -displayof $win]
	focus $widget.entry
}

# CallFocus - end
# ----------------------------------------------------------------------
# DisplayMessage

proc DisplayMessage {message win {anchor {nw}} {relx {0}} {rely {0}} {x {0}} {y {0}}} {
# runs with start
	global displayMessageId1 displayMessageId2 displayMessage
	set displayMessage $message
#	set win [join [lreplace [split $message .] end end] .]
	set displayMessageId1 [after 1000 place $message -in $win \
		-anchor $anchor -relx $relx -rely $rely -x $x -y $y]
	set displayMessageId2 [after 5000 place forget $message]
#	raise $top
}

# DisplayMessage - end
# ----------------------------------------------------------------------
# DeleteMessage

proc DeleteMessage {} {
# runs with start
	global displayMessageId1 displayMessageId2 displayMessage
	after cancel $displayMessageId1
	after cancel $displayMessageId2
	place forget $displayMessage
}

# DeleteMessage - end
# ----------------------------------------------------------------------
# DisableEntry

proc DisableEntry {widget varName} {
# runs with start
#	global environmentArray
#	upvar #0 $varName var	;# dd(resultx)
	upvar focus focus
	if {[info exists focus] && \
		$focus != "$widget.entry" && \
		[winfo exists $focus]} {focus $focus}
	$widget.entry config -bg gray -fg gray -state disabled
	$widget.button1.1 configure -state disabled
	$widget.button2.2 configure -state disabled
	$widget.button3.3 configure -state disabled
	$widget.button4.4 configure -state disabled
	$widget.button5.5 configure -state disabled
	$widget.button6.6 configure -state disabled
	if [regexp {\.dir\.} $widget] {
		if {[winfo exists .xxdirectory] &&
			[winfo ismapped .xxdirectory]} {
			wm withdraw .xxdirectory
		}
	}
	if [regexp {\.rep\.} $widget] {
		if {[winfo exists .xxrepository] &&
			[winfo ismapped .xxrepository]} {
			wm withdraw .xxrepository
		}
	}
}

# DisableEntry - end
# ----------------------------------------------------------------------
# EnableEntry
# this procedure is called from DDDialog

proc EnableEntry {widget entryName varName {listName {}}} {
# runs with start
	upvar focus focus
# puts [CallTrace]
	regexp {^..} $varName xx	;# dd
	upvar #0 ${xx}Reverse reverse
	upvar #0 ${xx}Search search
#	set focus [focus -displayof .$xx]
	regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
	set focus [focus -displayof $win]
	$widget.entry xview moveto 1.0
#	SetBackgroundEntry $widget.entry $entryName $varName $listName
	$widget.entry configure -state normal	;# used in CompleteEntry
	if !$search {$widget.button1.1 configure -state normal}
	if !$search {$widget.button2.2 configure -state normal}
	$widget.button3.3 configure -state normal
	$widget.button4.4 configure -state normal
#	set bgColor [lindex [$widget.entry config -bg] end]
#	if {$bgColor == "#ffccff"} {
## is magenta
#		$widget.button5.5 configure -state normal
#	}
	if !$reverse {
# key first
		$widget.button6.6 configure -state normal
	}
	CompleteEntry $widget.entry $entryName $varName check
	$widget.entry configure -fg black	;# must be after CompleteEntry
	focus $widget.entry
}

# EnableEntry - end
# ----------------------------------------------------------------------
# CompleteEntry
# It is called originally at each key stroke
# the listName is used when the entryWidget name contains
# the strings .lis. or .ent. or .rep. and reverse == 0 (key first)
#
# Example:
# CompleteEntry .window.main.bc.rep.h2.entry.entry bcRepository bc(result1)
#

proc CompleteEntry {entryWidget entryName varName {flag {}} {inputString {}}} {
# runs with start
	global environmentArray
	global typeTable
	global listNameTable
	global homePath
	
	if [string equal {} $inputString] {
		upvar #0 $varName var
	} else {
# used by SearchEntry
		set var $inputString
	}
	upvar #0 $entryName xxEntry
	set listName $listNameTable($xxEntry)
	if {[lindex [$entryWidget configure -state] end] == "disabled"} {
		return
	}
	regexp {^(..)\(result(.)} $varName m xx index	;# dd 2
	set searchName ${xx}Search	;# ddSearch
	upvar #0 $searchName search
	if {[info exists search] && $search} {
		set type .sea.
	} else {
		set type $typeTable($xxEntry)
	}
	regsub {\.entry$} $entryWidget {} widget
	switch -regexp -- $type \
		{\.dir\.|\.lis\.} {
			set root $var
		} \
		{\.rep\.} {
# Drop ^*
# ^* in var leads to a regular expression error in CorrectPath
			if [regexp {^\*$} $var] {
				set string ""
				UpdateEntry $widget $entryName $type $string $varName $listName
				return
			}
# Drop ^* - end
			regsub {(..).*} $varName \
				{\1Reverse} reverseName	;# ddReverse
			upvar #0 $reverseName reverse
			if $reverse {
# repository first
				set root $homePath/col/$var
				set root [DeleteKey $root]	;# delete the key
			} else {
# key first
				set bgColor [lindex [$entryWidget config -bg] \
					end]
				if {$bgColor == "#ffccff"} {
# is magenta
					regsub {.* } $var {} rep
					if ![file isdirectory $homePath/col/$rep] {
# the repository has been deleted
# puts {the repository has been deleted}
# puts [CallTrace]
#						set metadataRep [Eval FindMetadataRep $rep]	
						set metadataRep [Eval FindMetadataRep2 $rep]	;# added by GJFB on 2014-09-11 in order to return using an old code of FindMetadataRep (code of 2011) that works even the repository has been deleted
# puts --$metadataRep--
						if ![file isdirectory $homePath/col/$metadataRep] {
							UpdateVariables $metadataRep	;# updates the keyRepositoryList
						}
#						Eval CheckMetadataConsistency $metadataRep-0	;# done in FindMetadataRep
						UpdateVariables $rep	;# updates the keyRepositoryList
						Eval UpdateVariables $rep
						SetIndicator $xx $entryWidget		;# uses the keyRepositoryList
					}
				}
				set root $var
			}
		} \
		{\.ent\.} {
			if ![info exists \
				environmentArray(${xxEntry}SelectMenu)] {
				set environmentArray(${xxEntry}SelectMenu) ""
			}
			UpdateMenu $widget $entryName $varName
			CheckConsistency $entryWidget $type $varName \
				$environmentArray(${xxEntry}SelectMenu) \
				$listName  
			set menu $widget.button3.3.menu
			CreateMenu $menu $widget $entryName $type $varName \
				$environmentArray(${xxEntry}SelectMenu) \
				$listName {    }
			if {$flag == "\t"} {
				set string [CompleteLine $listName $var]
			} else {
				set string $var
			}
			UpdateEntry $widget $entryName $type $string $varName $listName
			return
		} \
		{\.sea\.} {
 			if {$flag == "\r"} {
				SearchEntry $widget $entryName $xx $index
			} else {
#				set string $var
#				UpdateEntry $widget $entryName $type $string $varName $listName
			}
			return
		}

	if ![info exists reverse] {set reverse 0}	;# could be 0 or 1
	set root [CorrectPath $type $root $reverse $listName]
	if {$flag == "check"} {
		set string $root	;# string (nothing more to do)
	} else {
# puts 1-$root
		set inputList [GlobDir $root $type $reverse $listName]
# puts 2-$inputList
		set string [CommonRoot $inputList $root]	;# string
	}
	regsub {/\.$} $string {/} string		;# /. -> /
	if {$flag == "\b" && $var != "$string" || [regexp {^[A-Za-z]:$} $var]} {
# back space
#		regexp {\.([^.]*\.[^.]*)} $widget m prefix	;# dd.dir
		regexp ".*\.($xx\.\[^.\]*)" $widget m prefix	;# dd.dir
		upvar #0 ${prefix}PostMenu postMenu
		set postMenu 0
#		ReduceEntry $widget $entryName $varName $listName
		ReduceEntry $widget $entryName $varName
		return
	}
#	UpdateEntry $widget $entryName $type $string $varName $listName $fileList
	UpdateEntry $widget $entryName $type $string $varName $listName
}

# CompleteEntry - end
# ----------------------------------------------------------------------
# CommonRoot
# Return the first common characters

proc CommonRoot {inputList root} {
# find the common root in inputlist (new root)
	set firstListElement [lindex $inputList 0]
	set lengthOfFirst [string length $firstListElement]
	set rootLength [string length $root]
	for {set i $rootLength} {$i < $lengthOfFirst} {incr i} {
		set character [string index $firstListElement $i]
		foreach listElement $inputList {
			set end no
			if {$character != [string index $listElement $i]} {
				set end yes
				break
			}
		}
		if {$end == "yes"} {break}
	}
	incr i -1
	return [string range $firstListElement 0 $i]	;# new root
}

# CommonRoot - end
# ----------------------------------------------------------------------
# UpdateEntry
#
# Examples:
#
# UpdateEntry .window.main.bc.rep.h2.entry bcRepository .rep. \
# {Banon::EnURBa dpi.inpe.br/banon/1999/10.31.20.32} bc(result1) keyRepositoryList
#
# UpdateEntry .window.main.dd.dir.h1.h2.v2.entry ddDirectory .dir. \
# C:/ftp/ dd(result1) {}
# 
# UpdateEntry .window.main.dd.rep.h1.h2.v2.entry ddRepository .rep. \
# : dd(result2) keyRepositoryList
#

proc UpdateEntry {widget entryName type string varName listName} {
# runs with start
	global environmentArray
	upvar #0 $varName var
# puts [CallTrace]
# puts $string
	if [regexp {\.rep\.} $type] {
		set string [AddKey $string]
	}
#	$widget.entry delete 0 end
#	$widget.entry insert 0 $string	;# update the entry

# Set previous entry
	set bgColor [lindex [$widget.entry config -bg] end]
	if {$bgColor == "#ffccff"} {
# is magenta
# puts magenta
		set environmentArray(${entryName}PreviousMagentaEntry) $var
	} elseif {$bgColor == "#ccffff"} {
# is cyan
# puts cyan
		set environmentArray(${entryName}PreviousCyanEntry) $var
	}
# Set previous entry - end
# puts $environmentArray(${entryName}PreviousMagentaEntry) 
# puts $environmentArray(${entryName}PreviousCyanEntry) 

# >>> update the entry
	set var $string				;# >>> update the entry

	regexp {^..} $varName xx	;# dd
	if {$string == ""} {
# empty entry
		$widget.button1.1 configure -state disabled
		regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
#		upvar #0 ${xx}SearchEntry xxSearchEntry
		if ![FindSearchMode $xx $win] {
# search is not active
			$widget.button5.5 configure -state normal	;# Reverse Button
		}
	} else {
# non-empty entry
		upvar #0 ${xx}Search search
		if {![info exists search] || !$search} {$widget.button1.1 configure -state normal}
		$widget.button5.5 configure -state disabled
	}
	$widget.entry icursor end
	$widget.entry xview moveto 1.0
	SetBackgroundEntry $widget.entry $entryName $varName $listName

	UpdateMenu2 $widget $entryName $varName
# add a delay for the case of an empty "which" entry
	if ![regexp {\.sea\.} $type] {
		after 500 [list UpdateMenu $widget $entryName $varName]
	}
}

# UpdateEntry - end
# ----------------------------------------------------------------------
# DeleteKey
# Delete the key at the beginning or at the end

proc DeleteKey {string} {
#	regsub {(^.*/col/[^/]*/[^/]*/[^/]*/[^/]*) [^ ]*:[0-9]*:[^ ]*$} \
#		$string {\1/} string
#	return $string
	if [regsub { [^ ]*:.*:.*$|^.*:[^/]*:[^ ]* } \
		$string {} string] {return $string/}
	return $string
}

# DeleteKey - end
# ----------------------------------------------------------------------
# SetBackgroundEntry
# Example:
# SetBackgroundEntry .window.main.bc.rep.h2.entry.entry bcRepository bc(result1) keyRepositoryList
# SetBackgroundEntry .window.main.dd.rep.h1.h2.v2.entry.entry ddRepository dd(result2) keyRepositoryList

proc SetBackgroundEntry {entryWidget entryName varName {listName {}}} {
# runs with start
	global w
	global typeTable
	global homePath
	global ddChoice3
	global ddChoice3Old
	upvar #0 $varName var
	upvar #0 $entryName xxEntry
	upvar #0 $listName list
	
	set type $typeTable($xxEntry)
	set root $var
	switch -regexp -- $type \
		{\.dir\.} {
			if [regexp {/$} $root] {
				$entryWidget config -bg #ffccff	;# magenta
				DisplayText $entryWidget $entryName $varName .xxdirectory #dddddd 0
				if [regexp "$homePath/col/(\[^/\]*/\[^/\]*/\[^/\]*/\[^/\]*)/doc/" $root] {
					if ![string equal copy $ddChoice3] {set ddChoice3Old $ddChoice3}
					set ddChoice3 copy
					$w.main.dd.radio.f1.r1 configure -state normal
					$w.main.dd.radio.f2.r2 configure -state normal
# disable for security reason - doc must not be removed
					$w.main.dd.radio.f3.r3 configure -state disabled
				} else {
					if [info exists ddChoice3Old] {
						set ddChoice3 $ddChoice3Old
						unset ddChoice3Old
					}
					$w.main.dd.radio.f1.r1 configure -state normal
					$w.main.dd.radio.f2.r2 configure -state normal
					$w.main.dd.radio.f3.r3 configure -state normal
				}
			} else {
				$entryWidget config -bg #ffffff
				if [winfo exists .xxdirectory] {
					.xxdirectory.f.t configure -state normal
					.xxdirectory.f.t delete 1.0 end
				}
				$w.main.dd.radio.f1.r1 configure -state disabled
				$w.main.dd.radio.f2.r2 configure -state disabled
				$w.main.dd.radio.f3.r3 configure -state disabled
			}
		} \
		{\.rep\.} {
			regsub {(..).*} $varName \
				{\1Search} searchName	;# ddSearch
#			regexp {^..} $entryName xx
#			set searchName ${xx}Search	;# ddSearch
			upvar #0 $searchName search
			if $search {
				$entryWidget config -bg #ccffff	;# cyan
				DisableBCButtons $entryName
				return
			}
# widget
			regsub {.entry$} $entryWidget {} widget
# reverse
			regsub {(..).*} $varName \
				{\1Reverse} reverseName	;# ddReverse
			upvar #0 $reverseName reverse
			if $reverse {
# repository first
				if [regexp { } $root] {
					$entryWidget config -bg #ffccff	;# magenta
					DisplayText $entryWidget $entryName $varName .xxrepository #dddddd 0 1
					$widget.button4.4 configure -state normal
#					ControlBCButtonState $entryWidget $entryName $varName
				} else {
					$entryWidget config -bg #ffffff
					if [winfo exists .xxrepository] {
						.xxrepository.f.t \
							configure -state normal
						.xxrepository.f.t delete 1.0 end
					}
					$widget.button4.4 configure -state disabled
					DisableBCButtons $entryName
				}
			} else {
# key first
				if {[lsearch -exact $list $root] != -1} {
					$entryWidget config -bg #ffccff	;# magenta
					DisplayText $entryWidget $entryName $varName .xxrepository #dddddd 0 1
					$widget.button4.4 configure -state normal
#					ControlBCButtonState $entryWidget $entryName $varName
				} else {
					$entryWidget config -bg #ffffff
					if [winfo exists .xxrepository] {
						.xxrepository.f.t \
							configure -state normal
						.xxrepository.f.t delete 1.0 end
					}
					$widget.button4.4 configure -state disabled
					DisableBCButtons $entryName
				}
			}
		} \
		{\.lis\.} {
			if {[lsearch -exact $list $root] != -1} {
				$entryWidget config -bg #ffccff	;# magenta
			} else {
				$entryWidget config -bg #ffffff
			}
		} \
		{\.ent\.} {
			$entryWidget config -bg #ffffff
		}
}

# SetBackgroundEntry - end
# ----------------------------------------------------------------------
# ControlBCButtonState
# used in SetBackgroundEntry
# Example:
# ControlBCButtonState .window.main.bc.rep.h2.entry.entry bcRepository bc(result1)

proc ControlBCButtonState {entryWidget entryName varName} {
# runs with start

# Global for delete repository
	global urlibEnvironment
	global URLibServiceRepository
	global loCoInRep
	global loBiMiRep
	global apacheRepository
	global tclRepository
	global unZipRepository
	global zipRepository
	global homePath
# puts [CallTrace]
# puts [list $entryWidget $entryName $varName]
# Global for delete repository - end

	upvar #0 $varName var
#	DisableButtons

# Control the button state
	if {[string compare $entryName bcRepository] == 0} {
# rep
		if ![regexp {^(.*/.*/.*/.*) .+} $var m rep] {
			regexp {^.* (.*/.*/.*/.+)} $var m rep
		}
		if [info exists rep] {
			set contentTypeIsMetadata [Eval TestContentType $rep Metadata]
# Edit and Reload Buttons
# security issue (in the if below)
#			if {[GetDocumentState $rep] || \
#				![file exists $homePath/col/$rep/service/hostCollection]} #
			if {[GetDocumentState $rep] || 0} {
## contains the original document or hostCollection doesn't exist
# contains the original document
				.window.main.bc.button.reload.reload config -fg #000000
				.window.main.bc.rep.label.lb1.lb1 config -fg #999999
				.window.main.bc.rep.label.lb2.lb2 config -fg #999999
				.window.main.bc.rep.label.lb3.lb3 config -fg #999999
				.window.main.bc.rep.label.lb4.lb4 config -fg #999999
				if $contentTypeIsMetadata {
# a metadata
					.window.main.bc.button.edit.edit config -state disabled
				} else {
					.window.main.bc.button.edit.edit config -state normal
				}
				.window.main.bc.button.reload.reload config -state normal
# Set warning
# puts [Eval ComputeVersionState $rep]
# return
				if {[CheckRegistration $rep] && !$contentTypeIsMetadata} {
# puts marrom
					.window.main.bc.button.reload.reload config -fg #aa7700
					.window.main.bc.rep.label.lb2.lb2 config -fg #444444
				}
				if {![file exists $homePath/col/$rep/download/time] && !$contentTypeIsMetadata} {
## puts blue
#					.window.main.bc.button.reload.reload config -fg #0000bb
# puts marrom
					.window.main.bc.button.reload.reload config -fg #aa7700
					.window.main.bc.rep.label.lb3.lb3 config -fg #444444
				}
				if [file exists $homePath/col/$rep/service/notCaptured] {
# puts marrom
					.window.main.bc.button.reload.reload config -fg #aa7700
					.window.main.bc.rep.label.lb4.lb4 config -fg #444444
				}
#				if ![catch {foreach {state officialSite imageURL} [Eval ComputeVersionState $rep $loCoInRep] {break}}] #
				if ![catch {foreach {state officialSite imageURL} [Eval ComputeVersionState $rep] {break}}] {
# officialSite and imageURL not used
					array set stateTable {
						{Registered Original} {Official}
						{Modified Original} {Modified}
						{Copy of an Original} {Modified}
						{Modified Copy of an Original} {Modified}
						{Unchecked} {Unchecked}
					}
					set state $stateTable($state)
# puts $state
					if [string equal Modified $state] {
# puts red
						.window.main.bc.button.reload.reload config -fg #bb0000
						.window.main.bc.rep.label.lb1.lb1 config -fg #444444
					}
				}
# Set warning - end
			} else {
## doesn't contain the original document and hostCollection exists
# doesn't contain the original document
				if [file exists $homePath/col/$rep/service/notCaptured] {
					.window.main.bc.button.reload.reload config -state normal
# puts red
					.window.main.bc.button.reload.reload config -fg #bb0000
					.window.main.bc.rep.label.lb4.lb4 config -fg #000000
				} else {
					.window.main.bc.button.reload.reload config -state disabled
					.window.main.bc.rep.label.lb4.lb4 config -fg #999999
				}
				.window.main.bc.button.edit.edit config -state disabled
				.window.main.bc.rep.label.lb1.lb1 config -fg #999999
				.window.main.bc.rep.label.lb2.lb2 config -fg #999999
				.window.main.bc.rep.label.lb3.lb3 config -fg #999999
			}
# Edit and Reload Buttons - end

# Check remote repository registration
# the repository must not be deleted until it has been registered from its new host collection
			if [file exists $homePath/col/$rep/service/notRemotelyRegistered] {
				Load $homePath/col/$rep/service/notRemotelyRegistered fileContent	;# contains a server address
# MULTIPLE SUBMIT
				set command [list list CheckRegistration $rep]
				foreach {remoteServerName remoteURLibPort} [ReturnCommunicationAddress $fileContent] {break}
				set flag [MultipleExecute [list [list $remoteServerName $remoteURLibPort]] $command]
				if {[string compare {} $flag] != 0 && !$flag} {
# remotely registered
					file delete $homePath/col/$rep/service/notRemotelyRegistered
				}
			}
# Check remote repository registration - end

# Delete Button
			if ![info exists urlibEnvironment] {
				set urlibEnvironment [Eval GetCitedRepositoryList $URLibServiceRepository]
				lappend urlibEnvironment $URLibServiceRepository
				if [info exists apacheRepository] {lappend urlibEnvironment $apacheRepository}
				lappend urlibEnvironment $tclRepository
				lappend urlibEnvironment $unZipRepository
				lappend urlibEnvironment $zipRepository
				lappend urlibEnvironment $loCoInRep
				lappend urlibEnvironment $loBiMiRep
			}
# puts $urlibEnvironment
# puts 1-[.window.main.bc.button.delete.delete config -state]
			set reason 0
			if {[lsearch -exact $urlibEnvironment $rep] != -1} {
# don't delete, the repository is part of the URLib environment
				set reason {1 - the Delete button is disabled because the repository is part of the URLib environment}
				.window.main.bc.button.delete.delete config -state disabled
			} elseif {1 && [TestDirectoryContent $homePath/col/$rep/auxdoc {cgi2/.htaccess cgi2/.htaccess2 cgi2/update cgi2/review returnPathArray.tcl}]} {
# don't delete, the auxdoc directory is not empty
				set reason {2 - the Delete button is disabled because the auxdoc directory is not empty}
				.window.main.bc.button.delete.delete config -state disabled
#			# elseif [TestDirectoryContent $homePath/col/$rep/source] #	;# commented by GJFB on 2025-11-17
			} elseif [TestDirectoryContent $homePath/col/$rep/source {.htaccess .htaccess2}] {	;# added by GJFB on 2025-11-17
# don't delete, the source directory is not empty
				set reason {3 - the Delete button is disabled because the source directory is not empty}
				.window.main.bc.button.delete.delete config -state disabled
			} elseif [TestDirectoryContent $homePath/col/$rep/not_sent] {
# don't delete, the not_sent directory is not empty (for URLibService Version 1.1)
				set reason {4 - the Delete button is disabled because the not_sent directory is not empty}
				.window.main.bc.button.delete.delete config -state disabled
			} elseif {[file exists $homePath/col/$rep/service/notRemotelyRegistered] && \
				![file exists $homePath/col/$rep/service/notRegistered]} {
# don't delete, the repository has been localy but not remotely registered
				set reason {5 - the Delete button is disabled because the repository has been localy but not remotely registere}
				.window.main.bc.button.delete.delete config -state disabled
			} elseif [file exists $homePath/col/$rep/service/notCaptured] {
# don't delete, the repository has not been captured
				set reason {6 - the Delete button is disabled because the repository has not been captured}
				.window.main.bc.button.delete.delete config -state disabled
			} elseif [file exists $homePath/col/$rep/service/citingItemList] {
# don't delete, the repository has citing items - added by GJFB on 2024-01-04
if 1 {
# added by GJFB on 2024-05-02 for migration reason
				source $homePath/col/$rep/service/citingItemList	;# citingArray
				if [info exists citingArray] {
					set reason {7 - the Delete button is disabled because the repository has citing items}
					.window.main.bc.button.delete.delete config -state disabled
				} else {
					file delete $homePath/col/$rep/service/citingItemList	;# added by GJFB on 2024-05-02
					.window.main.bc.button.delete.delete config -state normal
				}
} else {
				set reason 7
				.window.main.bc.button.delete.delete config -state disabled
}
			} else {
				set childRepList [GetCitingRepositoryList- $rep $entryWidget $varName]
				if {[llength $childRepList] != 0} {
# don't delete, the repository has children
					if $contentTypeIsMetadata {
# a metadata
						set parentRepList [Eval GetCitedRepositoryList $rep]
						if {[llength $parentRepList] > 1} {
# not the first metadata
							.window.main.bc.button.delete.delete config -state normal
						} else {
# the first metadada
							set reason {8 - the Delete button is disabled because the metadata repository has children}
							.window.main.bc.button.delete.delete config -state disabled
						}
					} else {
# not a metadata
						set reason {9 - the Delete button is disabled because the repository has children}
						.window.main.bc.button.delete.delete config -state disabled
					}
				} else {
# no child
					.window.main.bc.button.delete.delete config -state normal
				}
			}
			catch {puts "reason = $reason"}	;# catch required when transferring copyright - catches the error: 'error writing "stdout": I/O error'
# Delete Button - end
		}
	}
# puts 2-[.window.main.bc.button.delete.delete config -state]
# Control the button state - end
}

# ControlBCButtonState - end
# ----------------------------------------------------------------------
# DisableBCButtons
# used in SetBackgroundEntry

proc DisableBCButtons {entryName} {
#	DisableButtons
# puts [CallTrace]
	if {[string compare $entryName bcRepository] == 0} {
		.window.main.bc.button.edit.edit config -state disabled
		.window.main.bc.button.reload.reload config -state disabled
		.window.main.bc.button.delete.delete config -state disabled
		.window.main.bc.rep.label.lb1.lb1 config -fg #999999
		.window.main.bc.rep.label.lb2.lb2 config -fg #999999
		.window.main.bc.rep.label.lb3.lb3 config -fg #999999
		.window.main.bc.rep.label.lb4.lb4 config -fg #999999
	}		
}

# DisableBCButtons - end
# ----------------------------------------------------------------------
# GetDocumentState
# loose value is 0 or 1
# 1 means to consider that $rep contains the original document even
# the $loCoInRep appears just before the last element in hostCollection
# As of 2025-10-28 the loose option 1 was not used

# returns 1 if $rep contains the master (original document)
# (i.e., the host collection of $rep is the current collection)
# returns 0 otherwise

# similar code in ReturnState (see utilitiesMirror.tcl)

proc GetDocumentState {rep {loose 0}} {
# runs with start and post
	global loCoInRep

	set hostCollection [LoadHostCollection $rep]
	set lastHostCollection [lindex $hostCollection end]
	if [string equal $loCoInRep $lastHostCollection] {return 1}
	if $loose {
		set lastHostCollection2 [lindex $hostCollection end-1]
		if [string equal $loCoInRep $lastHostCollection2] {return 1}
	}
	return 0
}

# GetDocumentState - end
# ----------------------------------------------------------------------
# ReduceEntry
# Example:
# ReduceEntry .window.main.dd.rep.h1.h2.v2.entry ddRepository  dd(result2) 1

proc ReduceEntry {widget entryName varName {rightButton {0}}} {
# runs with start
	global typeTable	;# defined in DDDialog
	global listNameTable	;# defined in DDDialog
	global homePath
# puts [CallTrace]
	upvar #0 $varName var
	upvar #0 $entryName xxEntry
#	$widget.button2.2.menu unpost	;# has no effect
	set type $typeTable($xxEntry)
	regexp {^..} $varName xx	;# dd
	regexp ".*\.($xx\.\[^.\]*)" $widget m prefix	;# dd.dir
	regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
	upvar #0 ${prefix}PostponeReduceEntry postponeReduceEntry
	if $postponeReduceEntry {return}
	set postponeReduceEntry 1
	set searchMode [FindSearchMode $xx $win]
	if $searchMode {
		set listName ${xx}SelectedKeyRepList
	} else {
		set listName $listNameTable($xxEntry)
	}
# puts $listName
	if $rightButton {
# clear the entry
		set path ""
		if [regexp {\.dir\.} $type] {
			regexp {^[A-Za-z]:/} $var path
		}
		if {$path == ""} {
			$widget.button1.1 configure -state disabled
			if !$searchMode {
# search is not active
				$widget.button5.5 configure -state normal
			}
		}
		UpdateEntry $widget $entryName $type $path $varName $listName
		return
	}
	if [regexp {\.dir\.|\.lis\.|\.ent\.} $type] {
		set path $var
		set lowerBound 0
	} else {
# \.rep\.
#		regsub {([^\(]*)[^12]*(.)\)} $varName \
			{\1Reverse\2} reverseName	;# ddReverse2
		regsub {(..).*} $varName \
			{\1Reverse} reverseName	;# ddReverse
		upvar #0 $reverseName reverse
		if $reverse {
# repository first
			set path $homePath/col/$var
			set path [DeleteKey $path]	;# delete the key
			set lowerBound [string length $homePath/col/]
			incr lowerBound -1
		} else {
# key first
			set path $var
			set lowerBound 0
		}
	}
# the path could be out-of-date
	if ![info exists reverse] {set reverse 0}	;# could be 0 or 1 
	set path [CorrectPath $type $path $reverse $listName]
#
	regsub {^[A-Za-z]:/?$} $path {} path	;# c:/ or c: -> {}
	set length [string length $path]
	for {set i [expr $length - 1]} {$i >= $lowerBound} {incr i -1} {
		set root [string range $path 0 $i]
		set inputList [GlobDir $root $type $reverse $listName]
		set root [CommonRoot $inputList $root]	;# new root
		set rootLength [string length $root]
		if {$rootLength < $length} {
			UpdateEntry $widget $entryName $type $root $varName \
				$listName
			return
		}
	}
	UpdateEntry $widget $entryName $type "" $varName $listName
}

# ReduceEntry - end
# ----------------------------------------------------------------------
# ReverseEntry

proc ReverseEntry {widget entryName varName index} {
# runs with start
	global w
#	upvar #0 ${varName}Reverse$index reverse
	upvar #0 ${varName}Reverse reverse
	upvar #0 ${varName}(result$index) var
	set bg [$w cget -bg]
	set nc [NewColor $w $bg]
	if $reverse {
		set reverse 0	;# key first
		$widget.button5.5 configure -bg $bg
		$widget.button6.6 configure -state normal
		if {$var != ""} {
			set var "[lrange $var 1 end] [lindex $var 0]"
		}
	} else {
		set reverse 1	;# repository first
		$widget.button5.5 configure -bg $nc
		$widget.button6.6 configure -state disabled
		if {$var != ""} {
			set i [expr [llength $var] - 2]
			set var "[lindex $var end] [lrange $var 0 $i]"
		}
	}
	UpdateMenu $widget $entryName ${varName}(result$index)
	UpdateMenu2 $widget $entryName ${varName}(result$index)
}

# ReverseEntry - end
# ----------------------------------------------------------------------
# SearchEntry
# state == 0 or 1, force search == state
# state == {}, do not force
# puts $widget
# => .dd.rep.h1.h2.v2.entry
# puts $entryName
# => spPreference
# puts $varName
# => dd
# puts $index
# => 2
# Example:
# SearchEntry .window.main.bc.rep.h2.entry bcRepository bc 1
# CancelSearch .window.main.bc.rep.h2.entry bcRepository bc(result1)

proc SearchEntry {widget entryName varName index {state {}}} {
# runs with start
	global environmentArray
	global listNameTable
	global w
	global xxSearchResult
	global homePath
	global loCoInRep
	
	upvar #0 ${varName}SearchResult xxSearchResult	;# ddSearchResult
	upvar #0 ${varName}SelectedKeyRepList xxSelectedKeyRepList	;# ddSelectedKeyRepList
	upvar #0 ${varName}SearchEntry xxSearchEntry	;# ddSearchEntry
	upvar #0 ${varName}Search search	;# ddSearch
	upvar #0 ${varName}(result$index) var	;# dd(result2)
	upvar #0 $entryName xxEntry	;# ddRepository
	CancelSearch $widget $entryName ${varName}(result$index)
#	set r1 $searchRepository
	set listName $listNameTable($xxEntry)
	if {$state != {}} {set search $state}
	set bg [$w cget -bg]
	set nc [NewColor $w $bg]
	if $search {
		$widget.button1.1 configure -state normal
		$widget.button2.2 configure -state normal
		$widget.button4.4 configure -state normal
		$widget.button6.6 configure -bg $bg
		set xxSearchEntry $var
		UpdateMenu2 $widget $entryName ${varName}(result$index) 0
		set search 0	;# must be after UpdateMenu2
#		set xxSearchResult [Submit $localURLibClientSocketId \
			[list ${r1}::MountSearch $var]]
#		if [regexp {<(.*)>} $xxSearchResult m error] 
#		if [catch {${r1}::MountSearch $var} xxSearchResult]
# SEARCH
# the next comment line is for texting search error
#		GetMetadataRepositories 0 $var no no 1 metadatalastupdate
		regexp {^..} $varName xx	;# dd
		regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
#		if [catch {Eval GetMetadataRepositories 0 $var no no 1 metadatalastupdate} \
			xxSearchResult] ;# Eval doesn't work because the output may content more than one list element 

		set mirrorRep {}

		Load $homePath/col/$loCoInRep/auxdoc/xxx data binary
		set data [UnShift $data]
		set administratorCodedPassword [lindex $data end]
# GET
		if [catch {MultipleEval GetMetadataRepositories $mirrorRep 0 $var no no 1 {} repArray $administratorCodedPassword} xxSearchResult] {
# this case could be eliminated (dropping catch)
# puts 1>>>$xxSearchResult
			if {$xx == "dd"} {set cmd $win.rep.h1.h1.lb2}
			if {$xx == "bc"} {set cmd $win.rep.h1.lb2}
			$cmd configure \
				-text [Translate {syntax error}] \
				-fg #ff0000
			SearchEntry $widget $entryName $varName $index
			return
		} else {
# puts 2>>>$xxSearchResult
			if [regexp "^\{<.*>\}$" $xxSearchResult] {
				if {$xx == "dd"} {set cmd $win.rep.h1.h1.lb2}
				if {$xx == "bc"} {set cmd $win.rep.h1.lb2}
				$cmd configure \
					-text [Translate {syntax error}] \
					-fg #ff0000
				SearchEntry $widget $entryName $varName $index
				return
			}
			set xxSelectedKeyRepList {}
			set xxSearchResult [Grep {-0$} $xxSearchResult]
# puts 3>>>$xxSearchResult
			foreach rep-i $xxSearchResult {
				regsub -- {-[^-]*$} ${rep-i} {} metadataRep
				set rep [Eval ReturnRepositoryName $metadataRep]
				lappend xxSelectedKeyRepList [AddKey $rep/ 0]
			}
			SetIndicator $varName $widget
		}
## >>> update the entry
#		set var [CompleteLine ${varName}SelectedKeyRepList ""]	;# >>> update the entry
		set inputString [CompleteLine ${varName}SelectedKeyRepList ""]
		CompleteEntry $widget.entry $entryName \
			${varName}(result$index) check $inputString	;# inputString needed to avoid using var when returning from a search (cf. mouse right click on S)
#		SetBackgroundEntry $widget.entry $entryName \
			${varName}(result$index) $listName	;# redundant
		$widget.entry xview moveto 1.0
		$widget.entry icursor end
	} else {
		set search 1
		$widget.button1.1 configure -state disabled
		$widget.button2.2 configure -state disabled
		$widget.button4.4 configure -state disabled
		$widget.button5.5 configure -state disabled
		$widget.button6.6 configure -bg $nc
		if [info exists xxSearchEntry] {
#			if {$xxSearchEntry == {}} {
#				set xvar {- }	;# set entry
#			} else {
				set xvar $xxSearchEntry	;# set entry
#			}
		} else {
			set xvar {}
#			set xvar {- }
		}
		UpdateEntry $widget $entryName .sea. $xvar \
			${varName}(result$index) {}
#		SetBackgroundEntry $widget.entry $entryName \
			${varName}(result$index)
#		$widget.entry configure -state normal
		$widget.entry icursor end
		UpdateMenu2 $widget $entryName ${varName}(result$index)
	}
}

# SearchEntry - end
# ----------------------------------------------------------------------
# UpdateMenu
# Update the menu for the Menu Button 2.2
# puts $widget
# => .dd.rep.h1.h2.v2.entry
# puts $entryName
# => ddRepository
# puts $varName
# => dd(result2)

proc UpdateMenu {widget entryName varName} {
# runs with start
	global typeTable	;# defined in DDDialog
	global listNameTable	;# defined in DDDialog
	global homePath
	global keyRepositoryList
	global environmentArray
	upvar #0 $varName var
	upvar #0 $entryName xxEntry	;# e.g. ddRepository
#	.dd configure -cursor watch
# puts [array get listNameTable]
# => ddRepository keyRepositoryList ddDirectory {} ddSearch {}
# puts $xxEntry
# => ddRepository
	set listName $listNameTable($xxEntry)
# puts $listName
# => keyRepositoryList
	set type $typeTable($xxEntry)
#	regexp {.(..)} $widget m xx	;# dd
#	regexp {\.(..)\.} $widget m xx	;# dd
	regexp {^..} $varName xx	;# dd
#	upvar #0 ${xx}SearchEntry xxSearchEntry
#	if {[regexp {\.rep\.} $type] && \
		[info exists xxSearchEntry] && $xxSearchEntry != ""}
	regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
	set searchMode [FindSearchMode $xx $win]
	if {[regexp {\.rep\.} $type] && $searchMode} {
		set listName ${xx}SelectedKeyRepList	;# ddSelectedKeyRepList
	}
	set menu $widget.button2.2.menu
	if [catch {$menu delete 0 end}] {return}	;# catch is to avoid problem with after
#	if {[string compare $var ""] != 0} {
#		$menu add command -label " .." -underline 2 \
#			-command "ReduceEntry $widget $entryName $varName"
#	}
	set hcpLength 0	;# home collection path length
	regsub {(..).*} $varName \
		{\1Reverse} reverseName	;# ddReverse
	upvar #0 $reverseName reverse
	if ![info exists reverse] {set reverse 0}	;# could be 0 or 1
	set repFirst [expr [regexp {\.rep\.} $type] && $reverse]
	if !$repFirst {
# not .rep. or key first
		set root $var
	} else {
# repository first
		set root $homePath/col/$var
	}
	if {$repFirst && [regexp { } $var]} {
#		set itemList [DeleteKey $root]	;# delete the key
		set itemList [list [DeleteKey $root]]	;# delete the key
	} else {
# puts 1-$root
		set root [CorrectPath $type $root $reverse $listName]
# puts 2-$root
		set inputList [GlobDir $root $type $reverse $listName]
# puts 1-$inputList
		set outputList ""
		foreach input $inputList {
			if !$repFirst {
				set output $input
			} else {
# $input == C:/usuario/gerald/URLib/col/test/test/1998/08.29.16.07/bib/
				if [regexp \
					{(^.*/col/[^/]*/[^/]*/[^/]*/[^/]*/).} \
					$input m outputList] {break}
# propagate the search to the next directories
				set inputList2 [GlobDir $input $type $reverse]
				set output [CommonRoot $inputList2 $input]
#
			}
			lappend outputList $output
		}
# puts 2-$outputList
# Update keyRepositoryList
# (these lists may not be complete)
		if $repFirst {
#			set storeKeyRepositoryListFlag 0
			foreach output $outputList {
				if [regexp {^.*/col/([^/]*/[^/]*/[^/]*/[^/]*)/$} $output m rep] {
#					set nOR [llength $keyRepositoryList]
					if [UpdateKeyRepositoryList $rep] {
##						StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
#						set storeKeyRepositoryListFlag 1
						Eval UpdateRepositoryListForPost $rep
					}
					if $searchMode {
# the selectedKeyRepositoryList must be updated in case of a search beeing displayed
						UpdateKeyRepositoryList $rep 0 ${xx}SelectedKeyRepList	;# ddSelectedKeyRepList
					}
					SetIndicator $xx $widget
				}
			}
#			if $storeKeyRepositoryListFlag {StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl}
		}
# Update keyRepositoryList - end
# puts 3-$outputList
		set listLength [llength $outputList]
		if {$listLength > 8} {
			set itemList [lsort -dictionary [MinMax $outputList $root]]
		} else {
			set itemList [lsort -dictionary $outputList]
		}
	}
# puts 4-$itemList
	set itemList [CheckConsistency $widget $type $varName $itemList $listName]
# puts 5-$itemList
	set rootLength [string length $root]
	set listLength [llength $itemList]
# 8 <= 10
	if {$listLength > 10} {
# too many lines - mount submenus
		set j 1	;# submenu number
		for {set i 0} {$i < $listLength} {incr i} {
			set currentItem [lindex $itemList $i]
			if $repFirst {
				set homeColPath ""	;# in case of no match
				regexp {^.*/col/} $currentItem homeColPath
				set hcpLength [string length $homeColPath]
				set currentItem [AddKey $currentItem]
#				regsub {^.*/col/} $currentItem {} currentItem
			}
			set firstCharacter1 \
				[string index $currentItem \
					[expr $rootLength - $hcpLength]]
			set nextItem [lindex $itemList [expr $i + 1]]
			if $repFirst {
				regsub {^.*/col/} $nextItem {} nextItem
			}
			set firstCharacter2 \
				[string index $nextItem \
					[expr $rootLength - $hcpLength]]
			regsub -all {\?} $firstCharacter1 {\?} firstCharacter1	;# ? -> \?
			if [regexp -nocase "$firstCharacter1" \
				$firstCharacter2] {
# cascade
				set yy [CutLabel $widget \
"$root\[$firstCharacter1$firstCharacter2\]"] 
				$menu add cascade \
					-label [lindex $yy 1] -menu $menu.sub$j
#				$menu add cascade \
					-label " $root\[$firstCharacter1$firstCharacter2\]" \
					-menu $menu.sub$j
				if ![winfo exists $menu.sub$j] {
					set subMenu [menu $menu.sub$j \
						-tearoff 0 \
						-font {courier 9 roman}]
				} else {
					set subMenu $menu.sub$j
				}
				$subMenu delete 0 end
				regsub "^$root" $currentItem {} \
					currentLabel
				$subMenu add command \
					-label $currentLabel \
					-command "UpdateEntry \
					$widget $entryName $type {$currentItem} \
					$varName {$listName}"
				regsub "^$root" $nextItem {} nextLabel
				$subMenu add command \
					-label $nextLabel \
					-command "UpdateEntry \
					$widget $entryName $type {$nextItem} \
					$varName {$listName}"
				incr i
				incr j
			} else {
# no cascade
				set yy [CutLabel $widget $currentItem] 
				$menu add command \
					-underline [expr $rootLength - \
						[lindex $yy 0] - $hcpLength + 1] \
					-label [lindex $yy 1] \
					-command "UpdateEntry \
					$widget $entryName $type {$currentItem} \
					$varName {$listName}"
			}
		}
# too many lines - end
	} else {
# puts $itemList
		CreateMenu $menu $widget $entryName $type $varName $itemList $listName { } $rootLength
	}
#	.dd configure -cursor arrow
#	regexp {\.([^.]*\.[^.]*)} $widget m prefix	;# dd.dir
	regexp ".*\.($xx\.\[^.\]*)" $widget m prefix	;# dd.dir
	upvar #0 ${prefix}PostMenu postMenu
	upvar #0 ${prefix}PostponeReduceEntry postponeReduceEntry
	set index [$menu index last]
	if !$searchMode {
# search is not active
		$widget.button5.5 configure -state normal
	}
	if {$index == 1} {
		set label [$menu entrycget 1 -label]
		set entry [lindex [CutLabel $widget [$widget.entry get]] 1]
		if {[string compare $label $entry] == 0} {
# terminal node; nothing to display
			$menu delete 0 end
			$widget.button2.2 configure -state disabled
			if $repFirst {
				regsub {([^\(]*)[^12]*(.)\)} $varName \
					{\1Choice\2} choiceName	;# ddChoice1
				upvar #0 $choiceName choice
				if ![regexp {^rep} $choice] {return}
			}
			set postMenu 0
			set postponeReduceEntry 0
			return
		}
	}
	if [regexp {\.dir\.|\.rep\.} $type] {
		regsub {([^\(]*)[^12]*(.)\)} $varName \
			{\1Choice\2} choiceName	;# ddChoice1
		upvar #0 $choiceName choice
		if ![regexp {^dir|^rep} $choice] {return}
	}
	$widget.button2.2 configure -state normal
# drop out undue underline
	set numberOfEntry [$menu index end]
	if {$numberOfEntry != "none"} {
# nonempty menu
		incr numberOfEntry
		set letter "xx"
		for {set i 0} {$i < $numberOfEntry} {incr i} {
			set index [$menu entrycget $i -underline]
			set label [$menu entrycget $i -label]
			set currentLetter [string index $label $index]
			if {[string compare $letter $currentLetter] == 0} {
# the letters are equal
				$menu entryconfigure $i -underline -1
				$menu entryconfigure [expr $i - 1] -underline -1
			} else {
# the letters are different
				set letter $currentLetter
			} 
		}
	}
# drop out undue underline - end
	if $postMenu {
# post the menu now
		set x [winfo rootx $widget.button2.2]
		set y [winfo rooty $widget.button2.2]
		set h [winfo height $widget.button2.2]
		$menu post $x [expr $y + $h]
	}
	set postponeReduceEntry 0
}

# UpdateMenu - end
# ----------------------------------------------------------------------
# CutLabel

proc CutLabel {widget label {blank { }}} {
# runs with start
# maxNumberOfCharacters
#	regexp {(\...)\.} $widget m win	;# .dd
#	set geo [wm geometry $win]
#	regexp {^([^x]+)x([^\+]+)\+([^\+]+)\+([^\+]+)$} $geo m W H X Y
	set W [winfo screenwidth .]
	set a [expr 23.0 / 208]
	set maxNumberOfCharacters \
		[expr round([expr $a * [expr $W - 635] + 45])]
	incr maxNumberOfCharacters
# maxNumberOfCharacters - end
	set labelLength [string length $label]
	set begin [Max [expr $labelLength - $maxNumberOfCharacters] 0]
#	set begin 0
	return [list $begin $blank[string range $label $begin end]]
}

# CutLabel - end
# ----------------------------------------------------------------------
# UpdateMenu2
# Update the menu for the S Menu Button
# listName example: keyRepositoryList

proc UpdateMenu2 {widget entryName varName {flag {1}}} {
# runs with start
	global environmentArray
	global typeTable	;# defined in DDDialog
	global listNameTable	;# defined in DDDialog
	global loCoInRep
	global loBiMiRep
	upvar #0 $varName var
	regexp {^..} $varName xx	;# dd
	set searchName ${xx}Search	;# ddSearch
	upvar #0 $searchName search
	if {[info exists search] && $search} {
		set xxEntry ${xx}Search
		set type .sea.
	} else {
		upvar #0 $entryName xxEntry	;# ddRepository
		set type $typeTable($xxEntry)
	}
	set listName $listNameTable($xxEntry)
	set menu $widget.button3.3.menu
	if ![info exists environmentArray(${xxEntry}SelectMenu)] {
		set environmentArray(${xxEntry}SelectMenu) ""
	}
	set list [UpdateList $type $varName \
		environmentArray(${xxEntry}SelectMenu) $var 10 $listName]
	set list [CheckConsistency $widget $type $varName $list $listName 0]
# Add loCoInRep and loBiMiRep
	if [regexp {\.rep\.} $type] {
		upvar #0 ${xx}Reverse reverse
		if ![regexp $loCoInRep $list] {lappend list [AddKey $loCoInRep/ $reverse]}
		if ![regexp $loBiMiRep $list] {lappend list [AddKey $loBiMiRep/ $reverse]}
	}
# Add loCoInRep and loBiMiRep - end
	set environmentArray(${xxEntry}SelectMenu) $list
	if $flag {CreateMenu $menu $widget $entryName $type $varName $list $listName {    }}
}

# UpdateMenu2 - end
# ----------------------------------------------------------------------
# UpdateList
# Update the menu for the S Menu Button adding one item
# referenceListName example: keyRepositoryList
# example: $varName == sp

proc UpdateList {type varName listName item maxNumberOfItems \
	{referenceListName {}}} {
# runs with start
	upvar #0 $listName list
	upvar #0 $referenceListName referenceList
# puts 1-$list
# puts 2-$referenceList
	if ![info exists list] {set list {}}
	if [regexp {\.sea\.} $type] {
		if [regexp {^- \*$} $item] {
# don't add this item
			return $list
		}
	}
	regsub {(..).*} $varName \
		{\1Reverse} reverseName	;# ddReverse
	upvar #0 $reverseName reverse
	if ![info exists reverse] {set reverse 0}	;# could be 0 or 1
	set repFirst [expr [regexp {\.rep\.} $type] && $reverse]
	set keyFirst [expr [regexp {\.rep\.} $type] && !$reverse]
	if {[lindex $list end] != "$item" && \
		![regexp {^$} $item]} {
		if {[regexp {\.dir\.} $type] && [regexp {/$} $item] || \
			$repFirst && [regexp { } $item] || \
			[regexp {\.lis\.|\.ent\.} $type] && \
				[lsearch -exact $referenceList $item] != -1 || \
			[regexp {\.sea\.} $type] || \
			$keyFirst && \
				[lsearch -exact $referenceList $item] != -1} {
# drop the item if it exists
			if {[set i [lsearch -exact $list $item]] != -1} {
				set list [lreplace $list $i $i]
			}
# drop the item if it exists - end
			lappend list $item
			set numberOfItems [llength $list]
			if {$numberOfItems > "$maxNumberOfItems"} {
				set list [lreplace $list 0 0]
			}
		}
	}
# uniform the list according to key or repository first
	if [regexp {\.rep\.} $type] {
		set repList ""
		set list2 ""
		foreach item $list {
			set rep [DeleteKey $item]
			if {[lsearch -exact $repList $rep] == -1} {
				lappend repList $rep
				lappend list2 [AddKey $rep $reverse]
			}
		}
		set list $list2
	}
# uniform the list according to key or repository first - end
	return $list
}

# UpdateList - end
# ----------------------------------------------------------------------
# CreateMenu
# listName example: keyRepositoryList
# Example:
# CreateMenu .window.main.bc.rep.h2.entry.button3.3.menu .window.main.bc.rep.h2.entry bcRepository .rep. bc(result1)
# {{Banon::CuBiMi iconet.com.br/banon/2001/04.28.19.50} {UL::LoCoIn dpi.inpe.br/banon/1999/01.09.22.14} {UL::LoBiMi dpi.inpe.br/banon/1999/06.19.17.00} {Banon::DoUREn iconet.com.br/banon/2000/12.30.22.40} {Banon::BaBi dpi.inpe.br/banon/1995/09.01.00.00} {Banon::BiFoEx dpi.inpe.br/banon/2000/12.04.16.26} {Banon::EnURBa dpi.inpe.br/banon/1999/11.02.00.46} {Banon::EnURBa dpi.inpe.br/banon/1999/11.01.17.04}}
# keyRepositoryList {    } -1

proc CreateMenu {menu widget entryName type varName itemList listName \
	blank {rootLength {-1}}} {
# runs with start
# puts [list $menu $widget $entryName $type $varName $itemList $listName $blank $rootLength]
#	global referenceTable
	global tcl_platform
	
	upvar #0 $varName var
#	upvar #0 $listName list

	$menu delete 0 end
#	if {[string compare $var ""] != 0 && $blank == " "} {
#		$menu add command -label " .." -underline 2 \
#			-command "ReduceEntry $widget $entryName $varName"
#	}
	if [regexp {\.sea\.} $type] {
		$menu add command -label "" \
			-command "UpdateEntry $widget $entryName $type \
				{} $varName {$listName}"
		$menu add command -label "    - *" \
			-command "UpdateEntry $widget $entryName $type \
				{- *} $varName {$listName}"
	}
	set hcpLength 0	;# home collection path length
	regsub {(..).*} $varName {\1Reverse} reverseName	;# ddReverse
	upvar #0 $reverseName reverse
	if ![info exists reverse] {set reverse 0}	;# could be 0 or 1
	set repFirst [expr [regexp {\.rep\.} $type] && $reverse]
	set itemList [lsort $itemList]
# puts [CallTrace]
	foreach item $itemList {
		set label $item
# puts $label
		if $repFirst {
			set homeColPath ""	;# in case of no match
			regexp {^.*/col/} $label homeColPath
			set hcpLength [string length $homeColPath]
# puts 1-$label
			set label [AddKey $label]
# puts 2-$label
		}
		set yy [CutLabel $widget $label $blank]
		set underline [expr $rootLength - [lindex $yy 0] - $hcpLength + 1]
# puts $yy
		set label [lindex $yy 1]
#		set underline [expr $rootLength - $hcpLength + 1] 
#		set label $blank$label
		if {$rootLength != -1 && \
			$underline <= [string length $label] && \
			$underline != 0} {
# > button and not a terminal node
# puts "UpdateEntry $widget $entryName $type {$item} $varName {$listName}"
			$menu add command \
				-underline $underline \
				-label $label \
				-command "UpdateEntry $widget $entryName $type \
					{$item} $varName {$listName}"
		} else {
# S button
			$menu add command \
				-label $label \
				-command "UpdateEntry $widget $entryName $type \
					{$item} $varName {$listName}"
		}
	}
	if {$tcl_platform(os) != "SunOS" && !$reverse} {
		if {[regexp {\.rep\.} $type] && [regexp {button3.3} $menu]} {
			regexp {^(..)\(result(.)} $varName m xx index	;# dd 2
			$menu add command -label [Translate {    Find}] -background #ccffff \
				-command "SearchEntry $widget $entryName $xx $index"
		}
	} else {
# Find entry doesn't work with SunOS/tcl 8.0.2p (the application aborts)
	}
}

# CreateMenu - end
# ----------------------------------------------------------------------
# CheckConsistency
# Check consistency of itemList and referenceList with respect to the
# current collection
# itemList example: environmentArray(${xxEntry}SelectMenu)
# referenceListName example: keyRepositoryList
# flag value is 0 or 1, when the flag value is 0 the items which are not
# in the referenceList are discarded, when the flag value is 1 the
# items are preserved (default value is 1)

proc CheckConsistency {w type varName itemList referenceListName \
	{flag {1}}} {
# runs with start
	global homePath
	upvar #0 $referenceListName referenceList
	if [regexp {\.rep\.} $type] {
# rep case
		regexp {^..} $varName xx	;# dd
		set reverseName ${xx}Reverse	;# ddReverse
		upvar #0 $reverseName reverse
		set outputList ""
		set updateIndicator 0
		foreach item $itemList {
# check if the item is in the referenceList
# rep
			if [info exists rep] {unset rep}
			if ![regexp {^(.*/.*/.*/.*) .+} $item m rep] {
				regexp {^.* (.*/.*/.*/.+)} $item m rep
			}
			if ![info exists rep] {
				lappend outputList $item
				continue
			}
			if $reverse {
# repository first
				set i [lsearch -regexp $referenceList $rep]
			} else {
# key first
				set i [lsearch -exact $referenceList $item]
			}
			if {$i != -1} {
# the item is in the referenceList
				if ![file isdirectory $homePath/col/$rep] {
# the repository has been deleted
					UpdateVariables $rep	;# updates the keyRepositoryList
					Eval UpdateVariables $rep
# Test for the existence of metadataRep(s)
# update metadataArray
					while {[set metadataRep [Eval FindMetadataRep $rep]] != {}} {}
					if ![file isdirectory $homePath/col/$metadataRep] {
						UpdateVariables $metadataRep	;# updates the keyRepositoryList
					}
# Test for the existence of metadataRep(s) - end
					set updateIndicator 1
				} else {
# the repository has not been deleted
					lappend outputList $item
				}
			} else {
# the item is not in the referenceList
				if $flag {lappend outputList $item}
			}
		}
		if $updateIndicator {SetIndicator $xx $w}
	}
	if ![info exists outputList] {set outputList $itemList}
	return $outputList
}

# CheckConsistency - end
# ----------------------------------------------------------------------
# UpdateVariables

proc UpdateVariables {rep} {
# runs with start and post
	global applicationName
	global keyRepositoryList
	global environmentArray
	global referenceTable
	global repositoryProperties

# set xxx $applicationName
# global homePath
# Store xxx $homePath/xxx auto 0 a
# set xxx $rep
# Store xxx $homePath/xxx auto 0 a
# set xxx [CallTrace]
# Store xxx $homePath/xxx auto 0 a
	
	if {$applicationName == "post"} {
# discard rep from referenceTable
		set flag1 [DiscardRepository $rep referenceTable]
# discard rep from repositoryProperties
		set flag2 [DiscardRepository $rep repositoryProperties]
# SAVE
		if {$flag1 || $flag2} {
#			StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
#			StoreArray referenceTable ../auxdoc/.referenceTable.tcl
			SaveRepositoryProperties
			SaveReferenceTable
			UpdateRepositoryListForPost $rep
		}
# SAVE - end
	}
	if {$applicationName == "start"} {
# discard rep from keyRepositoryList
# Store rep C:/tmp/bb2 ;# may contain an error message
		set i [lsearch -regexp $keyRepositoryList $rep$]
		if {$i != -1} {set keyRepositoryList [lreplace $keyRepositoryList $i $i]}
# discard rep from environmentArray(bcSelectedKeyRepList)
		if [info exists environmentArray(bcSelectedKeyRepList)] {
			set i [lsearch -regexp $environmentArray(bcSelectedKeyRepList) $rep$]
			if {$i != -1} {set environmentArray(bcSelectedKeyRepList) [lreplace $environmentArray(bcSelectedKeyRepList) $i $i]}
		}
# discard rep from environmentArray(ddSelectedKeyRepList)
		if [info exists environmentArray(ddSelectedKeyRepList)] {
			set i [lsearch -regexp $environmentArray(ddSelectedKeyRepList) $rep$]
			if {$i != -1} {set environmentArray(ddSelectedKeyRepList) [lreplace $environmentArray(ddSelectedKeyRepList) $i $i]}
		}
	}
}

# UpdateVariables - end
# ----------------------------------------------------------------------
# CorrectPath
# Find the longest correct path within a given path
# if [regexp {\.rep\.} $widget] == 1 then
# reverse == 0 (means key first); == 1 (means repository first)
# otherwise the reverse value has no special meaning


proc CorrectPath {type path reverse listName} {
# runs with start
	global tcl_platform
	
	upvar #0 $listName list
	
# puts [CallTrace]
# puts 1-$path
	if {[regexp {\.dir\.} $type] || [regexp {\.rep\.} $type] && $reverse} {
		if {$tcl_platform(platform) == "unix"} {
			if ![regexp {^/} $path] {
				set path "/"	;# should be absolute
			}
		}
		if {$tcl_platform(platform) == "windows"} {
			regsub {^[a-zA-Z]$} $path {&:} path	;# c -> c:
			if ![regexp {^.:|^/} $path] {
				set path ""		;# should be absolute
			}
		}
		set correctPath ""
		foreach fileName [file split $path] {
			set testedPath $correctPath
			lappend testedPath $fileName
			set name [eval file join $testedPath]
# problem with glob
# dir... == dir (windows)
			regsub {[^/]\.+$} $name {*} name	;# dir. -> dir*
			set name [join [glob -nocomplain -- $name]]
# join is necessary in case of directory name with blank
# as in "New Folder". In this case, glob return is {C:/tmp/New Folder}.
#
			if {$name != "" && [file isdirectory $name]} {
				set correctPath [file split $name]
			} else {
				break
			}
		}
# puts 2-$correctPath
		if {$correctPath == ""} {return ""}
		set name [eval file join $correctPath]
		regsub {([^/]$)} $name {\1/} name	;# add missing trailing /
# puts "name = $name"
		set length [string length $name]
		set pathLength [string length $path]
# puts "path = $path"
		for {set i $length} {$i < $pathLength} {incr i} {
			set pattern [string range $path 0 $i]
# puts "pattern = $pattern"
			set globResult [glob -nocomplain -- $pattern*]
# puts "globResult = $globResult"
			set directoryList ""
			foreach fileName $globResult {
				if [file isdirectory $fileName] {
					lappend directoryList $fileName
				}
			}
# puts "directoryList = $directoryList"
			set grepResult [Grep $pattern $directoryList]	;# i I
# puts "grepResult = $grepResult"
			if {$grepResult == ""} {break}
		}
		incr i -1
		set string [string range $path 0 $i]
		regsub {/\./$} $string {/} string	;# /./ -> / (simplifying)
# puts 3-$string
		return $string
	} else {
		if !$reverse {set path [AddKey $path 0]}
		set length [string length $path]
#		set root ""
# puts --$path--
		for {set i 0} {$i < $length} {incr i} {
			set pattern [string range $path 0 $i]	;# por (i = 2)
# puts $i
# puts --$pattern--
			set end ""
			foreach item $list {
				regsub -all {\*} $pattern {\*} pattern	;# * -> \*
				regsub -all {\+} $pattern {\+} pattern	;# + -> \+
				regsub -all {\?} $pattern {\?} pattern	;# ? -> \?
				if [regexp "^$pattern" $item] {
					set end continue
					break
				}
			}
			if {$end == "continue"} {continue}
			break
		}
		incr i -1
		set string [string range $path 0 $i]
		return $string
	}
}

# set list {}
# puts [CorrectPath .dir. {/Program Files/Accessoies/aux} 0 list]
# => /Program Files/Accesso
# set list {{english} {portuguese} {french} {spanish}}
# puts [CorrectPath .lis. porttuguese 0 list]
# => port
# set list {{banon@dpi.inpe.br} {teste@teste}}
# puts [CorrectPath .ent. bannon 0 list]
# => ban 

# CorrectPath - end
# ----------------------------------------------------------------------
# Rootx
# Return the list of "${root}first character" of list elements
# used in MinMax

proc Rootx {inputList {root {}}} {
	set outputList ""
	set previousRootx ""
	foreach listElement [lsort $inputList] {
		regexp "^$root." $listElement rootx
		if ![info exists rootx] {return}
		if ![string equal $previousRootx $rootx] {
			lappend outputList $rootx
			set previousRootx $rootx
		}
	}
	return $outputList
}

# puts [Rootx {bs b ansi abc swr}]
# => a b s	
# puts [Rootx {c:/bs c:/b c:/ansi c:/abc c:/swr} c:/]
# => c:/a c:/b c:/s

# Rootx - end
# ----------------------------------------------------------------------
# GlobDir
# Return a list of directory names matching a pattern 
# if [regexp {\.rep\.} $type] == 1 then
# reverse == 0 (means key first); == 1 (means repository first)
# otherwise the reverse value has no special meaning

proc GlobDir {pattern type reverse {list2Name {defaultList}}} {
	global tcl_platform
	upvar #0 $list2Name list2
	
	if {[regexp {\.dir\.} $type] || [regexp {\.rep\.} $type] && $reverse} {
		set list ""
		if {$pattern == {}} {
			foreach letter {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} {
				if ![catch {glob $letter:/}] {
					lappend list $letter:/
				}
			}
			if {$list == ""} {set list [glob /*]}
		} else {
			regsub {^([a-z]):?$} $pattern {\1:/} pattern	;# c: -> c:/ or c -> c:/
# puts $pattern
			if [regexp {/$} $pattern] {
				if {[string equal {windows} $tcl_platform(platform)] && [info tclversion] == 8.5} {
					set globResult [glob -nocomplain -- $pattern*]	;# if pattern == C:/ then tcl 8.5 returns an error: couldn't read directory "C:/.*": no such file or directory (this error doesn't occur with tcl 8.4 and tcl 8.6)
				} else {
					set globResult [glob -nocomplain -- $pattern* $pattern.*]
				}
			} else {
# puts [glob dpi.inpe* dpi.inpe.*]
# => dpi.inpe.br dpi.inpe.br
# should be => dpi.inpe.br
				set globResult [glob -nocomplain -- $pattern*]
			}
			set grepResult [Grep $pattern $globResult]	;# i I
			foreach fileName $grepResult {
				if {[file isdirectory $fileName] && \
					![regexp {/\.$|/\.\.$} $fileName]} {
					lappend list $fileName/
				}
			}
		}
# propagate the search to the next directories
		if [regexp {\.rep\.} $type] {
			if {[llength $list] == 1} {
				set list [GlobDir [join $list] $type $reverse]
			}
		}
#		
		if {[llength $list] == 0} {
#			regsub {/$} $pattern {} list
#			set list [list $list] ;# {xx cc}
			set list [list $pattern] ;# {xx cc}
		}
# puts $list
	} else {
		set list [Grep "^$pattern" $list2]
	}
	return $list
}

# puts [GlobDir {} .dir 0]
# => c:/ d:/
# puts [GlobDir {c:/*} .dir 0]
# puts [GlobDir {c:/zzz*} .dir 0]
# =>			;# empty line
# puts [GlobDir {c:/usuari*} .dir 0]

# Globdir - end 
# ----------------------------------------------------------------------
# MinMax
# Return the minimum list containing the maximum strings
# root must be contained in the intersection of inputList

proc MinMax {inputList root} {
	set root [CommonRoot $inputList $root]	;# new root
	set rootLength [string length $root]
	set outputList ""
	if {[join $inputList] == $root} {
		lappend outputList [join $inputList]
		return $outputList
	}
	foreach rootx [Rootx $inputList $root] {
		set list [Grep "^$rootx" $inputList]
		set firstElement [lindex $list 0]
		set length [string length $firstElement]
		if {$length == [expr $rootLength + 1] || \
			[llength $list] == 1} {
			lappend outputList $firstElement
		} else {
			for {set i $rootLength} {$i < $length} {incr i} {
				foreach otherElement [lrange $list 1 end] {
					set end no
					if {[string index $firstElement $i] != \
						[string index $otherElement $i]} {
						set end yes
						break
					}
				}
				if {$end == "yes"} {break}
			}
			incr i -1
			lappend outputList [string range $firstElement 0 $i]
		}
	}
	return $outputList
}

# puts [MinMax {c:/usuario/gerald c:/usuario/gabi c:/usuario/lise} \
c:/usuario]
# => c:/usuario/g c:/usuario/lise

# MinMax - end
# ----------------------------------------------------------------------
# CompleteLine

proc CompleteLine {listName root} {
# runs with start
	upvar #0 $listName inputList
	set list [Grep "^$root" $inputList]
	if {$list == ""} {return $root}
# find the length of the shortest item
	set length 1000
	foreach item $list {
		set length [Min $length [string length $item]]
	}
#
	set rootLength [string length $root]
	for {set i $rootLength} {$i < $length} {incr i} {
		set letter [string index [lindex $list 0] $i]
		foreach item $list {
			if {$letter != "[string index $item $i]"} {
				incr i -1
				set length $i
				break
			}			
		}
	}
	return [string range [lindex $list 0] 0 $length]
}
# set list {c:/usuario/gerald c:/usuario/gabi c:/usuario/lise}
# puts [CompleteLine list c:/usua]
# => c:/usuario/	
# puts [CompleteLine list c:/usuario/l]
# => c:/usuario/lise
# puts [CompleteLine list c:/usuario/p]
# => c:usuario/p
	
# CompleteLine - end
# ----------------------------------------------------------------------
# NewColor
# Computing a new color.
# Example 35-2

proc NewColor {win color} {
# runs with start
	set rgb [winfo rgb $win $color]
	set mx [Max [lindex $rgb 0] \
		[Max [lindex $rgb 1] [lindex $rgb 2]]]
	set wht [winfo rgb $win white]
	if {$mx < [expr [lindex $wht 0] / 1.4]} {
		return [format "#%03x%03x%03x" \
		[expr round([lindex $rgb 0] * 0.85)] \
		[expr round([lindex $rgb 1] * 0.85)] \
		[expr round([lindex $rgb 2] * 0.85)]]
	} else {
		return [format "#%03x%03x%03x" \
		[expr round([lindex $rgb 0] * 1.15)] \
		[expr round([lindex $rgb 1] * 1.15)] \
		[expr round([lindex $rgb 2] * 1.15)]]
	}
}

# NewColor -end
# ----------------------------------------------------------------------
# Enter
# for help effect
# background values are 0 or 1
# 1 means to process the background
# 0 means to process the foreground
# color values are for example #bb0000 or #000000
# they are used for the foreground

proc Enter {text targets tagName {background 1} {color1 #bb0000} {color2 #000000}} {
# runs with start
	global w
	global reloadButtonForegroundColor
	$text tag configure $tagName -foreground #0000ff
	if $background {
		set bg [$w cget -bg]
		set nc [NewColor $w $bg]
		foreach target $targets {
			if {[$target cget -bg] == "$bg"} {
				$target configure -background $nc
			} else {
				$target configure -background $bg
			}
		}
	} else {
# used for the Reload Button
		set target $targets
		set reloadButtonForegroundColor [$target cget -fg]
		if {$reloadButtonForegroundColor == "$color1"} {
			$target configure -foreground $color2
		} else {
			$target configure -foreground $color1
		}
	}
}

# Enter - end
# ----------------------------------------------------------------------
# Leave
# for help effect
# background values are 0 or 1
# 1 means to process the background
# 0 means to process the foreground
# color values are for example #bb0000 or #000000
# they are used for the foreground

proc Leave {text targets tagName {background 1} {color1 #bb0000} {color2 #000000}} {
# runs with start
	global w
	global reloadButtonForegroundColor
	$text tag configure $tagName -foreground #000099
	if $background {
		set bg [$w cget -bg]
		set nc [NewColor $w $bg]
		foreach target $targets {
			if {[$target cget -bg] == "$bg"} {
				$target configure -background $nc
			} else {
				$target configure -background $bg
			}
		}
	} else {
# used for the Reload Button
		set target $targets
		$target configure -foreground $reloadButtonForegroundColor
	}
}

# Leave - end
# ----------------------------------------------------------------------
# TagBind
# background values are 0 or 1
# 1 means to process the background
# 0 means to process the foreground
# color values are for example #bb0000 or #000000
# they are used for the foreground

proc TagBind {t tagName targets {form {}} {background 1} {color1 #bb0000} {color2 #000000}} {
# runs with start
#	if [regexp {^\...\.definition} [join $targets]] 
	if [regexp {\.definition} [join $targets]] {
# for definition, e.g. .window.main.definition
# tagName is used as a definition name
		$t tag bind $tagName <1> \
			"PlaceDefinition {$tagName} $targets"
		$t tag bind $tagName <Enter> "$t config -cursor hand2"
		$t tag bind $tagName <Leave> "$t config -cursor double_arrow"
	} else {
# for help effect
		regexp {(.*\...)\.} $targets m win	;# .sp or .window.main.sp
		$t tag bind $tagName <Enter> "
			if ![regexp {^$} $form] {
				ProcessPreferenceButtons $win $form
			} 
			Enter $t {$targets} {$tagName} {$background} {$color1} {$color2}
		"
		$t tag bind $tagName <Leave> "
			Leave $t {$targets} {$tagName} {$background} {$color1} {$color2}
		"
	}
}

# TagBind - end
# ----------------------------------------------------------------------
# PlaceDefinition
# puts $t
# => .dd.definition or .window.main.dd.definition
# Example:
# PlaceDefinition document .window.main.definition

proc PlaceDefinition {definitionName t} {
#	regexp {\.[^.]*} $t win	;# .dd
#	regexp {(\...)\.} $t m win	;# .dd
#	regexp {(.*\...)\.} $t m parent	;# .dd or .window.main.dd
	regsub {.definition} $t {} parent	;# .window.main
	eval [list $definitionName $t]	;# insert text in $t
	set text [split [$t get 1.0 end] \n]
	set numberOfLines 0
	foreach line $text {
	set numberOfLines [expr int($numberOfLines + \
		ceil((1 + [string length $line].) / 55))]
# we add 1 because of the blank line
	}
#	set offset [expr (24 / ($numberOfLines + 2.)) / 100. + .5]
	set width 50
	$parent.definition configure -width $width \
		-height $numberOfLines 
	$parent.umbra configure -width $width \
		-height $numberOfLines 
	place $parent.definition -in $parent -anchor center \
				-relx .5 -rely .5
	place $parent.umbra -in $parent -anchor center \
				-relx .51 -rely .511
}

# PlaceDefinition - end
# ----------------------------------------------------------------------
# ProcessButton1
# Examples:
# ProcessButton1 .window.main.dd
# ProcessButton1 .window.main.bc
# ProcessButton1 .window.main.bc.rep.h2.entry.entry

proc ProcessButton1 {win} {
# runs with start
	global w
	regexp "($w.\[^\.\]*)\.(..)" $win m parent xx	;# .window.main dd
	if [regexp {.dd$} $win] {
		upvar #0 $xx.dirPostMenu dirPostMenu
		upvar #0 $xx.repPostMenu repPostMenu
		upvar #0 $xx.dirPostponeReduceEntry dirPostponeReduceEntry
		upvar #0 $xx.repPostponeReduceEntry repPostponeReduceEntry
		set dirPostMenu 0
		set repPostMenu 0
		set dirPostponeReduceEntry 0
		set repPostponeReduceEntry 0
	}
	if [regexp {.sp$} $win] {
		upvar #0 $xx.prePostMenu prePostMenu
		upvar #0 $xx.prePostponeReduceEntry prePostponeReduceEntry
		set prePostMenu 0
		set prePostponeReduceEntry 0
	}
	if [regexp {.bc$} $win] {
		upvar #0 $xx.repPostMenu repPostMenu
		upvar #0 $xx.repPostponeReduceEntry repPostponeReduceEntry
		set repPostMenu 0
		set repPostponeReduceEntry 0
	}
# forget definition
	if [winfo exists $parent.definition] {
		if [winfo ismapped $parent.definition] {
			place forget $parent.definition
			place forget $parent.umbra
		}
	}
}

# ProcessButton1 - end
# ----------------------------------------------------------------------
# Header
# used in XXDialog

proc Header {win title} {
# runs with start
# title
 	label $win.lb
	ConfigText $win.lb $title
	set font [lindex [$win.lb configure -font] end]
	$win.lb configure -font {$font 11 roman} -fg #666666
# help button
#	button $win.help -cursor hand2
#	ConfigText $win.help "Help"
# extra space
#	frame $win.sp1 -height .3c
}

# Header - end
# ----------------------------------------------------------------------
# Footer
# used in XXDialog
# Example:
# Footer .window.main.dd dd(ok)

proc Footer {entryWidget varName} {
# runs with start
# buttons
	global homePath
	global tcl_platform
	global loCoInRep
#	global endNoteRepository
	regexp {^..} $varName xx	;# dd
	set f .$xx	;# .dd
	regsub "$f" $entryWidget {} win	;# .window.main
	set width 2.2
	set height .6
	set b [frame $entryWidget.buttons -width 10.4c -height .8c]
	set bok [frame $b.ok -width [format "%sc" $width] \
			-height [format "%sc" $height]]
	set bsp1 [frame $b.sp1 -width .2c] ;# extra space
	set bcancel [frame $b.cancel -width [format "%sc" $width] \
			-height [format "%sc" $height]]
	set bedit [frame $b.edit -width [format "%sc" $width] \
			-height [format "%sc" $height]]
	set bsp2 [frame $b.sp2 -width .2c] ;# extra space
	set bhelp [frame $b.help -width [format "%sc" $width] \
			-height [format "%sc" $height]]
	button $bok.ok -command "OK $xx" -cursor hand2
	ConfigText $bok.ok OK
	button $bcancel.cancel -command "Cancel $xx" -cursor hand2
	ConfigText $bcancel.cancel Cancel
# puts $bedit.edit
# => .window.main.dd.buttons.edit.edit
#	if {$tcl_platform(platform) == "windows"}
	menubutton $bedit.edit \
		-cursor hand2 -relief raised -menu $bedit.edit.menu
	menu $bedit.edit.menu -tearoff 0
	bind $bedit.edit <1> [list CreateEditMenu $bedit.edit.menu \
		[list DisplayEditMetadata $entryWidget.rep.h1.h2.v2.entry.entry \
		ddRepository dd(result2) #dddddd]]	;# button press
	button $bhelp.help \
		-command "DisplayText $entryWidget {} $varName ${f}help #ffffcc" \
		-cursor hand2
	ConfigText $bedit.edit Edit
	ConfigText $bhelp.help Help
	pack propagate $b false
	pack propagate $bok false
	pack propagate $bcancel false
	pack propagate $bedit false
	pack propagate $bhelp false
	pack $bok -side left
	pack $bsp1 -side left
	pack $bcancel -side left
	pack $bhelp -side right
	if {$xx == "dd"} {pack $bsp2 $bedit -side right}
	pack $bok.ok -fill both
	pack $bcancel.cancel -fill both
	pack $bedit.edit -fill both
	pack $bhelp.help -fill both
# Definition window
	text $win.umbra -bg #777777 -relief flat \
		-padx .4c -pady .2c -wrap word
	text $win.definition -bg #ffffcc -relief flat \
		-padx .4c -pady .2c -wrap word
	set font [lindex [lindex [$win.definition configure -font] end] 0]
	$win.definition configure -font {$font 10}
	$win.umbra configure -font {$font 10}
# Definition window - end
	if {![info exists loCoInRep]} {
# disable cancel at installation
		$bcancel.cancel config -state disabled
	}
	return $b
}

# Footer - end
# ----------------------------------------------------------------------
# OK
# Example: OK dd

proc OK {xx} {
# runs with start
	global w
	global spSettingArray
	global languageTable
	global environmentArray
	global aBrowse
#	global dd bc
	global bcChoice1
	global bcSearch
	global installInitialCollection
	if [[string toupper $xx]OK $w.main.$xx 1] {return}	;# e.g., calls SPOK
#	pack forget $w.main.$xx
#	destroy $w.main.$xx
	destroy $w.main
# Source the current language
	if {$xx == "sp"} {
		set language $spSettingArray(spLanguageEntry)
		set environmentArray(spLanguageEntry) $language
		set environmentArray(serviceLanguageRepository) $languageTable($language)
		SourceLanguage environmentArray
	}
# Source the current language - end
	set environmentArray(bcChoice1) {}
	CreateMain 0
	[string toupper $xx]OK $w.main.$xx 0	;# e.g., calls SPOK
	destroy .xxdirectory
	destroy .xxrepository
#	set bc(result1) $dd(result2)
#	set environmentArray(bcRepositoryEntry) $dd(result2)
	set bcChoice1 repository ;# important to enable button 2.2 in UpdateMenu
	if !$installInitialCollection {
		if {$xx == "dd"} {
			CancelSearch $aBrowse bcRepository bc(result1)
			set bcSearch 0
			set bg [$w cget -bg]
			$aBrowse.button6.6 configure -bg $bg
		}
		EnableEntry $aBrowse bcRepository bc(result1) keyRepositoryList
		SetBackgroundEntry $aBrowse.entry bcRepository bc(result1) keyRepositoryList
		SetIndicator bc $w.main.bc
	}
	EnableButtons
}

# OK - end
# ----------------------------------------------------------------------
# Cancel

proc Cancel {xx} {
# runs with start
	global wbc wdd wrr wir wob wsp clo exi
	global w
	global environmentArray
	global installInitialCollection
#	pack forget $w.main.$xx
#	destroy $w.main.$xx
	destroy $w.main
	destroy .xxdirectory
	destroy .xxrepository
	CreateMain 1
	[string toupper $xx]Cancel $w.main.$xx	;# DDCancel
# at installation .environmentArray.tcl may not exist
	if [file exists ../auxdoc/.environmentArray.tcl] {
#		source ../auxdoc/.environmentArray.tcl
		SourceWithBackup ../auxdoc/.environmentArray.tcl environmentArray	;# added by GJFB on 2010-08-05
	}
	if $installInitialCollection {
		$wsp config -state normal
		$exi config -state normal
	} else {
		EnableButtons
	}
}

# Cancel - end
# ----------------------------------------------------------------------
# RemoveEntry
# example:
# RemoveEntry .window.main.sp.pre.entry spPreference sp(result1)

proc RemoveEntry {widget entryName varName} {
# runs with start
	global environmentArray
	global typeTable	;# defined in DDDialog
	global listNameTable	;# defined in DDDialog
	upvar #0 $varName var
	upvar #0 $entryName xxEntry
	set listName $listNameTable($xxEntry)
	upvar #0 $listName list
#	regsub {(..).*} $varName \
		{\1Search} searchName	;# ddSearch
#	upvar #0 $searchName search
#	if {[info exists search] && $search} {
#		set type .lis.
#	} else {
#		set type $widget
		set type $typeTable($xxEntry)
#	}

#	set i [lsearch -exact $list $var]
#	set list [lreplace $list $i $i]
	if {[set i [lsearch -exact $list $var]] != -1} {
		set list [lreplace $list $i $i]
	}

#	set i [lsearch -exact $environmentArray(${xxEntry}SelectMenu) \
		$var]
#	set environmentArray(${xxEntry}SelectMenu) \
		[lreplace $environmentArray(${xxEntry}SelectMenu) $i $i]
	if {[set i [lsearch -exact $environmentArray(${xxEntry}SelectMenu) $var]] != -1} {
		set environmentArray(${xxEntry}SelectMenu) \
			[lreplace $environmentArray(${xxEntry}SelectMenu) $i $i]
	}

	set menu $widget.button3.3.menu
	CheckConsistency $widget $type $varName \
		$environmentArray(${xxEntry}SelectMenu) $listName  
	CreateMenu $menu $widget $entryName $type $varName \
		$environmentArray(${xxEntry}SelectMenu) $listName \
		{    }
	set var ""
#	UpdateMenu $widget $entryName $varName $listName
	UpdateMenu $widget $entryName $varName
#	if {[llength $environmentArray(${xxEntry}SelectMenu)] == 0} {
#		regexp {^..} $varName xx	;# dd
#		regexp ".*\.($xx\.\[^.\]*)" $widget m prefix	;# dd.dir
#		upvar #0 ${prefix}PostMenu postMenu
#		set postMenu 0
#		$widget.button1.1 configure -state disabled
#		$widget.button2.2 configure -state disabled
#	}
}

# RemoveEntry - end
# ----------------------------------------------------------------------
# SetEntry

proc SetEntry {widget envIndex varName index \
	{arrayName {environmentArray}}} {
# runs with start
	upvar #0 $arrayName array
	upvar #0 $varName var
	if [info exists array($envIndex)] {
		set var($index) $array($envIndex)	;# set entry
	} else {
		if [regexp {\.dir\.} $widget] {
			set var($index) [lindex [file split [pwd]] 0]
		} else {
			set var($index) ""
		}
	}
	$widget.entry icursor end
}

# SetEntry - end
# ----------------------------------------------------------------------
# XXDirectory
# Display the directory content
# called from DisplayText


proc XXDirectory {entryWidget entryName varName} {
# runs with start
# entryWidget not used
	global w
	upvar #0 $varName var
	regsub {/$} $var {} dir	;#delete trailing /
	set fileList {}
	DirectoryContent fileList $dir $dir 650
	set fileList [lsort -dictionary $fileList]
	set t .xxdirectory.f.t	
	$t delete 1.0 end
	ClearSelection $t
	foreach tagName [$t tag names] {
		$t tag remove $tagName 1.0 end	;# remove old tags
	}
	$t configure -font {courier 11}
	TextStyles $t
	Insert $t insert \
{File List}
	TagAdd $t bold {File List}
	$t insert insert \n
	foreach file $fileList {
		eval [list $t insert insert " $file " [list $file]]
		regsub -all {%} $file {%%} file2	;# see page 298 Table 23-4
#		eval [list $t tag bind $file <1> "SelectFile $t {$file2}"]
		$t tag bind $file <1> "SelectFile $t {$file2}"
#		eval [list $t tag bind $file <Control-1> "SelectFile $t {$file2} 0"]
		$t tag bind $file <Control-1> "SelectFile $t {$file2} 0"
# /clear cannot be a file name
		$t insert insert \n /clear
	}
#	$t tag bind /clear <1> "ClearTargetSelection $t"
#	$t tag bind /clear <3> "ClearSelection $t"
	$t tag bind /clear <1> "ClearSelection $t"
	$t configure -state disabled
	.xxdirectory.button.close.close config -state normal
	.xxdirectory.button.reload.reload config -state normal
#	if [winfo exists $w.main.bc.button.reload.reload] {
#		$w.main.bc.button.reload.reload config -state disabled
#	}
}

# XXDirectory - end
# ----------------------------------------------------------------------
# SelectTargetFile

proc SelectTargetFile {t targetFileName rep entryWidget entryName varName} {
# runs with start
	global homePath
#	global loCoInRep
# puts $rep
	regexp {^..} $varName xx	;# dd
	set newTargetFileName $targetFileName
	set oldTargetFileName [Eval GetTargetFile $rep]
# puts --$newTargetFileName--
# puts --$oldTargetFileName--
	if {[string compare $newTargetFileName $oldTargetFileName] == 0} {return}
	set buttonCursorState [SetWaitingState $entryWidget $xx]
	$t configure -state normal
	if [string equal {} $oldTargetFileName] {
		if [Dialog {Yes No} {disabled active} {0 0} Check {selecting a target file} $newTargetFileName $rep] {
			$t configure -state disabled
			UnsetWaitingState $entryWidget $xx $buttonCursorState
			return
		}
	} else {
		if [Dialog {Yes No} {disabled active} {0 0} Check \
			{selecting a new target file} $newTargetFileName $rep $oldTargetFileName] {
			$t configure -state disabled
			UnsetWaitingState $entryWidget $xx $buttonCursorState
			return
		}
		ClearTargetSelection $t	;# used to turn off the red highlight
	}
	if [file exists $homePath/col/$rep/doc/$targetFileName] {
		$t tag configure $targetFileName -foreground #ff0000
#		foreach {state officialSite imageURL} [Eval ComputeVersionState $rep $loCoInRep] {break}
		foreach {state officialSite imageURL} [Eval ComputeVersionState $rep] {break}
# officialSite and imageURL not used
		array set stateTable {
			{Registered Original} {Official}
			{Modified Original} {Modified}
			{Copy of an Original} {Modified}
			{Modified Copy of an Original} {Modified}
			{Unchecked} {Unchecked}
		}
		set state $stateTable($state)
		UpdateTargetFile $rep $targetFileName
		if [string equal Modified $state] {
			PerformCheck $entryWidget $entryName $varName 0
		}
	}
	$t configure -state disabled
	UnsetWaitingState $entryWidget $xx $buttonCursorState
}

# SelectTargetFile - end
# ----------------------------------------------------------------------
# UpdateTargetFile
# Update @metadata.refer
# Update service/targetFile and repositoryProperties array
# Save repositoryProperties array
# Update download files
# Update metadataArray, repArray and wordOccurrenceArray 
# Save metadataArray, repArray and wordOccurrenceArray

proc UpdateTargetFile {rep targetFile {save 1}} {
# runs with start and post
	global homePath
	global loCoInRep
	global updateTargetFileRunning
	global environmentArray
	
	set updateTargetFileRunning 1	;# used by SetCursor

# metadataRep
	set metadataRep [Eval FindMetadataRep $rep]
# oldTargetFile
	Load $homePath/col/$rep/service/targetFile oldTargetFile

# Update @metadata.refer
# $targetFile -> @metadata.refer
	Load $homePath/col/$metadataRep/doc/@metadata.refer referMetadata
	set referMetadata [UpdateRefer $referMetadata [concat targetfile $targetFile]]
	Store referMetadata $homePath/col/$metadataRep/doc/@metadata.refer
# Update @metadata.refer - end

# Update service/targetFile and repositoryProperties array
# @metadata.refer -> service/targetFile
# @metadata.refer -> repositoryProperties array
# @metadata.refer -> metadataList
	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName
#	set metadataList [LoadMetadata $referMetadata]	;# for add
# puts $referMetadata
	set metadataList [LoadMetadata $referMetadata {} $administratorUserName]	;# for add
# puts --$metadataList--
# => ... iconet.com.br/banon/2003/08.18.12.15.26-0,targetfile {20 - [ARTIGO][INPE]  Michelly Karoline Alves Santana.jpg} ...
	set metadata2List {}	;# for remove
# Update service/targetFile and repositoryProperties array - end

# Save repositoryProperties array
#	if $save {Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl}
	if $save {Eval SaveRepositoryProperties}
# Save repositoryProperties array - end

# Update download files
#	Eval UpdateDownloadFilesByAdministrator $rep
	if [file exists $homePath/col/$rep/download/doc.zip] {
		if [file exists $homePath/col/$rep/service/targetFile] {
			Eval UpdateArchiveFile $rep col/$rep/service/targetFile
		} else {
			if ![string equal {} $oldTargetFile] {
				Eval UpdateArchiveFile $rep col/$rep/service/targetFile -d
			}
		}
		set metadataRepList [FindAllLanguageVersions $metadataRep]
		foreach mRep $metadataRepList {
			UpdateArchiveFile $rep col/$mRep/doc/@metadata.refer
		}
	}
# Update download files - end

# Update metadataArray, repArray and wordOccurrenceArray 
# repositoryProperties array -> metadataArray, repArray and wordOccurrenceArray 
#	set metadataList {}	;# for add
#	set metadata2List {}	;# for remove
# puts -0-$metadata2List--
# puts -0-$metadataList--
	UpdateField $rep $metadataRep targetfile metadataList metadata2List
# puts -1-$metadata2List--
# puts -1-$metadataList--
if 0 {
# commented by GJFB on 2020-08-18
	Eval RemoveMetadata $metadata2List
	Eval AddMetadata $metadataList
} else {
# puts --$metadata2List--
# => --iconet.com.br/banon/2003/08.18.12.15.26-0,targetfile {}--
# puts --$metadataList--
	Eval UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
# Update metadataArray, repArray and wordOccurrenceArray  - end

# Save metadataArray, repArray and wordOccurrenceArray
	Set saveMetadata 1
	if $save {
		Eval SaveMetadata
		Eval UpdateRepositoryListForPost $rep
	}

# Save metadataArray, repArray and wordOccurrenceArray - end

	set updateTargetFileRunning 0	;# used by SetCursor
}

# UpdateTargetFile - end
# ----------------------------------------------------------------------
# ClearTargetSelection
# Updates target file if $rep is not empty

proc ClearTargetSelection {text {rep {}} {entryWidget {}} {entryName {}} {varName {}}} {
# runs with start
#	global loCoInRep
	set xx {}
	regexp {^..} $varName xx	;# dd
	set buttonCursorState [SetWaitingState $entryWidget $xx]
	foreach tagName [$text tag names] {
		set colorFg [$text tag cget $tagName -foreground]
		set colorBg [$text tag cget $tagName -background]
#		if {$colorFg == "#ff0000" || \
			[Info exists repositoryProperties($rep,targetfile)]}
		if {$colorFg == "#ff0000"} {
			if {$colorBg == "#000088"} {
# blue (not used)
				$text tag configure $tagName \
					-foreground #000000 \
					-background #dddddd  
			} else {
				if {[string compare {} $rep] != 0} {
if 0 {
					set targetFile [Get repositoryProperties($rep,targetfile)]
					set targetFile [join $targetFile]	;# {RBMET_SAULO[1].pdf} -> RBMET_SAULO[1].pdf - braces appear while executing: lappend replyList $reply, within GetReply
} else {
# added by GJFB on 2021-01-21 because Get lost extra white spaces disfiguring the target file name
					LoadService $rep targetFile targetFile 0 1
}
					if [Dialog {Yes No} {disabled active} {0 0} Check \
						{clearing the target file selection} $targetFile $rep] {
						UnsetWaitingState $entryWidget $xx $buttonCursorState
						return
					}
					$text tag configure $tagName -foreground #000000
#					foreach {state officialSite imageURL} [Eval ComputeVersionState $rep $loCoInRep] {break}
					foreach {state officialSite imageURL} [Eval ComputeVersionState $rep] {break}
# officialSite and imageURL not used
					array set stateTable {
						{Registered Original} {Official}
						{Modified Original} {Modified}
						{Copy of an Original} {Modified}
						{Modified Copy of an Original} {Modified}
						{Unchecked} {Unchecked}
					}
					set state $stateTable($state)
					UpdateTargetFile $rep {}	;# no target file
					if {[string compare Modified $state] == 0} {
						PerformCheck $entryWidget $entryName $varName 0
					}
				} else {
					$text tag configure $tagName -foreground #000000
				}
			}
			break
		}
	}
	UnsetWaitingState $entryWidget $xx $buttonCursorState
}

# ClearTargetSelection - end
# ----------------------------------------------------------------------
# SelectFile

proc SelectFile {text tagName {flag {1}}} {
	if $flag {ClearSelection $text}
	set colorFg [$text tag cget $tagName -foreground]
	set colorBg [$text tag cget $tagName -background]
	if {$colorFg == "#ff0000"} {
		if {$colorBg == "#000088"} {
			$text tag configure $tagName \
				-foreground #ff0000 \
				-background #dddddd
		} else {
			$text tag configure $tagName \
				-foreground #ff0000 \
				-background #000088
		}
	} else {
		if {$colorBg == "#000088"} {
			$text tag configure $tagName \
				-foreground #000000 \
				-background #dddddd  
		} else {
			$text tag configure $tagName \
				-foreground #ffffff \
				-background #000088
		}
	}
#	set targetFileSelected no
	foreach tagName2 [$text tag names] {
		set color [$text tag cget $tagName2 -foreground]
		if {$color == "#ff0000"} {
			$text tag configure $tagName2 -background #000088
#			set targetFileSelected yes
			break
		}
	}
#	if {$targetFileSelected == "no"} {
#		$text tag configure $tagName -foreground #ff0000
#	}
}

# SelectFile - end
# ----------------------------------------------------------------------
# ClearSelection

proc ClearSelection {text} {
	foreach tagName [$text tag names] {
		set color [$text tag cget $tagName -foreground]
		$text tag configure $tagName -background #dddddd
		if {$color != "#ff0000"} {
			$text tag configure $tagName -foreground #000000
		}
	}
}

# ClearSelection - end
# ----------------------------------------------------------------------
# OpenFileManager
# used in XXRepository only

proc OpenFileManager {rep} {
	global homePath
	global tcl_platform
	
	if {$tcl_platform(platform) == "windows"} {
		regsub -all {/} $homePath/col/$rep/doc {\\} path
		catch {exec c:/windows/explorer.exe $path}
	}
}

# OpenFileManager - end
# ----------------------------------------------------------------------
# XXRepository
# Display the meta content of a repository
# called from DisplayText
# Example:
# XXRepository .window.main.bc.rep.h2.entry.entry bcRepository bc(result1)
# service -> repositoryProperties

proc XXRepository {entryWidget entryName varName} {
# runs with start
#	global metadataArray
#	global referRepository
#	global repositoryProperties	;# post
#	global referenceTable	;# post
	global col
	global homePath
#	global keyRepositoryList
	global environmentArray
	global commonWords
	global citationKeyRepository
	global tcl_platform
	global loCoInRep
	global editorPath	;# set in LoadGlobalVariables
	global mswordEditorPath	;# set in LoadGlobalVariables
	global metadataRepTitle	;# to allow tag deleting
	global parentRepTitle	;# to allow tag deleting
	global wishPath	;# set in LoadGlobalVariables

	upvar #0 $varName var
	DisableButtons
	set r $citationKeyRepository
# xx
	regexp {^..} $varName xx	;# dd

# rep (name of the repository to display)
	if ![regexp {^(.*/.*/.*/.*) .+} $var m rep] {
		regexp {^.* (.*/.*/.*/.+)} $var m rep
	}

# documentState
	set documentState [GetDocumentState $rep]

	set t .xxrepository.f.t	
	$t configure -state normal
	bind $t <Control-Button-1> "OpenFileManager $rep"	;# added by GJFB on 2010-11-16
	bind $t <3> "clipboard clear; clipboard append $rep"
	set font [lindex [lindex [$t configure -font] end] 0]
	$t delete 1.0 end
	TextStyles $t
	bindtags $t [list $t .XXRepository all]	;# drop Text to avoid click side effects during the text construction
# Delete tags to prevent undesired click effect before text completion
	if [info exists metadataRepTitle] {
		$t tag delete $metadataRepTitle
	}
	$t tag delete {Content Type}
	if [info exists parentRepTitle] {
		$t tag delete $parentRepTitle
	}
	$t tag delete {Copyright}
	$t tag delete {Author Home Page}
	$t tag delete {Permission}
	$t tag delete {Mirror Sites}
	$t tag delete {Remote Permission}
# no protection made for Language and Host Collection
# Delete tags to prevent undesired click effect before text completion - end
	$t configure -font {courier 11}
# Repository
	Insert $t insert \
{Repository}
	TagAdd $t bold {Repository}
	$t insert insert \n
	if ![Eval TestContentType $rep {Metadata}] {
		$t insert insert "$rep " [list fixed $rep blue indent]
		$t tag bind $rep <1> "Link $rep"
		$t tag bind $rep <Enter> "SetCursor $t hand2"
		$t tag bind $rep <Leave> "SetCursor $t double_arrow"
	} else {
# Metadata
		$t insert insert "$rep " {fixed indent}
	}
	$t insert insert \n\n
# Metadata
# metadataRepList
	set metadataRepList [FindMetadataRepList $rep $entryWidget $varName]
# metadataRep
	set metadataRep [Eval FindMetadataRep $rep]
	if {$metadataRep != {}} {
# >
# the data below are extracted from the (first) metadata in the first language
	Load $col/$metadataRep/doc/@metadata.refer entry
	array set metadataArray [ConvertMultipleRefer2MetadataList 0 $entry $metadataRep]
# type
	set type [ReturnType metadataArray $metadataRep-0 1]
# author
	set author [GetAuthor $metadataRep-0 1]
#	regsub -all ",\}" $author "\}" nameList
	set nameList $author
# year
	set year [GetFieldValue $metadataRep-0 year 1]
# title
	set title [GetFieldValue $metadataRep-0 title 1]
	Insert $t insert \
{Metadata}
	TagAdd $t bold {Metadata}
	$t insert insert \n
	foreach name $nameList {
		regsub {,$} $name {} name
		$t insert insert "$name" {times indent}
		$t insert insert \n
	}
	$t insert insert " :$year:" fixed
	$t insert insert \n
	$t insert insert "$title" {italic11 wrap indent gray}
	$t insert insert \n\n
# Identification Key
	set citationkey [CreateCitationKey metadataArray $metadataRep-0 1]
	Insert $t insert \
{Identification Key}
	TagAdd $t bold {Identification Key}
	$t insert insert \n
#	$t insert insert " [${r}::CreateKey $author $year $title $commonWords]" fixed
	$t insert insert " $citationkey" fixed
	$t insert insert \n\n
# Document Type
	Insert $t insert \
{Document Type}
	TagAdd $t bold {Document Type}
	$t insert insert \n
#	$t insert insert " $metadataArray($metadataRep-0,referencetype)" \
		fixed
	$t insert insert " $type" \
		fixed
#	$t insert insert " $metadataArray($metadataRep-0,$type,%0)" \
		fixed
	$t insert insert \n\n

# Metadata Repository
	if {[llength $metadataRepList] != 0} {
		if {[llength $metadataRepList] == 1} {
			set metadataRepTitle {Metadata Repository}
		} else {
			set metadataRepTitle {Metadata Repositories}
		}
		Insert $t insert $metadataRepTitle [list bold $metadataRepTitle]
		if $documentState {
			TagAdd $t blackgreen $metadataRepTitle
			$t tag bind $metadataRepTitle <Enter> "SetCursor $t hand2"
			$t tag bind $metadataRepTitle <Leave> "SetCursor $t double_arrow"
		} else {
			$t tag delete $metadataRepTitle
		}
		$t insert insert \n
		foreach metadataRep2 $metadataRepList {
			$t insert insert "$metadataRep2 " \
				"fixed9 $metadataRep2 blue indent"
#			$t tag bind $metadataRep2 <1> "Link $metadataRep2"
			$t tag bind $metadataRep2 <1> \
				"InternalLink $entryWidget $entryName $varName $metadataRep2"
			$t tag bind $metadataRep2 <Enter> "SetCursor $t hand2"
			$t tag bind $metadataRep2 <Leave> "SetCursor $t double_arrow"
			$t insert insert \n
		}
		$t insert insert \n
	}
# <
	}

# Content Type

	Insert $t insert {Content Type} [list bold {Content Type}]
	if $documentState {
		TagAdd $t blackgreen {Content Type}
		set contentTypeList {
{}
{Access Icon}
{Author Home Page}
{Banner}
{Banner Sequence}
{Bibliography Data Base}
{CGI Script}
{Copyright}
{External Contribution}
{Index}
{Local Copyright}
{Metadata}
{Mirror}
{Submission Form}
{Tcl Page}
{Template}
}
#		$t tag bind {Content Type} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {select content type} {} {} {} \
				listbox {Content Type} $contentTypeList \
				$rep $entryWidget $entryName $varName]
		$t tag bind {Content Type} <Enter> "SetCursor $t hand2"
		$t tag bind {Content Type} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Content Type}
	}
	if [Info exists repositoryProperties($rep,type)] {
		$t insert insert \n
		set contentType [Get repositoryProperties($rep,type)]
		$t insert insert "$contentType" {indent fixed}
	} else {
		set contentType {}
	}
	$t insert insert \n\n

# History
	if [Info exists repositoryProperties($rep,history)] {
		Insert $t insert \
{Version History}
		TagAdd $t bold {Version History}
		$t insert insert \n
		set i 0
		foreach version [Eval ReturnTheMostRecentVersions $rep] {
			$t mark set firstLine "insert -$i line"
			$t insert firstLine "$version\n" {indent wrap fixed9}
			incr i
		}
		$t insert insert \n
	}

# Cited Repository
# Parent Repository
#	set citedRepositoryList [Eval GetCitedRepositoryList $rep 1]
	set citedRepositoryList [Eval GetCitedRepositoryList $rep]	;# returns all
# puts --$citedRepositoryList--
	if {[llength $citedRepositoryList] <= 1} {
		set parentRepTitle {Parent Repository}
	} else {
		set parentRepTitle {Parent Repositories}
	}
	Insert $t insert $parentRepTitle [list bold $parentRepTitle]

	if $documentState {
		Load $col/$rep/service/reference fileContent
		TagAdd $t blackgreen $parentRepTitle
		$t tag bind $parentRepTitle <Enter> "SetCursor $t hand2"
		$t tag bind $parentRepTitle <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete $parentRepTitle
	}

	$t insert insert \n
	foreach citedRepository $citedRepositoryList {
		$t insert insert "$citedRepository " \
			"fixed9 $citedRepository blue indent"
#		$t tag bind $citedRepository <1> "Link $citedRepository"
		$t tag bind $citedRepository <1> \
			"InternalLink $entryWidget $entryName $varName $citedRepository"
		$t tag bind $citedRepository <Enter> "SetCursor $t hand2"
		$t tag bind $citedRepository <Leave> "SetCursor $t double_arrow"
		$t insert insert \n
	}
	$t insert insert \n

# Citing Repository
# Child Repository
	set citingRepositoryList [GetCitingRepositoryList- $rep $entryWidget $varName]
	if {[llength $citingRepositoryList] != 0} {
		if {[llength $citingRepositoryList] <= 1} {
			set childRepTitle {Child Repository}
		} else {
			set childRepTitle {Child Repositories}
		}
		Insert $t insert $childRepTitle [list bold $childRepTitle]

		$t insert insert \n
		foreach citingRepository $citingRepositoryList {
			$t insert insert "$citingRepository " \
				"fixed9 $citingRepository blue indent"
			$t tag bind $citingRepository <1> \
				"InternalLink $entryWidget $entryName $varName $citingRepository"
			$t tag bind $citingRepository <Enter> "SetCursor $t hand2"
			$t tag bind $citingRepository <Leave> "SetCursor $t double_arrow"
			$t insert insert \n
		}
		$t insert insert \n
	}

	if ![string equal Metadata $contentType] {
# >
# Copyright
#	Insert $t insert {Copyright} \
		[list bold {Copyright} blackgreen]
	Insert $t insert {Copyright} [list bold {Copyright}]
	if $documentState {
		set list [Array get repositoryProperties *,type]
		set copyrightList {{}}
		foreach {index value} $list {
#			if {[string compare {Copyright} $value] == 0}
			if [regexp {Copyright} $value] {
# get Copyright and Local Copyright
				regsub {,type} $index {} repName
				set keyRep [AddKey $repName/ 0]
				regsub { } $keyRep {   } keyRep
				lappend copyrightList $keyRep
			}
		}
		TagAdd $t blackgreen {Copyright}
		$t tag bind {Copyright} <Enter> "SetCursor $t hand2"
		$t tag bind {Copyright} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Copyright}
	}
	$t insert insert \n
	if [Info exists repositoryProperties($rep,copyright)] {
		set copyrightRepositories [Get repositoryProperties($rep,copyright)]
		foreach copyrightRep $copyrightRepositories { 
			$t insert insert "$copyrightRep " \
				"fixed9 $copyrightRep blue indent"
			$t tag bind $copyrightRep <1> \
				"InternalLink $entryWidget $entryName $varName $copyrightRep"
			$t tag bind $copyrightRep <Enter> "SetCursor $t hand2"
			$t tag bind $copyrightRep <Leave> "SetCursor $t double_arrow"
			$t insert insert \n
		}
	}
	$t insert insert \n
# Author Home Page
#	Insert $t insert {Author Home Page} \
		[list bold {Author Home Page} blackgreen]
	Insert $t insert {Author Home Page} [list bold {Author Home Page}]
	if $documentState {
		set list [Array get repositoryProperties *,type]
		set authorHomePageList {{}}
		foreach {index value} $list {
			if [string equal {Author Home Page} $value] {
				regsub {,type} $index {} repName
				set keyRep [AddKey $repName/ 0]
				regsub { } $keyRep {   } keyRep
				lappend authorHomePageList $keyRep
			}
		}
		TagAdd $t blackgreen {Author Home Page}
		$t tag bind {Author Home Page} <Enter> "SetCursor $t hand2"
		$t tag bind {Author Home Page} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Author Home Page}
	}
	$t insert insert \n
	if [Info exists repositoryProperties($rep,authorhomepage)] {
		set authorHomePageRep [Get repositoryProperties($rep,authorhomepage)]
		$t insert insert "$authorHomePageRep " \
			"fixed9 $authorHomePageRep blue indent"
		$t tag bind $authorHomePageRep <1> \
			"InternalLink $entryWidget $entryName $varName $authorHomePageRep"
		$t tag bind $authorHomePageRep <Enter> "SetCursor $t hand2"
		$t tag bind $authorHomePageRep <Leave> "SetCursor $t double_arrow"
		$t insert insert \n
	}
	$t insert insert \n

# Visibility
	Insert $t insert {Visibility} [list bold {Visibility}]
	if $documentState {
		TagAdd $t blackgreen {Visibility}
		$t tag bind {Visibility} <Enter> "SetCursor $t hand2"
		$t tag bind {Visibility} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Visibility}
	}
	$t insert insert \n
	if [file exists $homePath/col/$rep/service/visibility] { 
		LoadService $rep visibility visibility 1 1
		if $visibility {
			$t insert insert {hidden} [list fixed9 {hidden}]
		} else {
			$t insert insert {shown} [list fixed9 {shown}]
		}
		$t insert insert \n
	}
	$t insert insert \n

# Permission
	Insert $t insert {Permission} [list bold {Permission}]
	if $documentState {
		TagAdd $t blackgreen {Permission}
#		$t tag bind {Permission} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {set permission} {} {} {} \
				PermissionWidget {Permission} {} \
				$rep $entryWidget $entryName $varName]
		$t tag bind {Permission} <Enter> "SetCursor $t hand2"
		$t tag bind {Permission} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Permission}
	}
	$t insert insert \n
#	if [Info exists repositoryProperties($rep,docpermission)]
	Load $homePath/col/$rep/service/docPermission currentDocPermission
	if {$currentDocPermission != ""} {
		Insert $t insert {doc} [list fixed9 {doc}]
		$t insert insert \n
#		set currentDocPermission [Get repositoryProperties($rep,docpermission)]
		foreach line [split $currentDocPermission \n] {
			$t insert insert "$line" {indent fixed9}
			$t insert insert \n
		}
	}
#	if [Info exists repositoryProperties($rep,downloadpermission)]
	Load $homePath/col/$rep/service/downloadPermission currentDownloadPermission
	if {$currentDownloadPermission != ""} {
		Insert $t insert {download} [list fixed9 {download}]
		$t insert insert \n
#		set currentDownloadPermission [Get repositoryProperties($rep,downloadpermission)]
		foreach line [split $currentDownloadPermission \n] {
			$t insert insert "$line" {indent fixed9}
			$t insert insert \n
		}
	}
	$t insert insert \n

# Mirror Sites
	Insert $t insert {Mirror Sites} [list bold {Mirror Sites}]
	if $documentState {
		TagAdd $t blackgreen {Mirror Sites}
#		$t tag bind {Mirror Sites} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {select mirror sites} {} {} {} \
				listbox {Mirror Sites} {} \
				$rep $entryWidget $entryName $varName]
		$t tag bind {Mirror Sites} <Enter> "SetCursor $t hand2"
		$t tag bind {Mirror Sites} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Mirror Sites}
	}
	$t insert insert \n
	if [Info exists repositoryProperties($rep,mirrorsites)] {
		set mirrorSites [Get repositoryProperties($rep,mirrorsites)]
		foreach mirrorSite $mirrorSites { 
			$t insert insert "$mirrorSite" {indent fixed9}
			$t insert insert \n
		}
	}
	$t insert insert \n

# Remote Permission
	Insert $t insert {Remote Permission} [list bold {Remote Permission}]
	if $documentState {
		TagAdd $t blackgreen {Remote Permission}
#		$t tag bind {Remote Permission} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {set remote permission} {} {} {} \
				PermissionWidget {Remote Permission} {} \
				$rep $entryWidget $entryName $varName]
		$t tag bind {Remote Permission} <Enter> "SetCursor $t hand2"
		$t tag bind {Remote Permission} <Leave> "SetCursor $t double_arrow"
	} else {
		$t tag delete {Remote Permission}
	}
	$t insert insert \n
	LoadService $rep docRemotePermission currentDocRemotePermission 1 1
	if {$currentDocRemotePermission != ""} {
		Insert $t insert {doc} [list fixed9 {doc}]
		$t insert insert \n
		foreach line [split $currentDocRemotePermission \n] {
			$t insert insert "$line" {indent fixed9}
			$t insert insert \n
		}
	}
	LoadService $rep downloadRemotePermission currentDownloadRemotePermission 1 1
	if {$currentDownloadRemotePermission != ""} {
		Insert $t insert {download} [list fixed9 {download}]
		$t insert insert \n
		foreach line [split $currentDownloadRemotePermission \n] {
			$t insert insert "$line" {indent fixed9}
			$t insert insert \n
		}
	}
	$t insert insert \n

# <
	}

# Language
	set indexList [Array names referenceTable *$rep*]
	foreach index $indexList {
#		if {[Get referenceTable($index)] == "+" || \
#			[Info exists repositoryProperties($rep,language)]}
		if 1 {
			Insert $t insert {Language} [list bold {Language}]
			if $documentState {
				TagAdd $t blackgreen {Language}
				set languageList [list \
{} \
{en} \
{es} \
{fr} \
{pt} \
{pt-BR} \
{English} \
{French} \
{Portuguese} \
{Spanish} \
{Afrikaans [af]} \
{Albanian [sq]} \
{Arabic [ar]} \
{Arabic/Algeria [ar-DZ]} \
{Arabic/Bahrain [ar-BH]} \
{Arabic/Egypt [ar-EG]} \
{Arabic/Iraq [ar-IQ]} \
{Arabic/Jordan [ar-JO]} \
{Arabic/Kuwait [ar-KW]} \
{Arabic/Lebanon [ar-LB]} \
{Arabic/Libya [ar-LY]} \
{Arabic/Morocco [ar-MA]} \
{Arabic/Oman [ar-OM]} \
{Arabic/Quatar [ar-QA]} \
{Arabic/Saudi Arabia [ar-SA]} \
{Arabic/Syria [ar-SY]} \
{Arabic/Tunisia [ar-TN]} \
{Arabic/U.A.E. [ar-AE]} \
{Arabic/Yemen [ar-YE]} \
{Basque [eu]} \
{Bulgarian [bg]} \
{Byelorussian [be]} \
{Catalan [ca]} \
{Chinese [zh]} \
{Chinese/China [zh-CN]} \
{Chinese/Hong Kong [zh-HK} \
{Chinese/Singapore [zh-SG]} \
{Chinese/Taiwan [zh-TW]} \
{Croatian [hr]} \
{Czech [cs]} \
{Danish [da]} \
{Dutch [nl]} \
{Dutch/Belgium [nl-BE]} \
{English [en]} \
{English/Australia [en-AU]} \
{English/Belize [en-BZ]} \
{English/Canada [en-CA]} \
{English/Ireland [en-IE]} \
{English/Jamaica [en-JM]} \
{English/New Zealand [en-NZ]} \
{English/South Africa [en-ZA]} \
{English/Trinidade [en-TT]} \
{English/United Kingdom [en-GB]} \
{English/United States [en-US]} \
{Estonian [et]} \
{Faeroese [fo]} \
{Farsi [fa]} \
{Finnish [fi]} \
{French [fr]} \
{French/Belgium [fr-BE]} \
{French/Canada [fr-CA]} \
{French/France [fr-FR]} \
{French/Switzerland [fr-CH]} \
{Galician [gl]} \
{German [de]} \
{German/Austria [de-AU]} \
{German/Liechtenstein [de-LI]} \
{German/Luxembourg [de-LU]} \
{German/Germany [de-DE]} \
{German/Switzerland [de-CH]} \
{Greek [el]} \
{Hebrew [he]} \
{Hindi [hi]} \
{Hungarian [hu]} \
{Icelandic [is]} \
{Indonesian [id]} \
{Irish [ga]} \
{Italian [it]} \
{Italian/Switzerland [it-CH]} \
{Japonese [ja]} \
{Korean [ko]} \
{Latvian [lv]} \
{Lithuanian [lt]} \
{Malaysian [ms]} \
{Maltese [mt]} \
{Macedonian [mk]} \
{Norwegian [no]} \
{Polish [pl]} \
{Portuguese [pt]} \
{Portuguese/Brazil [pt-BR]} \
{Romanian [ro]} \
{Romanian/Moldavia [ro-MO]} \
{Russian [ru]} \
{Scots Gaelic [gd]} \
{Serbian [sr]} \
{Slovak [sk]} \
{Slovenian [sl]} \
{Sorbian [sb]} \
{Spanish [es]} \
{Spanish/Argentina [es-AR]} \
{Spanish/Bolivia [es-BO]} \
{Spanish/Chile [es-CL]} \
{Spanish/Colombia [es-CO]} \
{Spanish/Costa Rica [es-CR]} \
{Spanish/Ecuador [es-EC]} \
{Spanish/El Salvador [es-SV]} \
{Spanish/Guatemala [es-GT]} \
{Spanish/Honduras [es-HN]} \
{Spanish/Mexican [es-MX]} \
{Spanish/Nicaragua [es-NI]} \
{Spanish/Panama [es-PA]} \
{Spanish/Paraguay [es-PY]} \
{Spanish/Peru [es-PE]} \
{Spanish/Puerto Rico [es-PR]} \
{Spanish/Spain [es-ES]} \
{Spanish/Uruguay [es-UY]} \
{Spanish/Venezuela [es-VE]} \
{Sutu [sx]} \
{Swedish [sv]} \
{Swedish/Finland [sv-FI]} \
{Thai [th]} \
{Tsonga [ts]} \
{Tswana [tn]} \
{Turkish [tr]} \
{Ukrainian [uk]} \
{Urdu [ur]} \
{Vietnamese [vi]} \
{Xhosa [xh]} \
{Yiddish [ji]} \
{Zulu [zu]} \
]
				$t tag bind {Language} <1> \
					[list Dialog {OK Cancel} {disabled disabled} \
						{-1 -1} Check {select language} {} {} {} \
						listbox {Language} $languageList \
						$rep $entryWidget $entryName $varName]
				$t tag bind {Language} <Enter> "SetCursor $t hand2"
				$t tag bind {Language} <Leave> "SetCursor $t double_arrow"
			} else {
				$t tag delete {Language}
			}
			$t insert insert \n
			if [Info exists repositoryProperties($rep,language)] {
				set language [Get repositoryProperties($rep,language)]
				$t insert insert " $language" fixed
				$t insert insert \n
			}
			$t insert insert \n
			break
		}	
	}

## Password

#	if $documentState {
#		Insert $t insert Password [list bold Password]
#		TagAdd $t blackgreen Password
#		$t tag bind Password <Enter> "SetCursor $t hand2"
#		$t tag bind Password <Leave> "SetCursor $t double_arrow"
#		$t insert insert \n
#		if [file exists $homePath/col/$rep/service/password] {
#			LoadService $rep password password 1 1
#			regsub -all {.} $password {*} password
#			$t insert insert $password {indent fixed9}
#			$t insert insert \n
#		}
#		$t insert insert \n
#	} else {
#		$t tag delete Password
#	}

# User with Write Permission
	if $documentState {
		Insert $t insert {User with Write Permission} [list bold {User with Write Permission}]
		TagAdd $t blackgreen {User with Write Permission}
#		$t tag bind {User with Write Permission} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {select a user with write permission} {} {} {} \
				listbox {User with Write Permission} {} \
				$rep $entryWidget $entryName $varName]
		$t tag bind {User with Write Permission} <Enter> "SetCursor $t hand2"
		$t tag bind {User with Write Permission} <Leave> "SetCursor $t double_arrow"
		$t insert insert \n
		if [file exists $homePath/col/$rep/service/userName] {
#			Load $homePath/col/$rep/service/userName userName
			LoadService $rep userName userName 1 1
			$t insert insert "$userName" {indent fixed9}
			$t insert insert \n
		}
		$t insert insert \n
	} else {
		$t tag delete {User with Write Permission}
	}

# Users with Read Permission
	if [Eval TestContentType $rep {Submission Form}] {
# such repositories contain submission.js that should not be read protected because submission.js needs
# to be read from any submission forms
		$t tag delete {User with Read Permission}
	} else {
		Insert $t insert {Users with Read Permission} [list bold {Users with Read Permission}]
		TagAdd $t blackgreen {Users with Read Permission}
		$t tag bind {Users with Read Permission} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {select users with read permission} {} {} {} \
				listbox {Users with Read Permission} {} \
				$rep $entryWidget $entryName $varName]
		$t tag bind {Users with Read Permission} <Enter> "SetCursor $t hand2"
		$t tag bind {Users with Read Permission} <Leave> "SetCursor $t double_arrow"
		$t insert insert \n
		if [Info exists repositoryProperties($rep,authenticatedusers)] {
			set authenticatedUsers [Get repositoryProperties($rep,authenticatedusers)]
			foreach authenticatedUser $authenticatedUsers { 
				$t insert insert "$authenticatedUser" {indent fixed9}
				$t insert insert \n
			}
		}
		$t insert insert \n
	}

# Host Collection
	LoadService $rep transferableFlag transferableFlag 1 1
# puts [list [GetDocumentState $rep 1] [CheckRegistration $rep] $transferableFlag]
#	if {![string equal Metadata $contentType] && [GetDocumentState $rep 1] && \
#	![CheckRegistration $rep] && $transferableFlag} #
# copyright transfer must be registration dependent in order to be able to follow the original
	if ![catch {foreach {state officialSite imageURL} [Eval ComputeVersionState $rep] {break}}] {
# officialSite and imageURL not used
		array set stateTable {
			{Registered Original} {Official}
			{Modified Original} {Modified}
			{Copy of an Original} {Modified}
			{Modified Copy of an Original} {Modified}
			{Unchecked} {Unchecked}
		}
		set state $stateTable($state)
		if {[string equal Official $state] && $transferableFlag} {
			Insert $t insert {Host Collection} [list bold {Host Collection}]
			TagAdd $t blackgreen {Host Collection}
			$t tag bind {Host Collection} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {select host collection} {} {} {} \
					listbox {Host Collection} {} \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Host Collection} <Enter> "SetCursor $t hand2"
			$t tag bind {Host Collection} <Leave> "SetCursor $t double_arrow"
		} else {
			Insert $t insert \
{Host Collection}
			TagAdd $t bold {Host Collection}
		}
	} else {
		Insert $t insert \
{Host Collection}
		TagAdd $t bold {Host Collection}
	}
	if [Info exists repositoryProperties($rep,hostcollection)] { 
#		set hostCollection [Get repositoryProperties($rep,hostcollection)]
#		$t insert insert \n
#		$t insert insert "$hostCollection" {indent fixed9}
#		$t insert insert \n\n
		$t insert insert \n
		set i 0
#		foreach hc [Get repositoryProperties($rep,hostcollection)] #	;# commented by GJFB on 2025-11-21
		foreach hc [lreverse [Get repositoryProperties($rep,hostcollection)]] {	;# added by GJFB on 2025-11-21 to be like in full metadata
			$t mark set firstLine "insert -$i line"
			$t insert firstLine "$hc\n" {indent wrap fixed9}
			incr i
		}
		$t insert insert \n
	} else {
		$t insert insert \n\n
	}

# Size
	if [Info exists repositoryProperties($rep,size)] {
		Insert $t insert \
{Size}
		TagAdd $t bold {Size}
		$t insert insert \n
		set size [Get repositoryProperties($rep,size)]
		set size [lindex $size 0]
		if {$size <= 1} {
			set size [Translate {$var1 Kbyte} $size]
		} else {
			set size [Translate {$var1 Kbytes} $size]
		}
		$t insert insert "$size" {indent}
		$t insert insert \n\n
	}
# Number of Files
	if [Info exists repositoryProperties($rep,numberoffiles)] {
		Insert $t insert \
{Number of Files}
		TagAdd $t bold {Number of Files}
		$t insert insert \n
		set numberOfFiles [Get repositoryProperties($rep,numberoffiles)]
		$t insert insert "$numberOfFiles" {indent}
		$t insert insert \n\n
	}
# File List
	set dir $homePath/col/$rep/doc
	set fileList {}
#	DirectoryContent fileList $dir $dir 650	;# commented by GJFB on 2022-05-17
	DirectoryContent fileList $dir $dir 1650	;# added by GJFB on 2022-05-17
	Insert $t insert \
{File List}
	TagAdd $t bold {File List}
#	$t configure -font {courier 11}
	$t insert insert \n
	foreach file [lsort -dictionary $fileList] {
		eval [list $t insert insert " $file " [list $file]]
		if [file exists $editorPath] {
#			eval [list $t tag bind $file <1> [list Edit $editorPath $homePath/col/$rep/doc/$file]]
			if [regexp -nocase {\.tcl$} $file] {
#				eval [list $t tag bind $file <Lock-Button-1> [list ExecuteWish $rep $wishPath $col/$rep/doc/$file]]
#				eval [list $t tag bind $file <Shift-Button-1> [list ExecuteWish $rep $wishPath $col/$rep/doc/$file]]
#				eval [list $t tag bind $file <Alt-Button-1> [list ExecuteWish $rep $wishPath $col/$rep/doc/$file]]
				eval [list $t tag bind $file <Double-Button-1> [list ExecuteWish $rep $wishPath $col/$rep/doc/$file]]
			}
			if {[regexp -nocase {\.(doc|docx)$} [file extension $file]] && $tcl_platform(platform) == "windows"} {
				eval [list $t tag bind $file <1> [list Edit $mswordEditorPath $col/$rep/doc/$file]]	;# path must be relative
			} else {
				eval [list $t tag bind $file <1> [list Edit $editorPath $col/$rep/doc/$file]]	;# path must be relative
			}
			eval [list $t tag bind $file <Enter> "SetCursor $t hand2"]
			eval [list $t tag bind $file <Leave> "SetCursor $t double_arrow"]
		}
		if {$metadataRep != {}} {
			eval [list $t tag bind $file <3> \
				"SelectTargetFile $t {$file} $rep $entryWidget $entryName $varName"]
# /clear cannot be a file name
			$t insert insert \n /clear
		} else {
			$t insert insert \n
		}
	}
	$t tag bind /clear <3> "ClearTargetSelection $t $rep $entryWidget $entryName $varName"
# target file
	ClearTargetSelection $t	;# used to turn off the red highlight
	if [Info exists repositoryProperties($rep,targetfile)] {
if 0 {
		set targetFile [Get repositoryProperties($rep,targetfile)]
# puts --$targetFile--
# => --20 - {[ARTIGO][INPE]} Michelly Karoline Alves Santana.jpg--
# the braces were added and the second white space before Michelly was lost when using Get (which use GetReply)
		set targetFile [join $targetFile]	;# {RBMET_SAULO[1].pdf} -> RBMET_SAULO[1].pdf - braces appear while executing: lappend replyList $reply, within GetReply
# puts --$targetFile--
# => --20 - [ARTIGO][INPE] Michelly Karoline Alves Santana.jpg--
} else {
# added by GJFB on 2021-01-21 because Get lost extra white spaces disfiguring the target file name
		LoadService $rep targetFile targetFile 0 1
# puts --$targetFile--
# => --20 - [ARTIGO][INPE]  Michelly Karoline Alves Santana.jpg--
}
		if [file exists $homePath/col/$rep/doc/$targetFile] {
			$t tag configure $targetFile -foreground #ff0000
		}
	}
	$t configure -state disabled

	if $documentState {
		.xxrepository.button.reload.reload config -state normal
#		if {$metadataRep != {} && $searchResult != {}}
#		if {$metadataRep != {}}
		if {$metadataRep != {} && [llength $metadataRepList] != 0} {
			$t tag bind $metadataRepTitle <1> \
				[list DisplayEditMetadata $entryWidget $entryName $varName \
				#dddddd {}]
		}
		$t tag bind {Content Type} <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {select content type} {} {} {} \
				listbox {Content Type} $contentTypeList \
				$rep $entryWidget $entryName $varName]
		$t tag bind $parentRepTitle <1> \
			[list Dialog {OK Cancel} {disabled disabled} \
				{-1 -1} Check {define parent repositories} {} {} {} \
				text {Parent Repositories} $fileContent \
				$rep $entryWidget $entryName $varName]
		if {[string compare Metadata $contentType] != 0} {
			$t tag bind {Copyright} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {select copyright} {} {} {} \
					listbox {Copyright} $copyrightList \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Author Home Page} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {select author home page} {} {} {} \
					listbox {Author Home Page} $authorHomePageList \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Visibility} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {set visibility} {} {} {} \
					VisibilityWidget {Visibility} {} \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Permission} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {set permission} {} {} {} \
					PermissionWidget {Permission} {} \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Mirror Sites} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {select mirror sites} {} {} {} \
					listbox {Mirror Sites} {} \
					$rep $entryWidget $entryName $varName]
			$t tag bind {Remote Permission} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {set remote permission} {} {} {} \
					PermissionWidget {Remote Permission} {} \
					$rep $entryWidget $entryName $varName]
#			$t tag bind {Password} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {change password} {} {} {} \
					entry {Password} {} \
					$rep $entryWidget $entryName $varName]
			$t tag bind {User with Write Permission} <1> \
				[list Dialog {OK Cancel} {disabled disabled} \
					{-1 -1} Check {select a user with write permission} {} {} {} \
					listbox {User with Write Permission} {} \
					$rep $entryWidget $entryName $varName]
		}
	}
	.xxrepository.button.close.close config -state normal
#	RestoreBCButtons $entryName
	ControlBCButtonState $entryWidget $entryName $varName
	EnableButtons
}

# XXRepository - end
# ----------------------------------------------------------------------
# RestoreBCButtons

proc RestoreBCButtons {entryName} {
	if {[string compare $entryName bcRepository] == 0} {
		.window.main.bc.button.edit.edit config -state normal
		.window.main.bc.button.reload.reload config -state normal
	}
#	EnableButtons
}

# RestoreBCButtons - end
# ----------------------------------------------------------------------
# Link
# examples:
# Link dpi.inpe.br/banon/1998/08.02.08.56
# Link {} banon-pc.dpi.inpe.br:1905

proc Link {{rep {}} {path {}} {file {}}} {
# runs with post and start
	global environmentArray
	global loBiMiRep
	global localSite

	if {$path == ""} {
		if {$rep == ""} {set rep $loBiMiRep}
		set path $localSite/rep/$rep
		if {$file != ""} {append path /$file}
	}
	if ![info exists environmentArray(spBrowserEntry)] {return}
	if {$environmentArray(spBrowserEntry) == "Netscape"} {
		if [FindBrowser netscape] {return}
		exec "$environmentArray(netscape)" http://$path &
	}
	if {$environmentArray(spBrowserEntry) == "Mozilla"} {
		if [FindBrowser mozilla] {return}
		exec "$environmentArray(mozilla)" http://$path &
	}
	if {$environmentArray(spBrowserEntry) == "HotJava"} {
		if [FindBrowser hotjava] {return}
		exec "$environmentArray(hotjava)" http://$path &
	}
	if {$environmentArray(spBrowserEntry) == "Konqueror"} {
		if [FindBrowser konqueror] {return}
		exec "$environmentArray(konqueror)" http://$path &
	}
	if {$environmentArray(spBrowserEntry) == "Internet Explorer"} {
		if [FindBrowser internetExplorer] {return}
		exec "$environmentArray(internetExplorer)" http://$path &
	}
	if {$environmentArray(spBrowserEntry) == "Chrome"} {
		if [FindBrowser chrome] {return}
		exec "$environmentArray(chrome)" http://$path &
	}
}

# Link - end
# ----------------------------------------------------------------------
# InternalLink
# Example:
# InternalLink .window.main.bc.rep.h2.entry.entry bcRepository bc(result1) dpi.inpe.br/banon/1999/05.03.22.11

proc InternalLink {entryWidget entryName varName rep} {
	global w
	regsub {.entry$} $entryWidget {} widget
	set bg [$w cget -bg]
	$widget.button6.6 configure -bg $bg
	CancelSearch $widget $entryName $varName
	set string [AddKey $rep/ 0]
	UpdateEntry $widget $entryName .rep. $string $varName keyRepositoryList
}

# InternalLink - end
# ----------------------------------------------------------------------
# ExecuteWish

proc ExecuteWish {rep wishPath executePath} {
	global doubleClickFlag
	
	set doubleClickFlag 1
	exec $wishPath $executePath $rep &
}

# ExecuteWish - end
# ----------------------------------------------------------------------
# Edit

proc Edit {editor path} {
	global doubleClickFlag
	
	set doubleClickFlag 0
	set x 0; after 600 {set x 1}; vwait x
	if $doubleClickFlag {return}
	
	if ![file exists $path] {
# create an empty file
		set fileContent {}
		Store fileContent $path
	}
# puts "exec $editor $path &"
	exec $editor $path &
}

# Edit - end
# ----------------------------------------------------------------------
# ReturnReferModel
# used by CreateMirror (Submit option) and others
# complete values is 0, 1 or a refer field name (e.g., %A)
# 0 means to return all the fields except fields %0, %2, %4 (e.g., {%A author} {%B journal} ...)
# 1 means to return all fields
# otherwise means to return the corresponding output of conversionTable (e.g., %A means to return for example author)

proc ReturnReferModel {referenceType {complete 0}} {
# runs with start and post
	global referRepository
	global ${referRepository}::conversionTable	;# conversionTable(Journal Article,%A) author
	global fieldAttributeTable

	if {[string equal {0} $complete] || [string equal {1} $complete]} {
		set referModel {}
		if ![string equal {} $referenceType] {
			foreach index [array names conversionTable $referenceType,%*] {
				if ![string equal {} $conversionTable($index)] {
					if [regsub {.*,%(.)$} $index {\1} referFieldName] {
						if !$complete {if {$referFieldName == 0 || $referFieldName == 2 || $referFieldName == 4} {continue}}
						lappend referModel "%$referFieldName $conversionTable($index)"
					} else {
						regexp {,%(.*)$} $index m fieldName	;# @site
						regsub {^@} $fieldName {} field	;# dropping @
						if {[info exists fieldAttributeTable($field,4)] && $fieldAttributeTable($field,4)} {
# add
							lappend referModel "%$fieldName $conversionTable($index)"	;# %A author
						}
					}
				}
			}
			return [lsort -command ReferFieldCompare $referModel]
		}
		return
	} else {
		if [info exists conversionTable($referenceType,$complete)] {
			return $conversionTable($referenceType,$complete)
		}
		return
	}
}

# ReturnReferModel - end
# ----------------------------------------------------------------------
# SetInitialValue

proc SetInitialValue {varName default} {
# runs with start
	global environmentArray
	upvar #0 $varName var
	if [info exists environmentArray($varName)] {
		set var $environmentArray($varName)
	} else {
		set var $default
		set environmentArray($varName) $default
	}
}

# SetInitialValue - end
# ----------------------------------------------------------------------
# ProcessRepositoryListForStart
# used in SetIndicator
# repositoryListForStart is updated by LoadBiblioDB, CaptureRepository, CreateRepMetadataRep and UpdateRepMetadataRep

proc ProcessRepositoryListForStart {xx searchMode} {
# runs with start
	global keyRepositoryList
	Load ../auxdoc/repositoryListForStart fileContent
	set repList [lsort -unique [split $fileContent \n]]
#	set storeKeyRepositoryListFlag 0
	foreach rep $repList {
#		set storeKeyRepositoryListFlag [UpdateKeyRepositoryList $rep $storeKeyRepositoryListFlag]
		UpdateKeyRepositoryList $rep
		if $searchMode {
# the selectedKeyRepositoryList must be updated in case of a search beeing displayed
			UpdateKeyRepositoryList $rep 0 ${xx}SelectedKeyRepList	;# ddSelectedKeyRepList
		}
	}
#	if $storeKeyRepositoryListFlag {
#		StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
#	}
	file delete ../auxdoc/repositoryListForStart
}

# ProcessRepositoryListForStart - end
# ----------------------------------------------------------------------
# SetIndicator
# example: 2/12/24
# puts $xx
# => dd
# puts $widget
# => .dd or .window.main.dd or .dd.rep.h1.h2.v2.entry
# or .window.main.dd.rep.h1.h2.v2.entry

proc SetIndicator {xx widget {numberOfRep {0}}} {
# runs with start
#	global environmentArray
	global keyRepositoryList
#	global metadataArray
#	global repositoryProperties
	global homePath
#	regexp {.(..)$} $widget m xx	;# dd
	regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
	switch -exact $xx \
		dd {
			set index 2
			set searchEntryLabel $win.rep.h1.h1.lb1
			set indicatorLabel $win.rep.h1.h1.lb2
		} \
		bc {
			set index 1
			set searchEntryLabel $win.rep.h1.lb1
			set indicatorLabel $win.rep.h1.lb2
		}
	upvar #0 ${xx}SearchResult xxSearchResult
	upvar #0 ${xx}SearchEntry xxSearchEntry
	upvar #0 ${xx}Choice$index xxChoiceI

	if [info exists xxSearchResult] {
		set searchMode 1
# Compute numberOfmetadataRep
		set numberOfmetadataRep [Eval ReturnNumberOfMetadataRep]
# Compute numberOfmetadataRep - end
		set selectedRepList {}
		foreach metadataRep-i $xxSearchResult {
# puts ${metadataRep-i}
			if ![regexp -- {-0$} ${metadataRep-i}] {continue}
			regsub -- {-[^-]*$} ${metadataRep-i} {} metadataRep
			set rep [Eval ReturnRepositoryName $metadataRep]
			if {$rep != {}} {
				if ![file isdirectory $homePath/col/$rep] {
# the repository has been deleted
					UpdateVariables $rep
					Eval UpdateVariables $rep
				} else {
# the repository has not been deleted
					if {[lsearch -exact $selectedRepList $rep] == -1} {
						lappend selectedRepList $rep
					}
				}
			}
		}
		set searchEntry "$xxSearchEntry   "
		set numberOfSelectedRep [llength $selectedRepList]
		set indicator \
			$numberOfSelectedRep/$numberOfmetadataRep/
		if [winfo exists $widget.button5.5] {
			$widget.button5.5 configure -state disabled
		}
	} else {
		set searchMode 0
		set searchEntry ""
		set indicator ""
		if {[winfo exists $widget.button5.5] && \
			$xxChoiceI == "repository"} {
			$widget.button5.5 configure -state normal
		}
	}

	ProcessRepositoryListForStart $xx $searchMode	;# updates keyRepositoryList

	if {$numberOfRep == 0} {
		set numberOfRep [llength $keyRepositoryList]
	}

	if [winfo exists $searchEntryLabel] {
		$searchEntryLabel configure -text $searchEntry \
			-fg #007700
	}
	if [winfo exists $indicatorLabel] {
		$indicatorLabel configure -text $indicator$numberOfRep \
			-fg #000000
	}
}

# SetIndicator - end
# ----------------------------------------------------------------------
# CancelSearch
# Example:
# CancelSearch .window.main.bc.rep.h2.entry bcRepository bc(result1)

proc CancelSearch {widget entryName varName} {
# runs with start
	global environmentArray
# puts [CallTrace]
	regexp {^..} $varName xx	;# dd
#	upvar #0 ${xx}Search search	;# ddSearch
	upvar #0 ${xx}SearchResult xxSearchResult
#	if ![info exists search] {return}
#	if !$search 
	if [info exists xxSearchResult] {
		unset xxSearchResult
	}
	if [info exists environmentArray(${xx}SearchResult)] {
		unset environmentArray(${xx}SearchResult)
	}
	if 1 {
		regexp ".*\.$xx" $widget win	;# .dd or .window.main.dd
		if ![FindSearchMode $xx $win] {return}
# search is active
#		upvar #0 ${xx}SearchEntry xxSearchEntry
#		if [info exists xxSearchEntry] {
#			set xxSearchEntry {}
#			set environmentArray(${xx}SearchEntry) {}
#			if [winfo exists $widget] {
				SetIndicator $xx $widget
				regexp ".*\.($xx\.\[^.\]*)" $widget m prefix	;# dd.dir
				upvar #0 ${prefix}PostMenu postMenu
				set postMenu 0	;# otherwise UpdateMenu below would post the menu
				UpdateMenu $widget $entryName $varName
				UpdateMenu2 $widget $entryName $varName
#			}
#		}
	}
#	set search 0
}

# CancelSearch - end
# ----------------------------------------------------------------------
# FindSearchMode
# returns 0 or 1, 1 means that a search result is beeing displayed

proc FindSearchMode {xx win} {
	if {$xx == "dd"} {set cmd $win.rep.h1.h1.lb2}
	if {$xx == "sp"} {set cmd {}}
	if {$xx == "bc"} {set cmd $win.rep.h1.lb2}
	if [winfo exists $cmd] {
		set searchMode [regexp {/} [lindex [$cmd configure -text] end]]
	} else {
		set searchMode 0
	}
	return $searchMode
}

# FindSearchMode - end
# ----------------------------------------------------------------------
# UpdateRefer
# updates the referMetadata with the newEntry
# referMetadata must contain the %0 field ending with \n
# newEntry is a list like {name value}
# see conversionTable (in referTables.tcl file) for the field names
# newEntry example: {area SO150000}
# newEntry example: {keywords xx, yy.}
# newEntry example: {keywords {xx, yy.}} (the result is the same as above)
# newEntry example: {author {{xx, yy,} {aa, bb,}}} (multiple line fields)
# if the entry already exists, then it updated, otherwise it is added
# if the field value is empty the field is deleted
# UpdateRefer returns the updated metadata in the refer format

proc UpdateRefer {referMetadata newEntry} {
# runs with start and post
	global inverseTable
	global tcl_platform
	global applicationName
	
	regexp "%0 (\[^%\]*)\n%" $referMetadata m referenceType
	if ![info exists referenceType] {
		if {$tcl_platform(platform) == "windows" && $applicationName == "start"} {
			console show
		}
		puts [CallTrace]
		puts {UpdateRefer: syntax error:}
		puts {the metadata is not in refer format}
		puts {line beginning with %0 not found in the data below}
		puts --$referMetadata--
		puts {solution:}
		puts {correct the file content}
		puts {press exit}
		puts {start again URLibService}
		vwait forever
	}
# puts [CallTrace]
# puts --$newEntry--
#	set field [lindex $newEntry 0]
##	set value [lrange $newEntry 1 end]
#	set value [join [lrange $newEntry 1 end]]	;# newEntry => targetfile carla[1].doc - value => carla[1].doc
#	if ![regexp {^([^ ]*) (.*)$} $newEntry m field value] # commented by GJFB on 2012-05-26 to allow any type of heading, in between and trailing spaces
	if ![regexp {^\s*(.*?)\s+(.*?)\s*$} $newEntry m field value] {
		set field $newEntry
		set value {}
	}
# puts $value
 	if [string equal {targetfile} $field] {
# do nothing - added by GJFB on 2021-01-21 because join below remove extra white spaces and add \ before [ and ] disfiguring the target file name
 	} else {
		set value [join $value]	;# {xx, yy.} -> xx, yy.
	}
# puts $value
	if [info exists inverseTable($referenceType,$field)] {
		set referField $inverseTable($referenceType,$field)
# puts [list $referMetadata $referField $value]
		set referMetadata [PutReferField $referMetadata $referField $value]
# puts $referMetadata
	}
#	return [string trim $referMetadata \n]
	return $referMetadata
}

if 0 {
# testing
	source utilitiesStart.tcl
	source utilities1.tcl
	source utilities2.tcl
	source cgi/mirrorFind-.tcl
	set referRepository dpi.inpe.br/banon/1999/08.08.19.14
	source ../../../../../$referRepository/doc/referTables.tcl
	global ${referRepository}::conversionTable
	global inverseTable
	global applicationName
	global multipleLineReferFieldNamePattern
#	set multipleLineReferFieldNamePattern {A|E|Y|\?|@affiliation|@electronicmailaddress|@group|@isbn|@issn|@usergroup}
	LoadGlobalVariables
	set applicationName post
	array set inverseTable [CreateInverseTable]
#	puts $inverseTable(Electronic Source,nextedition)
#	Load ../../../../../iconet.com.br/banon/2003/11.21.21.08.28/doc/@metadata.refer referMetadata
#	Load ../../../../../dpi.inpe.br/banon/2000/05.25.20.06/doc/@metadata.refer referMetadata
	Load ../../../../../iconet.com.br/banon/2003/08.17.10.41.18/doc/@metadata.refer referMetadata
	puts $referMetadata
#	puts [UpdateRefer $referMetadata [concat keywords {}]]
#	puts [UpdateRefer $referMetadata [concat keywords {dd xx, cc yy.}]]
	set targetFile {}
	puts [UpdateRefer $referMetadata [concat {targetfile} ${targetFile}]]
#	puts [UpdateRefer $referMetadata [concat keywords dd xx, cc yy.]]
#	puts [UpdateRefer $referMetadata [list keywords {xx, yy.}]]	;# can be concat or list
#	puts [UpdateRefer $referMetadata {area SO150000}]
#	puts [UpdateRefer $referMetadata {keywords image patch.}]
#	puts [UpdateRefer $referMetadata {usergroup bb jefferson}]
#	puts [UpdateRefer $referMetadata {usergroup {bb jefferson}}]
#	puts [UpdateRefer $referMetadata {nextedition dpi.inpe.br/banon/1999/08.08.19.14}]
#	puts [UpdateRefer $referMetadata {previousedition dpi.inpe.br/banon/1999/09.12.15.10}]
#	puts [UpdateRefer $referMetadata [concat documentstage banon]]
# => %0 Computer Program ...
}

# UpdateRefer - end
# ----------------------------------------------------------------------
# UpdateReferMetadata
# updates @metadata.refer
# used by script (see administrator pages) and by CreateRepMatadataRep
# newEntryList is a list of newEntry (see UpdateRefer)
# userName must be administrator or its name
# password must be coded

proc UpdateReferMetadata {metadataRep newEntryList userName password} {
# runs with post
	global homePath

# puts "newEntryList = --$newEntryList--"	
# => --{nexthigherunit {}}--
# => --{nexthigherunit J8LNKB5R7W/3EB9F8L}--

	set message [CheckAdministratorPassword $userName $password]
	if ![string equal {} $message] {
		return "UpdateReferMetadata: $message" 
	}
	Load $homePath/col/$metadataRep/doc/@metadata.refer referMetadata
	foreach newEntry $newEntryList {
		set referMetadata [UpdateRefer $referMetadata $newEntry]
	}
	Store referMetadata $homePath/col/$metadataRep/doc/@metadata.refer
}

# UpdateReferMetadata - end
# ----------------------------------------------------------------------
# UpdateReferMetadata2
# used with multiple submit

# not used
proc UpdateReferMetadata2x {metadataRep newEntryList userName password} {
	return [UpdateReferMetadata $metadataRep $newEntryList $userName $password]
}

# UpdateReferMetadata2 - end
# ----------------------------------------------------------------------
# UpdateNonServiceFields
# updates a non service field called fieldName with a new fieldValue
# creates a new version stamp
# if the field already exists, then it updated, otherwise it is added
# if the field value is empty the field is deleted
# examples:
# UpdateANonServiceField $repository $metadataRepository area SO150000
# UpdateANonServiceField $repository $metadataRepository keywords {xx, yy.}
# UpdateANonServiceField $repository $metadataRepository author {{xx, yy,} {aa, bb,}}
# used in UpdateArchivingPolicy only

proc UpdateNonServiceFields {repository metadataRepository fieldName fieldValue} {
# runs with post
	global homePath

	if [GetDocumentState $repository] {
# the document is the original - otherwise do nothing

# Waiting for the completion of other repository insertions
		WaitQueue UpdateNonServiceFields
# Waiting for the completion of other repository insertions - end
		
		set metadataList {}	;# for add
		set metadata2List {}	;# for remove
		set repositoryList {}
# remove
		set metadata2List [concat $metadata2List [GetMetadata $metadataRepository-0,$fieldName]]
# add
		if ![string equal {} $fieldValue] {
			set metadataList [concat $metadataList [list $metadataRepository-0,$fieldName $fieldValue]]
		}
# Update history
# CREATE A NEW VERSION STAMP (for the metadata repository (metadataRepository))
		Load $homePath/col/$metadataRepository/doc/@metadata.refer referMetadata
		set referMetadata [UpdateRefer $referMetadata [list $fieldName $fieldValue]]
		Store referMetadata $homePath/col/$metadataRepository/doc/@metadata.refer
#		LoadService $repository userName oldUserName 1 1
#		if [string equal {} $oldUserName] {set oldUserName administrator}
		set seconds [clock seconds]
#		set metadataVersionStamp [CreateVersionStamp $seconds $oldUserName $referMetadata]
		set metadataVersionStamp [CreateVersionStamp $seconds administrator $referMetadata]
		UpdateHistory $metadataRepository $metadataVersionStamp
# Update history - end
# remove
		set metadata2List [concat $metadata2List [GetMetadata $metadataRepository-0,metadatalastupdate]]
# add
		set metadataList [concat $metadataList [list $metadataRepository-0,metadatalastupdate $metadataVersionStamp]]

		lappend repositoryList $repository
		lappend repositoryList $metadataRepository
if 0 {
# commented by GJFB on 2020-08-18
		RemoveMetadata $metadata2List
		AddMetadata $metadataList
} else {
		UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
		UpdateRepositoryListForPost $repositoryList
		LeaveQueue
	}
}

# UpdateNonServiceFields - end
# ----------------------------------------------------------------------
# UpdateArchivingPolicy
# updates the archivingpolicy field value of metadataRepository from attributeTable sourced in year=_issn_archivingpolicy.tcl
# using the issn value and data in attributeTable
# used in GetURLPropertyList and CreateMirror (remotely) only

proc UpdateArchivingPolicy {repository metadataRepository userName administratorCodedPassword} {
# runs with post
	global metadataArray
	global homePath
	global standaloneModeFlag	;# set in LoadGlobalVariables
	
	ConditionalSet archivingPolicyValue metadataArray($metadataRepository-0,archivingpolicy) {}
	
	set message [CheckAdministratorPassword $userName $administratorCodedPassword]
	if ![string equal {} $message] {return $archivingPolicyValue}	;# unfair call - do nothing
	
	if [info exists metadataArray($metadataRepository-0,issn)] {
		set issnValue [lindex $metadataArray($metadataRepository-0,issn) 0]	;# use the first - it is assumed that all policies are the same, otherwise should pick the most restrictive policy
if 0 {
# for standalone testing
		Source http://banon-pc3/col/dpi.inpe.br/banon-pc3/2011/03.14.15.45/doc/year=_issn_archivingpolicy.tcl attributeTable
} else {
		set repositoryName dpi.inpe.br/banon-pc3/2011/03.14.15.45	;# contains the file year=_issn_archivingpolicy.tcl
		set tclFileName year=_issn_archivingpolicy.tcl	;# file defining the archiving policy of the journal having issn
		if $standaloneModeFlag {
# in standalone mode
			set useURLibServerFlag 0
		} else {
			set useURLibServerFlag 1	;# avoid waiting for nonexisting repository in the local scope
		}
# SOURCE
		if [catch {SetAttributeTable $repositoryName $tclFileName $useURLibServerFlag}] {
			global errorInfo
			return -code error "UpdateArchivingPolicy (1): $errorInfo"
		}
}
# puts [info exists attributeTable(year=,issn,archivingpolicy,$issnValue)]
# puts [llength [array names attributeTable]]
		if [info exists attributeTable] {
# set attributeTable(year=,issn,archivingpolicy,0262-8856) {denypublisher allowfinaldraft}
			ConditionalSet archivingPolicyValue2 attributeTable(year=,issn,archivingpolicy,$issnValue) {}
			if ![string equal $archivingPolicyValue $archivingPolicyValue2] {
# archiving policy has changed - update it
				set archivingPolicyValue $archivingPolicyValue2
# CREATE A NEW VERSION STAMP (for the metadata repository (metadataRepository)) if the document is the original
				UpdateNonServiceFields $repository $metadataRepository archivingpolicy $archivingPolicyValue
			}
		} else {
			set log "\[[clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]\] UpdateArchivingPolicy: attributeTable doesn't exist\n"
			puts $log
			Store log $homePath/@errorLog auto 0 a
			return -code error "UpdateArchivingPolicy (2): attributeTable doesn't exist"
		}
	}
	return $archivingPolicyValue
}

# UpdateArchivingPolicy - end
# ----------------------------------------------------------------------
# UpdateReadPermissionFromSecondaryDate
# used in GetURLPropertyList only
# similar to "Update field value" in col/dpi.inpe.br/banon-pc@1905/2005/02.19.00.40/cgi/script.tcl

proc UpdateReadPermissionFromSecondaryDate {
	repository metadatarepository language contentType visibility secondaryDate readPermission
} {
# runs with post
	global homePath
	global loCoInRep
	global errorInfo

	set permission [ComputeReadPermissionFromSecondaryDate $secondaryDate $readPermission]
# puts --$permission--
# puts [CallTrace]

	if [string equal {} $permission] {return}	;# nothing to do - leave the read permission as it is
	
if 0 {
	set log "\[[clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]\] UpdateReadPermissionFromSecondaryDate: [list $repository $metadatarepository $language $contentType $visibility $secondaryDate $readPermission]\n"
	Store log $homePath/@errorLog auto 0 a
}		
#	while {[EnterQueue UpdateReadPermissionFromSecondaryDate]} {
#		set x2 0; after 100 {set x2 1}; vwait x2
#	}

	WaitQueue UpdateReadPermissionFromSecondaryDate	;# added by GJFB on 2013-09-11
	
	Load $homePath/col/$loCoInRep/auxdoc/xxx data binary
	set data [UnShift $data]
	set codedPassword [lindex $data end]
	set booleanVisibility [expr [string equal {hidden} $visibility]]

# CREATE A NEW VERSION STAMP
#	set returnCode [Execute $documentServerAddress [list UpdateRepMetadataRep #
	if [catch {UpdateRepMetadataRep \
	$repository $metadatarepository administrator $codedPassword preserve 0 \
	1 $contentType 1 $permission administrator {} \
	disable {} \
	{} {} 0 \
	$language 1 0 \
	{} 0 $booleanVisibility} returnCode] {
		StoreLog {error} {UpdateReadPermissionFromSecondaryDate (1)} $errorInfo
	}
#	{} 0 $booleanVisibility]]
	
	LeaveQueue
	if {![string equal 0 $returnCode] && ![string equal 1 $returnCode]} {
		StoreLog {alert} {UpdateReadPermissionFromSecondaryDate (2)} $returnCode
	}
}

# UpdateReadPermissionFromSecondaryDate - end
# ----------------------------------------------------------------------
# CheckAdministratorPassword
# userName must be administrator or its alias name
# password must be coded
# sessionTime value are miliseconds - added by GJFB on 2019-01-16

proc CheckAdministratorPassword {userName password {sessionTime {}}} {
# runs with post
	global environmentArray

# administratorUserName
	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName

	if ![string equal {administrator} $userName] {
		if [string equal $administratorUserName $userName] {
# $userName is the administrator
		} else {
# $userName is not the administrator
			return "CheckAdministratorPassword: $userName is not the administrator"
		}
	}
	if [CheckPassword $userName $password $sessionTime] {
		return "CheckAdministratorPassword: the password is incorrect or the user name doesn't exist" 
	}
}

# CheckAdministratorPassword - end
# ----------------------------------------------------------------------
# UpdateHTMLTargetFile
# Update the base (if any) in an HTML target file.

# not in use (probably works)
proc UpdateHTMLTargetFile {rep {update {1}} {userName {}}} {
# runs with start
#	global repositoryProperties	;# post
	global col
	global homePath
	global localSite
#	upvar $metadataListName metadataList
#	upvar $metadata2ListName metadata2List
	if [Info exists repositoryProperties($rep,targetfile)] {
if 0 {
		set targetFile [Get repositoryProperties($rep,targetfile)]
		set targetFile [join $targetFile]	;# {RBMET_SAULO[1].pdf} -> RBMET_SAULO[1].pdf - braces appear while executing: lappend replyList $reply, within GetReply
} else {
# added by GJFB on 2021-01-21 because Get lost extra white spaces disfiguring the target file name
		LoadService $rep targetFile targetFile 0 1
}
		if [regexp {\.[hH][tT][mM]$|\.[hH][tT][mM][lL]$} $targetFile] {
			Load $col/$rep/doc/$targetFile fileContent
			if [regexp {^(.*</[hH][eE][aA][dD]>)(.*)$} $fileContent m head body] {
#				set site banon-pc.dpi.inpe.br:1905
#				set site [GetServerAddress]
				set site $localSite
				if [regexp {<[bB][aA][sS][eE]>[^<]*</[bB][aA][sS][eE]>} $head base] {
					if ![regexp "$site/col/$rep/doc" $base] {
						regsub {<[bB][aA][sS][eE]>[^<]*</[bB][aA][sS][eE]>} $head \
							"<BASE>HREF=http://$site/col/$rep/doc/</BASE>" head
						set fileContent $head$body
						Store fileContent $col/$rep/doc/$targetFile
						if $update {
							set metadataRep [Eval FindMetadataRep $rep]
							if ![file isdirectory $homePath/col/$metadataRep] {
								UpdateVariables $metadataRep
								set metadataRep {}
							}
							Eval UpdateLastUpdate $rep $metadataRep none $userName
						}
					}
				}
			}
 		}
	}
}

# source C:/usuario/gerald/URLib/col/dpi.inpe.br/banon/1998/08.02.08.56/auxdoc/.repositoryProperties.tcl
# source C:/usuario/gerald/URLib/col/dpi.inpe.br/banon/1998/08.02.08.56/doc/cgi/mirrorfind-.tcl
# source C:/usuario/gerald/URLib/col/dpi.inpe.br/banon/1998/08.02.08.56/doc/utilities1.tcl
# UpdateHTMLTargetFile dpi.inpe.br/banon/1999/11.27.14.56

# UpdateHTMLTargetFile - end
# ----------------------------------------------------------------------
# UpdateMetadataField
# Example:
# UpdateMetadataField $metadataRep metadatalastupdate $stamp metadataList metadata2List
# multiple value is 0 (default) or 1
# 1 means that update is done for all the metadata repositories (for all languages)
# adds only nonempty value
# used in UpdateLastUpdate (post), PerformCheck (start), GetClipboard (start), Dialog (start), CreateRepMetadataRep, UpdateRepMetadataRep, LoadMetadata and UpdateCrossReferences in this file and by other procedures and other files

if 0 {
# old version - commented by GJFB on 2021-01-22
proc UpdateMetadataField {metadataRep field value metadataListName metadata2ListName {multiple {0}}} {
# runs with start and post
	upvar $metadataListName metadataList
	upvar $metadata2ListName metadata2List

	if $multiple {
		set metadataRepList [Eval FindAllLanguageVersions $metadataRep]
	} else {
		set metadataRepList $metadataRep
	}
	foreach mRep $metadataRepList {
# remove
		set oldValue [Eval GetMetadata $mRep-0,$field]
		if [string equal $oldValue $value] {continue}	;# added by GJFB on 2011-10-01 - update accelerator
		set metadata2List [concat $metadata2List $oldValue]
# add
		if ![string equal {} $value] {
			set metadataList [concat $metadataList [list $mRep-0,$field $value]]
		}
	}
}

} else {
# new version - added by GJFB on 2021-01-22 to avoid pair (name value) duplicate in metadataList and fix the update accelerator
proc UpdateMetadataField {metadataRep field value metadataListName metadata2ListName {multiple {0}}} {
# runs with start and post
	global col
	upvar $metadataListName metadataList
	upvar $metadata2ListName metadata2List

	array set currentMetadataArray $metadataList
	array set currentMetadata2Array $metadata2List
	
	if $multiple {
		set metadataRepList [Eval FindAllLanguageVersions $metadataRep]
	} else {
		set metadataRepList $metadataRep
	}
	
	foreach mRep $metadataRepList {
# remove
		set oldPair [Eval GetMetadata $mRep-0,$field]
# puts --$oldPair--
# => --iconet.com.br/banon/2003/08.18.12.15.26-0,targetfile cgi/teste2.py--
		set oldValue [lindex $oldPair 1]	;# because Eval lost extra white spaces oldValue might be disfigured - this might be the case of a target file name like {20 - {[ARTIGO][INPE]}  Michelly Karoline Alves Santana.jpg}
		if [string equal $oldValue $value] {continue}	;# update accelerator
		set currentMetadata2Array($mRep-0,$field) $oldValue
# add
		if ![string equal {} $value] {
			set currentMetadataArray($mRep-0,$field) $value
		}
	}
	set metadataList [array get currentMetadataArray]
	set metadata2List [array get currentMetadata2Array]
}
}

# UpdateMetadataField - end
# ----------------------------------------------------------------------
# DeleteMetadataField
# example:
# DeleteMetadataField $metadataRep contenttype metadata2List 1
# Multiple values are 0 (default) or 1
# 1 means that delete is done for all the metadata repositories (for all languages)

proc DeleteMetadataField {metadataRep field metadata2ListName {multiple {0}}} {
# runs with start
	upvar $metadata2ListName metadata2List
	if $multiple {
		set metadataRepList [Eval FindAllLanguageVersions $metadataRep]
	} else {
		set metadataRepList $metadataRep
	}
	foreach mRep $metadataRepList {
# remove
		set metadata2List [concat $metadata2List [Eval GetMetadata $mRep-0,$field]]
	}
}

# DeleteMetadataField - end
# ----------------------------------------------------------------------
# FindAllLanguageVersions
# metadataRep is the first langague repository
# FindAllLanguageVersions returns the list of all the repositories
# containing a translation of the first language repository
# plus this repository (which appears in the first position in the list)

proc FindAllLanguageVersions {metadataRep} {
# runs with post
	global referenceTable
	set repList $metadataRep
	foreach index [array names referenceTable *,$metadataRep] {
		if {$referenceTable($index) == "+"} {
			regsub {,.*} $index {} mRep
			lappend repList $mRep
		}
	}
	return $repList
}

# FindAllLanguageVersions - end
# ----------------------------------------------------------------------
# TestUpdateLastUpdate
# Used in PerformCheck and MakeDownloadFile
# UpdateLastUpdate is executed whenever the document in $rep has been changed
# force values are 0 or 1
# 1 means to execute, when needed, UpdateLastUpdate even for Bibliography Data Base
# works with gmt
# userName is the name of the advanced user who is creating the version stamp
# it is optional
# updateChildLastUpdateFlag value is 0 or 1
# 1 means to update child last update in procedure UpdateLastUpdate

proc TestUpdateLastUpdate {rep metadataRep {force 1} {userName {}} {updateChildLastUpdateFlag 1}} {
# runs with post
	global homePath
#	global StartApacheServer	;# commented by GJFB on 2018-07-22
	global startApacheServer	;# added by GJFB on 2018-07-22
	global repositoryProperties
	set newer 0
# set xxx [CallTrace]
# Store xxx C:/tmp/bbb auto 0 a
	if [GetDocumentState $rep] {
# the document is the original one
		set lastChange1 [GetLastChange $rep]
		set seconds [RepositoryMTime $rep $homePath]
		set lastChange2 [clock format $seconds -format %Y:%m.%d.%H.%M.%S -gmt 1]
# set xxx [list $lastChange1 $lastChange2]
# Store xxx C:/tmp/bbb auto 0 a
		if ![string equal $lastChange1 $lastChange2] {
# NEWER - UPDATE
			set newer 1
# Update history
# Restart apache server
			if ![info exists repositoryProperties($rep,history)] {
				set repositoryProperties($rep,history) {}
				set startApacheServer 1
			}
# Restart apache server - end
			if {$force || ![TestContentType $rep {Bibliography Data Base}]} {
				UpdateLastUpdate $rep $metadataRep $seconds $userName $updateChildLastUpdateFlag
			}
# Update history - end
		}
	}
	return $newer
}

# TestUpdateLastUpdate - end
# ----------------------------------------------------------------------
# UpdateLastUpdate
# Used when the document in $rep has been changed
# lastupdate for rep and metadataRep (if any) are updated
# metadataRep is for the first language
# if there exist others metatadaReps they are updated too
# if $rep is a metadadaRep (and $metadataRep == {}) then
# the metadataLastUpdate only is updated
# size and numberOfFile are updated too
# userName is the name of the advanced user who is creating the version stamp,
# it is optional
# updateChildLastUpdateFlag value is 0 or 1
# 1 means to update child last update
# set to 1 in procedure ComputeRepositoryList only

# used in ProcessTclPage, TestUpdateLastUpdate, UpdateRepMetadataRep, UpdateHTMLTargetFile, UpdateRepository2, LoadBiblioDB and Script (Administrator page) only.

proc UpdateLastUpdate {
	rep metadataRep {seconds none} {userName {}} {updateChildLastUpdateFlag 1}
} {
# runs with post
	global homePath

# puts --$rep--
# set xxx [CallTrace]
# Store xxx C:/tmp/bbb.txt auto 0 a
	set metadataList {}	;# for add
	set metadata2List {}	;# for remove
# CREATE A NEW VERSION STAMP 
 	if {$seconds == "none"} {set seconds [RepositoryMTime $rep $homePath]}
	set versionStamp [CreateVersionStamp $seconds $userName]
	UpdateHistory $rep $versionStamp

	if {$metadataRep != {}} {
# a metadata exists for this rep
		foreach mRep [FindAllLanguageVersions $metadataRep] {
# Update mTime
# simulate a change
			Load $homePath/col/$mRep/doc/@metadata.refer reference
			Store reference $homePath/col/$mRep/doc/@metadata.refer
# Update mTime - end
#			set seconds2 [DirectoryMTime $homePath/col/$mRep/doc]
			set seconds2 [clock seconds]
			set versionStamp2 [CreateVersionStamp $seconds2 $userName $reference]
			UpdateHistory $mRep $versionStamp2
			UpdateMetadataField $mRep lastupdate $versionStamp metadataList metadata2List
			UpdateMetadataField $mRep metadatalastupdate $versionStamp2 metadataList metadata2List
# set xxx [list $versionStamp $versionStamp2]
# Store xxx C:/tmp/aaa auto 0 a
		}
	} else {
		if [TestContentType $rep Metadata] {
# rep is a metadata (this happens when updating a metadata from
# a bibliographic data base - see LoadBiblioDB)
#			set seconds2 [DirectoryMTime $homePath/col/$rep/doc]
			set seconds2 [clock seconds]
			set versionStamp [CreateVersionStamp $seconds2 $userName]
			UpdateHistory $rep $versionStamp
			UpdateMetadataField $rep metadatalastupdate $versionStamp metadataList metadata2List
		}
	}

# Update size and numberOfFiles
# SIMILAR to a code in LoadMetadata
	foreach {size numberOfFiles} [ComputeInfo $rep] {break}
#	if [string equal {0 Kbyte} $size] #
	if [string equal {0 KiB} $size] {
		file delete $homePath/col/$rep/service/size
		set size {}	;# used by UpdateMetadataField below (to remove size)	
	} else {
		Store size $homePath/col/$rep/service/size
		set repositoryProperties($rep,size) $size	
	}	
	if [string equal {0} $numberOfFiles] {
		file delete $homePath/col/$rep/service/numberOfFiles
		set numberOfFiles {}	;# used by UpdateMetadataField below (to remove numberoffiles)
		catch {file delete $homePath/col/$rep/auxdoc} 	
		catch {file delete $homePath/col/$rep/source} 	
	} else {
		Store numberOfFiles $homePath/col/$rep/service/numberOfFiles
		set repositoryProperties($rep,numberoffiles) $numberOfFiles	
		file mkdir $homePath/col/$rep/auxdoc
		file mkdir $homePath/col/$rep/source
	}
	UpdateMetadataField $metadataRep size $size metadataList metadata2List 1
	UpdateMetadataField $metadataRep numberoffiles $numberOfFiles metadataList metadata2List 1
# Update size and numberOfFiles - end

# UPDATE METADATA
if 0 {
# commented by GJFB on 2020-08-18
	RemoveMetadata $metadata2List
	AddMetadata $metadataList
} else {
	UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}

	if $updateChildLastUpdateFlag {
# Update child lastupdate
		set childRepositories [GetCitingRepositoryList $rep]
		foreach childRepository $childRepositories {
			if [TestContentType $childRepository Metadata] {continue}
			set childMetadataRep [FindMetadataRep $childRepository]
			UpdateLastUpdate $childRepository $childMetadataRep $seconds $userName
#			UpdateLastUpdate $childRepository $childMetadataRep none $userName	;# changed by GJFB on 2010-08-20 - a child may have more than one parent with different last update - time consuming - not needed when updateChildLastUpdateFlag == 1
			file delete $homePath/col/$childRepository/download/doc.zip
		}
# Update child lastupdate - end
	}

## SAVE
#	set saveMetadata 1
#	SaveMetadata
## SAVE - end
if 0 {
# testing mostRecentReferences
	global col
	global URLibServiceRepository
	set auxDoc $col/$URLibServiceRepository/auxdoc
	StoreArray mostRecentReferences $auxDoc/.mostRecentReferences.tcl w list
}
}

# UpdateLastUpdate - end
# ----------------------------------------------------------------------
# PutInternetAddress
# puts the internet address in title

proc PutInternetAddress {} {
# runs with start
	global w
	global serverAddress
	global environmentArray
## server address 
#	set serverAddress [GetServerAddress]
	wm title $w "${Text::URLibService} - $serverAddress \[$environmentArray(ipAddress)\]"
}

# PutInternetAddress - end
# ----------------------------------------------------------------------
# Dialog
# program is used to form the string ${program}ExtraDialog
# Examples:
# Dialog {Yes No} {disabled active} {0 0} Start {URLibService running}
# return 0 if Yes is pressed and 1 if No is pressed
#
# Dialog OK disabled -1 SP {port in use} [lindex $errorMessage 2] $portNumber
#
# Dialog {OK Cancel} {disabled disabled} \
#	{-1 -1} Check {select content type} {} {} {} \
#	listbox {Content Type} $contentTypeList \
#	$rep $entryWidget $entryName $varName]

# button is a list of one or two button names
# default is a list of one or two boolean values
# underline is a list of one of two integer values
#
# widget values are:
# entry (not used - not completly tested)
# listbox
# VisibilityWidget
# PermissionWidget
# MirrorSitesWidget
#
# title values are:
# Content Type
# Visibility
# Permission
# Mirror Sites
# Remote Permission
# Language
# User with Write Permission
# Users with Read Permission
# Host Collection
# Examples:
# Dialog OK disabled -1 Check {no password}

proc Dialog {
	button default underline
	program string {var1 {}} {var2 {}} {var3 {}}
	{widget {}} {title {}} {valueList {}} {rep {}}
	{entryWidget {}} {entryName {}} {varName {}}
} {
# runs with start and post
	global returnDialog
	global environmentArray
#	global wDialogLanguage	;# not used in this procedure
	global homePath
#	global repositoryProperties	;# post
#	global saveMetadata	;# post
#	global startApacheServer
	global applicationName
	global xxVisibility
	global xxDocAccessPermission
	global xxDownloadAccessPermission
	global xxDefaultPermission
#	global xxDocDefaultPermission
#	global xxDownloadDefaultPermission
	global loCoInRep
	global tcl_platform
	global dialogRunning
#	global serverAddressWithIP	;# commented by GJFB on 2014-09-11 - not used
	global URLibServiceRepository
#	global zipPath
#	global pwd

	if {$applicationName == "post"} {return}
	if {$widget == {}} {
		set d .w
		set x {}
	} else {
		set d .widget
		set x { - }
	}
	set test [Dialog_Create $d "URLibService$x$title" -borderwidth 10]
	if $test {
# text
#		set bg [lindex [$d configure -bg] end]
		set bg [$d cget -bg]
		set t [text $d.text -wrap word -fg black \
			-relief flat -bg $bg]
		set font [lindex [lindex [$t configure -font] end] 0]
		$t configure -font {$font 10}
# listbox
		if {$widget == "listbox"} {
			if {$tcl_platform(os) == "Linux"} {
				set height 8
			} else {
				set height 10
			}
			set l $d.f
			set lb [Scrolled_Widget $widget $l list \
				-width 40 -height $height -bg #FFFFFF]
			if [regexp {Host Collection|Mirror Sites} $title] {
				$lb config -width 70
				Load $homePath/col/$loCoInRep/doc/@siteList.txt fileContent
				if [regexp {Mirror Sites} $title] {set valueList {{}}}
				foreach line [split $fileContent \n] {
					lappend valueList "[list [lindex $line 0]]   [lindex $line 1]   [lindex $line 2]"
				}
			} 
			if [regexp {User with Write Permission} $title] {
				$lb config -width 40
				set valueList [concat {{} {administrator}} [GetUserData * write]]
			} 
			if [regexp {Users with Read Permission} $title] {
				$lb config -width 40
				set valueList [concat {{} {administrator}} [GetUserData * read]]
				set valueList [lsort -unique $valueList]
			}
			foreach value $valueList {
				$lb insert end " $value"
			}
			if {$title == {Content Type}} {
				if [Info exists repositoryProperties($rep,type)] {
					set contentType [Get repositoryProperties($rep,type)]
					set i [lsearch $valueList $contentType]
				} else {
					set i 0
				}
				$lb selection set $i
			}
			if {$title == {Copyright}} {
				if [Info exists repositoryProperties($rep,copyright)] {
					set copyrightRepositories [Get repositoryProperties($rep,copyright)]
					foreach copyrightRep $copyrightRepositories {
						set i [lsearch -regexp $valueList $copyrightRep]
						$lb selection set $i
					}
				}
				$lb config -selectmode extended 
				$lb config -width 60			}
			if {$title == {Author Home Page}} {
				if [Info exists repositoryProperties($rep,authorhomepage)] {
					set authorHomePageRep [lindex [Get repositoryProperties($rep,authorhomepage)] end]
					set i [lsearch -regexp $valueList $authorHomePageRep]
				} else {
					set i 0
				}
				$lb selection set $i
				$lb config -width 60
			}
			if {$title == {Mirror Sites}} {
				if [Info exists repositoryProperties($rep,mirrorsites)] {
					set mirrorSites [Get repositoryProperties($rep,mirrorsites)]
					foreach site $mirrorSites {
						set i [lsearch -regexp $valueList $site]
						$lb selection set $i
					}
				}
				$lb config -selectmode extended 
			}
			if {$title == {User with Write Permission}} {
				if [file exists $homePath/col/$rep/service/userName] {
#					Load $homePath/col/$rep/service/userName userName
					LoadService $rep userName userName 1 1
					set i [lsearch -regexp $valueList $userName]
					$lb selection set $i
				}
			}
			if {$title == {Users with Read Permission}} {
				if [Info exists repositoryProperties($rep,authenticatedusers)] {
					set authenticatedUsers [Get repositoryProperties($rep,authenticatedusers)]
					foreach user $authenticatedUsers {
						set i [lsearch -exact $valueList $user]
						$lb selection set $i
					}
				}
				$lb config -selectmode extended 
			}
#			$l config -height [winfo pixels $d 4.5c]	;# 9 * .5	;# doesn't work: hides the buttons in Linux
# frame (extra space)
			set f [frame $d.sp -height .2c]	;# extra space
		}
# entry
if 0 {
		if {$widget == "entry"} {
			set e [frame $d.f]
			set et1 [entry $e.${widget}1 -show * -bg white \
				-textvariable password1 -font {courier 9 roman}]
			set et2 [entry $e.${widget}2 -show * -bg white \
				-textvariable password2 -font {courier 9 roman}]
			grid $et1 -sticky news -pady 3
			grid $et2 -sticky news -pady 3
# frame (extra space)
			set f [frame $d.sp -height .2c]	;# extra space
			LoadService $rep password password1 1 1
			set password2 $password1
		}
}

# text
		if {$widget == "text"} {
			set t2 $d.f
			set tt [Scrolled_Widget $widget $t2 list \
				-width 70 -height 5 -bg #FFFFFF \
				-font {courier 10} -wrap none]
			$tt insert insert $valueList
# frame (extra space)
			set f [frame $d.sp -height .2c]	;# extra space
		}

# VisibilityWidget
		if {$widget == "VisibilityWidget"} {
			frame $d.f -width 6c
			frame $d.f.h1
			checkbutton $d.f.h1.check1 -variable xxVisibility
			text $d.f.h1.text1 -relief flat -height 1 -width 48 -state normal
			TextStyles $d.f.h1.text1
			Insert $d.f.h1.text1 insert {Hide the repository at search.}
			frame $d.f.sp1 -height .4c ;# extra space
			if [file exists $homePath/col/$rep/service/visibility] { 
				LoadService $rep visibility xxVisibility 1
			} else {
				set xxVisibility 1
			}
		}

# PermissionWidget
		if {$widget == "PermissionWidget"} {
			frame $d.f -width 6c
			frame $d.f.h1
			checkbutton $d.f.h1.check1 -variable xxDefaultPermission
			if [string equal {Permission} $title] {
				text $d.f.h1.text1 -relief flat -height 2 -width 61 -state normal
				TextStyles $d.f.h1.text1
				Insert $d.f.h1.text1 insert {Use the local collection default permission\n(see the SP Button).}
				TagAdd $d.f.h1.text1 current9 SP
				set lowerSuffix {permission} 
				set upperSuffix {Permission}
				set secure 0 
			}
			if [string equal {Remote Permission} $title] {
				text $d.f.h1.text1 -relief flat -height 2 -width 71 -state normal
				TextStyles $d.f.h1.text1
#				Insert $d.f.h1.text1 insert {Use the default remote permission\n(just allow the local collection for doc).}
				Insert $d.f.h1.text1 insert {Use the default remote permission\n(see the SP Button of the remote local collection).}
				set lowerSuffix {remotepermission} 
				set upperSuffix {RemotePermission} 
				set secure 1 
			}
# puts --$xxDefaultPermission--
			set xxDefaultPermission 0
			LoadService $rep doc$upperSuffix xxDocAccessPermission $secure
			if {$xxDocAccessPermission == {}} {
				set xxDefaultPermission 1
				set xxDocAccessPermission {allow from all}
			}
			LoadService $rep download$upperSuffix xxDownloadAccessPermission $secure
			if {$xxDownloadAccessPermission == {}} {
				set xxDefaultPermission 1
				set xxDownloadAccessPermission {deny from all}
			}
			PermissionWidget $d xx $xxDocAccessPermission $xxDownloadAccessPermission $xxDefaultPermission
		}

# button
		set width 2.2
		if {$tcl_platform(platform) == "windows"} {
			set height .6
		} elseif {$tcl_platform(os) == "SunOS"} {
			set height .8
		} else {
			set height .6
		}
		set ib [llength $button]	;# number of buttons
		incr ib -1
		set b [frame $d.buttons \
			-width [expr 2.8 * $ib + 2.2]c \
			-height .8c]
		set button0 [lindex $button 0] 
		set default0 [lindex $default 0] 
		set underline0 [lindex $underline 0] 
		set bbutton0 [frame $b.button0 \
				-width [format "%sc" $width] \
				-height [format "%sc" $height]]
		button $bbutton0.0 \
			-command {set returnDialog 0} \
			-default $default0 \
			-underline $underline0 \
			-cursor hand2
		ConfigText $bbutton0.0 $button0
		if $ib {
			set button1 [lindex $button 1] 
			set default1 [lindex $default 1] 
			set underline1 [lindex $underline 1] 
			set bbutton1 [frame $b.button1 \
					-width [format "%sc" $width] \
					-height [format "%sc" $height]]
			button $bbutton1.1 \
				-command {set returnDialog 1} \
				-default $default1 \
				-underline $underline1 \
				-cursor hand2
			ConfigText $bbutton1.1 $button1
		}
		if {$widget == "listbox"} {
			if [regexp {Language|Host Collection} $title] {
#					bind $lb <ButtonPress-1> "$bbutton0.0 configure -state normal"
					bind $lb <ButtonPress-1> [list EnableOKButton $bbutton0.0 $valueList]
					$bbutton0.0 configure -state disabled
			} 
		}
		bind $d <KeyPress> \
			"ProcessKeyForDialog {$button} {$underline} %A"
		pack propagate $b false
		pack propagate $bbutton0 false
		if $ib {pack propagate $bbutton1 false}
		pack $bbutton0 -side left
		if $ib {pack $bbutton1 -side right}
		pack $t -fill x	;# now -tabs is working properly
		if {$widget == {}} {
			pack $t $b -side top
		}
		if {$widget == "listbox"} {
			pack $t $l $f $b -side top
		}
		if {$widget == "entry"} {
			pack $t $e $f $b -side top
		}
		if {$widget == "text"} {
			pack $t $t2 $f $b -side top
		}
		if {$widget == "VisibilityWidget"} {
			pack $t -side top
#			pack $d.f.h1 -fill x
			pack $d.f.h1.check1 $d.f.h1.text1 -side left
			pack $d.f.h1 -side top
			pack $d.f.sp1 -side top
			pack $d.f -side top
		}
		if {$widget == "PermissionWidget"} {
			pack $t -side top
			pack $d.f.h1 -fill x
			pack $d.f.h1.check1 $d.f.h1.text1 -side left
			pack $d.f.h1 -side top
			pack $d.f -side top
			pack $d.tab $b -side top
			pack $d.tab -padx .8c -pady .4c
			bind $d.f.h1.check1 <ButtonPress-1> "ProcessPermissionCheckButton $d"
		}
		pack $b -pady .2c
		pack $bbutton0.0 -fill both -expand true
		if $ib {pack $bbutton1.1 -fill both -expand true}

# insert dialog
		${program}ExtraDialog $t $string $var1 $var2 $var3
	} else {
		set t $d.text
	}

	if {$widget == {}} {
		set extraH 1.6c
	}
	if {$widget == "listbox"} {
# for copyright
#		set extraH 6.1c	;# 1.6c + 4.5c
		set extraH 6.8c	;# for linux; acceptable for windows
	}
	if {$widget == "entry"} {
		set extraH 3.1c
	}
	if {$widget == "text"} {
		set extraH 4.1c
	}
	if {$widget == "VisibilityWidget"} {
		set extraH 3.1c
	}
	if {$widget == "PermissionWidget"} {
#		set extraH 6.4c
		set extraH 6.8c	;# for linux; acceptable for windows
	}
# puts --$widget--
	ComputeGeometry $d $t 2.8c $extraH

	set returnDialog [lsearch $default true]
# puts [CallTrace]
	Dialog_Wait $d returnDialog
# puts OK

	set return $returnDialog
# puts $return
	if {$widget != {} && !$return} {
# OK (return == 0)

# Waiting for the completion of other repository insertions
		WaitQueue
# puts OK
# Waiting for the completion of other repository insertions - end

# Button state and cursor
		regexp {^..} $varName xx	;# dd
		set buttonCursorState [SetWaitingState $entryWidget $xx]
		set dialogRunning 1	;# used by SetCursor
# Button state and cursor - end

# metadataRep
# puts --$rep--
		if [regexp {^Content Type|^Parent Repositories|^Copyright|^Permission|^Remote Permission|^Language|^Host Collection|^User with Write Permission$|^Users with Read Permission$|^Visibility$} $title] {
			set metadataRep [Eval FindMetadataRep $rep]
			
			if ![file isdirectory $homePath/col/$metadataRep] {
				UpdateVariables $metadataRep
				set metadataRep {}
			} else {
				set metadataList {}	;# for add
				set metadata2List {}	;# for remove
			}
		}

		set metadataRepList {}
#		LoadService $rep userName oldUserName 1 1
		set createNewVersionStampFlag 0	;# no creation

# Content Type
		if {$title == {Content Type}} {
			set i [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			Load $homePath/col/$rep/service/type fileContent
			if {$i == 0} {
				file delete $homePath/col/$rep/service/type
				set value {}
			} else {
				set value [lindex $valueList $i]
				Store value $homePath/col/$rep/service/type
			}
# Bibliography Data Base
			if {[string equal $fileContent {Bibliography Data Base}] && \
			![string equal $value {Bibliography Data Base}]} {
# remove
				UpdateMetadataFromBiblioDB2 $rep 1	;# remove
			}
			if {![string equal $fileContent {Bibliography Data Base}] && \
			[string equal $value {Bibliography Data Base}]} {
				UpdateMetadataFromBiblioDB2 $rep
			}
# Bibliography Data Base - end
# Mirror
			if {[string equal $fileContent {Mirror}] && ![string equal $value {Mirror}]} {
# not more a mirror
				set index [lsearch $environmentArray(mirrorRepList) $rep]
				set environmentArray(mirrorRepList) [lreplace $environmentArray(mirrorRepList) $index $index]
# SAVE
#				StoreArray environmentArray ../auxdoc/.environmentArray.tcl
#				StoreArray environmentArray ../auxdoc/.environmentArray2.tcl	;# backup
#				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl	;# added by GJFB on 2010-08-05
				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl w list	;# added by GJFB on 2010-08-05
# SAVE - end
				Set startApacheServer 1
			}
			if {![string equal $fileContent {Mirror}] && [string equal $value {Mirror}]} {
# a new mirror
				UpdateTargetFile $rep mirror.cgi
				lappend environmentArray(mirrorRepList) $rep
if 0 {
# not used
				Load $homePath/col/$rep/doc/@hidedMetadataRepositoryList.txt hidedMetadataRepositoryList
				set hidedMetadataRepositoryList [string trim $hidedMetadataRepositoryList " \n"]
				set environmentArray($rep,hidedmetadatarepositorylist) $hidedMetadataRepositoryList
				Set environmentArray($rep,hidedmetadatarepositorylist) $hidedMetadataRepositoryList
}
# SAVE
#				StoreArray environmentArray ../auxdoc/.environmentArray.tcl
#				StoreArray environmentArray ../auxdoc/.environmentArray2.tcl	;# backup
#				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl	;# added by GJFB on 2010-08-05
				StoreArrayWithBackup environmentArray ../auxdoc/.environmentArray.tcl w list	;# added by GJFB on 2010-08-05
# SAVE - end
				Set startApacheServer 1
			}
# CGI Script
			if {[string equal $fileContent {CGI Script}] && \
			![string equal $value {CGI Script}]} {
# no more a CGI Script
				Set startApacheServer 1
# Migration 23/08/03
				if [Info exists repositoryProperties($rep,cgiscriptname)] {
					Unset repositoryProperties($rep,cgiscriptname)
					file delete $homePath/col/$rep/service/cgiScriptName
				}
# Migration 23/08/03 - end
				Unset repositoryProperties($rep,cgiscriptnamelist)
				file delete $homePath/col/$rep/service/cgiScriptNameList
				file delete -force $homePath/col/$rep/auxdoc/cgi
			}
			if {![string equal $fileContent {CGI Script}] && \
			[string equal $value {CGI Script}]} {
# a new CGI Script
				Eval InstallCGIScript $rep	;# may set startApacheServer to 1
			}
			Eval UpdateRepositoryProperties $rep contenttype

# The code below is itentical to the one in PerformCheck
# Create targetFile and reference for a metadata repository
# when creating a new repository with no metadata and this repository
# is for metadata then we need to create service/targetFile
			CreateTargetFileFile $rep $entryWidget $entryName $varName	;# startApacheServer
			CreateReferenceFile $rep
# Create targetFile and reference for a metadata repository - end
			Eval UpdateMultipleGlobalVariables $rep
# The code below is itentical to the one in PerformCheck - end
# SAVE
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
#			Eval StoreArray referenceTable ../auxdoc/.referenceTable.tcl
			Eval SaveRepositoryProperties
			Eval SaveReferenceTable
# SAVE - end
# Start apache server
			Eval StartApacheServer
# Start apache server - end
#			set fieldName contenttype
			if {$metadataRep != {}} {
				UpdateField $rep $metadataRep contenttype metadataList metadata2List
			}
			set createNewVersionStampFlag 1
		}
# Parent Repositories
		if {$title == {Parent Repositories}} {
			set fileContent [string trim [$tt get 1.0 end] " \n"]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			if {[string compare {} $fileContent] == 0} {
				file delete $homePath/col/$rep/service/reference
			} else {
				Store fileContent $homePath/col/$rep/service/reference
			}
			UpdateCrossReferences $rep $metadataRep metadataList metadata2List ;# uses $homePath/col/$rep/service/reference
#			Eval StoreArray referenceTable ../auxdoc/.referenceTable.tcl
			Eval SaveReferenceTable
			set createNewVersionStampFlag 1
		}
		set updateFlag 0
# Copyright
		if {$title == {Copyright}} {
			set iList [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set copyrightRepositories {}
			foreach i $iList {
				if {$i == 0} {continue}	;# blank line
				lappend copyrightRepositories [lindex [lindex $valueList $i] end]
			}
# Update copyright
			if ![string equal {} $copyrightRepositories] {
				Store copyrightRepositories $homePath/col/$rep/service/copyright
#				Set repositoryProperties($rep,copyright) $copyrightRepositories	
			} else {
				file delete $homePath/col/$rep/service/copyright
			}
			Eval UpdateRepositoryProperties $rep copyright	;# better solution because may delete empty copyright file
			UpdateCrossReferences $rep $metadataRep metadataList metadata2List
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
#			Eval StoreArray referenceTable ../auxdoc/.referenceTable.tcl
			Eval SaveRepositoryProperties
			Eval SaveReferenceTable
			if {$metadataRep != {}} {
				UpdateField $rep $metadataRep copyright metadataList metadata2List
# Add metadatalastupdate in metadataList
# useful to force the update of mostRecentReferences and mostRecentFullTexts
#				set versionStamp [Eval GetVersionStamp $metadataRep]
#				UpdateMetadataField $metadataRep metadatalastupdate $versionStamp metadataList metadata2List 1
				set updateFlag 1
# Add metadatalastupdate in metadataList - end
			}
			set createNewVersionStampFlag 1
		}
# Author Home Page
		if {$title == {Author Home Page}} {
			set i [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			if {$i == 0} {
				file delete $homePath/col/$rep/service/authorHomePage
			} else {
				set value [lindex [lindex $valueList $i] end]
				Store value $homePath/col/$rep/service/authorHomePage
			}
			Eval UpdateRepositoryProperties $rep authorhomepage
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
			Eval SaveRepositoryProperties
		}
# Visibility
		if {$title == {Visibility}} {
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
#			StoreService xxVisibility $rep visibility 1
#			UpdateRobotstxtFile $rep $xxVisibility
			LoadService $rep visibility oldBooleanVisibility 1 1
			if ![string equal $xxVisibility $oldBooleanVisibility] {
				StoreService xxVisibility $rep visibility
				LoadService $rep docPermission docPermission 0 1
				set booleanDocPermission [regexp {deny} $docPermission]
				UpdateRobotstxtFile $rep $xxVisibility $booleanDocPermission
			
				if {$metadataRep != {}} {
					UpdateMetadataField $metadataRep visibility [expr $xxVisibility?{hidden}:{shown}] metadataList metadata2List 1
# Add metadatalastupdate in metadataList
# useful to force the update of mostRecentReferences and mostRecentFullTexts
##				set history [Get repositoryProperties($metadataRep,history)]
##				set versionStamp [lindex $history end]
#				set versionStamp [Eval GetVersionStamp $metadataRep]
#				UpdateMetadataField $metadataRep metadatalastupdate $versionStamp metadataList metadata2List 1
					set updateFlag 1
# Add metadatalastupdate in metadataList - end
				}
				set createNewVersionStampFlag 1
			}
		}
		if $updateFlag {
			set versionStamp [Eval GetVersionStamp $metadataRep]
			UpdateMetadataField $metadataRep metadatalastupdate $versionStamp metadataList metadata2List 1
		}
# Permission and Remote Permission
		if [regexp {^Permission|^Remote Permission} $title] {
			if [string equal {Permission} $title] {
				set lowerSuffix {permission} 
				set upperSuffix {Permission}
				set secure 0 
			}
			if [string equal {Remote Permission} $title] {
				set lowerSuffix {remotepermission} 
				set upperSuffix {RemotePermission} 
				set secure 1 
			}
			if [ComputeAccessPermission doc $d xx] {
# syntax error
				LeaveQueue [pid] ;# added by GJFB on 2011-09-26 - otherwise wait for ever (in WaitQueue above) when pressing OK in the Dialog below
				Dialog $button $default $underline \
				$program $string $var1 $var2 {} \
				$widget $title $valueList $rep \
				$entryWidget $entryName $varName
# Button state and cursor
				set dialogRunning 0	;# used by SetCursor
				UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
				LeaveQueue [pid]
				return
			}
			if [ComputeAccessPermission download $d xx] {
# syntax error
				LeaveQueue [pid] ;# added by GJFB on 2011-09-26 - otherwise wait for ever (in WaitQueue above) when pressing OK in the Dialog below
				Dialog $button $default $underline \
				$program $string $var1 $var2 {} \
				$widget $title $valueList $rep \
				$entryWidget $entryName $varName
# Button state and cursor
				set dialogRunning 0	;# used by SetCursor
				UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
				LeaveQueue [pid]
				return
			}
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			LoadService $rep docPermission oldDocPermission 0 1
			if {$oldDocPermission == {}} {
				set oldDocPermission {allow from all}	;# added by GJFB on 2015-05-08
			}
			
# Store read permission
			set startApacheServer [StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
			$rep $metadataRep $upperSuffix $lowerSuffix $secure $title metadataList metadata2List]
# Store read permission - end

# Updadte robots.txt
# puts $upperSuffix
# puts --$xxDefaultPermission--
# puts [list $xxDocAccessPermission $oldDocPermission]
 			if [string equal {Permission} $upperSuffix] {	;# added by GJFB on 2015-05-08
				if $xxDefaultPermission {
					set xxDocAccessPermission {allow from all}	;# added by GJFB on 2015-05-08
				}
				if ![string equal $xxDocAccessPermission $oldDocPermission] {
					LoadService $rep visibility booleanVisibility 1 1
					set booleanDocPermission [regexp {deny} $xxDocAccessPermission]
					UpdateRobotstxtFile $rep $booleanVisibility $booleanDocPermission	;# added by GJFB on 2011-06-13
				}
			}
# Updadte robots.txt - end

#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
			Eval SaveRepositoryProperties

			if $startApacheServer {
				Set startApacheServer 1
				Eval StartApacheServer
			}
			UpdateAccessFile $rep
			set createNewVersionStampFlag 1
		}
# Mirror Sites
		if {$title == {Mirror Sites}} {
			set iList [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set mirrorSites {}
			foreach i $iList {
				lappend mirrorSites [lindex [lindex $valueList $i] 1]
			}
# Update mirrorSites
			if ![string equal {{}} $mirrorSites] {
				StoreService mirrorSites $rep mirrorSites 1 1
#				Set repositoryProperties($rep,mirrorsites) $mirrorSites	
			} else {
				file delete $homePath/col/$rep/service/mirrorSites
			}
			Eval UpdateRepositoryProperties $rep mirrorsites	;# better solution because may delete empty mirrorSites file
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
			Eval SaveRepositoryProperties
		}
# Language
		if {$title == {Language}} {
			set i [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set value [lindex $valueList $i]
			if [string equal {} $value] {
				file delete $homePath/col/$rep/service/language
			} else {
				Store value $homePath/col/$rep/service/language
			}
			Eval UpdateRepositoryProperties $rep language
			if [Eval TestContentType $rep {Metadata}] {
# added by GJFB on 2013-02-11 to search for the proper metadata repository based on its language and display the corresponding entry in the proper language
# useful for multiple language document to display resume or archival unit document in the proper language
				if [Info exists repositoryProperties($rep,language)] {
					set language [Get repositoryProperties($rep,language)]	
					regexp {\[(.*)\]} $language m language	;# English {[en]} -> en
					UpdateMetadataField $rep textlanguage $language metadataList metadata2List 1
				} else {
					DeleteMetadataField $rep textlanguage metadata2List 1
				}
			} else {
				if {$metadataRep != {}} {
					UpdateField $rep $metadataRep language metadataList metadata2List
				}
			}
			Eval SaveRepositoryProperties
			set createNewVersionStampFlag 1
		}
# User with Write Permission
		if {$title == {User with Write Permission}} {
			set iList [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set userName {}
			foreach i $iList {
				lappend userName [lindex $valueList $i]
			}
# Update userName
			LoadService $rep userName oldUserName 1 1
			if ![string equal $userName $oldUserName] {
				if ![string equal {{}} $userName] {
# new user name
					StoreService userName $rep userName 1 1
#					MakeCgiScript $URLibServiceRepository $rep update update.tcl Update cgi2
					MakeCgiScript $URLibServiceRepository $rep update mirror.tcl {CreateMirror 1} cgi2
					if {$metadataRep != {}} {
						UpdateMetadataField $metadataRep username $userName metadataList metadata2List 1

#						DeleteMetadataField $metadataRep documentstage metadata2List 1
						Load $homePath/col/$metadataRep/doc/@metadata.refer referMetadata
						set userGroup [GetReferField $referMetadata @usergroup]
						lappend userGroup $userName
						set userGroup [lsort -unique $userGroup]
						set referMetadata [UpdateRefer $referMetadata [concat usergroup $userGroup]]
#						regsub "\n%@documentstage \[^\n\]*" $referMetadata {} referMetadata
						Store referMetadata $homePath/col/$metadataRep/doc/@metadata.refer
					}
				} else {
# empty user name
					file delete $homePath/col/$rep/service/userName
#					file delete -force $homePath/col/$rep/auxdoc/cgi2
					file delete -force $homePath/col/$rep/auxdoc/cgi2/update
					if {$metadataRep != {}} {
						DeleteMetadataField $metadataRep username metadata2List 1
#						DeleteMetadataField $metadataRep documentstage metadata2List 1
#						Load $homePath/col/$metadataRep/doc/@metadata.refer entry
#						regsub "\n%@documentstage \[^\n\]*" $entry {} entry
#						Store entry $homePath/col/$metadataRep/doc/@metadata.refer
					}
				}
# Migration 3/3/03
				file delete $homePath/col/$rep/service/password
# Migration 3/3/03 - end
				Eval UpdateRepositoryProperties $rep username	;# better solution because may delete empty userName file
#				Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
				Eval SaveRepositoryProperties
				UpdateAccessFile $rep	;# added by GJFB on 2011-04-09
#				if [string equal {} $oldUserName] {set oldUserName administrator}
				set createNewVersionStampFlag 1
			}
#			UpdateAccessFile $rep	;# commented by GJFB on 2011-04-09
		}
# User with Write Permission - end
# Users with Read Permission
		if {$title == {Users with Read Permission}} {
			set iList [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set authenticatedUsers {}
			foreach i $iList {
				lappend authenticatedUsers [lindex $valueList $i]
			}
# Update authenticatedUsers
			if ![string equal {{}} $authenticatedUsers] {
 				Store authenticatedUsers $homePath/col/$rep/service/authenticatedUsers
if 0 {
# Make review cgi script
				set childRepositories [Eval GetCitingRepositoryList $rep]
				foreach childRepository $childRepositories {
					set targetFile [Get repositoryProperties($childRepository,targetfile)]
					if [string equal {@reviewSheet.html} $targetFile] {
# a work with at least one assigned reviewer
						MakeCgiScript $URLibServiceRepository $rep review review.tcl Review cgi2
						break
					}
				}
# Make review cgi script - end
}
#				Set repositoryProperties($rep,authenticatedusers) $authenticatedUsers	
				if {$metadataRep != {}} {
					UpdateMetadataField $metadataRep readergroup $authenticatedUsers metadataList metadata2List 1
				}
			} else {
				file delete $homePath/col/$rep/service/authenticatedUsers
				if {$metadataRep != {}} {
					DeleteMetadataField $metadataRep readergroup metadata2List 1
				}
			}
			Eval UpdateRepositoryProperties $rep authenticatedusers	;# better solution because may delete empty authenticatedUsers file
#			Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
			Eval SaveRepositoryProperties
#			if [file exists $homePath/col/$rep/service/readPasswords] {
#				exec $apachePath htpasswd -f $serverRoot/conf/httpd.conf &
#			} else {
#			}

#			Set startApacheServer 1
#			Eval StartApacheServer
			UpdateAccessFile $rep
#			set createNewVersionStampFlag 1	;# commented by GJFB on 2011-07-05 - Users with Read Permission option may be changed for documents that are copies (in other lcal collections), therefore it is convenient to leave the version stamp unchanged even though the Users with Read Permission is changed
		}
# Users with Read Permission - end
# Host Collection
		if {$title == {Host Collection}} {
			set i [$lb curselection]
			destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
			set value [lindex $valueList $i]
			regsub -all {   } $value { } value
			if [Dialog {Yes No} {disabled active} {0 0} Check {transferring the copyright} $value] {
# don't transfer
# Button state and cursor
				set dialogRunning 0	;# used by SetCursor
				UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
				ControlBCButtonState $entryWidget $entryName $varName
				LeaveQueue [pid]
				return
			}
# TRANSFER COPYRIGHT
			set return [Eval TransferCopyright $rep $metadataRep $value administrator]
			if [string equal {TransferCopyright: ----} $return] {
# a copyright transfer has been done but (A) receives a premature return of CaptureRepository
# because the transfer lasts longer than the MultipleExecute time-out
# do nothing
			} else {
				if ![string equal {} $return] {
					if {[string equal {unknown host} $return] || \
					[string equal {site not allowed to transfer copyright} $return] || \
					[string equal {@sitesAllowedToTransferCopyright.tcl not found or permission denied} $return]} {
						Dialog OK disabled -1 Check $return $value
					} else {
						set log "Dialog: $return"
						puts $log
						Store log $homePath/@errorLog auto 0 a
					}
# Button state and cursor
					set dialogRunning 0	;# used by SetCursor
					UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
					ControlBCButtonState $entryWidget $entryName $varName
					LeaveQueue [pid]
					return
				}
			}
#		# else #
## same code as in TransferCopyright
## Update download files
## unless title is {User with Write Permission} since in this case service/userName is not part of doc.zip
#			if {$title != {User with Write Permission}} #
#				Eval UpdateDownloadFilesByAdministrator $rep	;# commented by GJFB on 2012-11-09 - now below, after CREATE A NEW VERSION STAMP, otherwise doc.zip has a wrong version stamp
#			#
## Update download files - end
		}
		if [regexp {^Content Type|^Parent Repositories|^Copyright|^Visibility$|^Permission|^Remote Permission|^Language|^User with Write Permission$|^Users with Read Permission$} $title] {
			if [Eval TestContentType $rep {Metadata}] {set metadataRep $rep}
			if {$metadataRep != {}} {
				if $createNewVersionStampFlag {
# Update history
# CREATE A NEW VERSION STAMP (for the metadata repository (metadataRep))
					Load $homePath/col/$metadataRep/doc/@metadata.refer referMetadata
					set seconds [clock seconds]
#					set metadataVersionStamp [CreateVersionStamp $seconds $oldUserName $referMetadata]
					set metadataVersionStamp [CreateVersionStamp $seconds administrator $referMetadata]	;# it is assumed that the administrator acts on behalf of the old user
					Eval UpdateHistory $metadataRep $metadataVersionStamp	
# Update history - end
					UpdateMetadataField $metadataRep metadatalastupdate $metadataVersionStamp metadataList metadata2List 1
# Delete out-of-date doc.zip
# metadata have changed (e.g., remote permission), therefore child doc.zip are out-of-date (e.g., files like .htaccess)
					Eval DeleteChildOutOfDateDocZip $rep
# Delete out-of-date doc.zip - end
				}
# UPDATE METADATA
# puts [list $metadataList $metadata2List]
if 0 {
# commented by GJFB on 2020-08-18
				Eval RemoveMetadata $metadata2List
				Eval AddMetadata $metadataList
} else {
				Eval UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
				Set saveMetadata 1
			} 
		}
# SAVE
		if {$title != {Host Collection}} {
			Eval SaveMetadata
			Eval UpdateRepositoryListForPost [concat $rep $metadataRepList]
		}
# SAVE - end

# same code as in TransferCopyright
# Update download files
# unless title is {User with Write Permission} since in this case service/userName is not part of doc.zip
		if {$title != {Host Collection} && $title != {User with Write Permission}} {
# puts OK
			Eval UpdateDownloadFilesByAdministrator $rep
		}
# Update download files - end

# Button state and cursor
		set dialogRunning 0	;# used by SetCursor
		UnsetWaitingState $entryWidget $xx $buttonCursorState
# Button state and cursor - end
		LeaveQueue [pid]
# update text		
		XXRepository $entryWidget $entryName $varName
	} else {
# Cancel
		destroy $d	;# this sets returnDialog to default (cf. Dialog_Wait)
	}
# puts --$return--
	return $return
}

# Dialog - end
# ----------------------------------------------------------------------
# DeleteChildOutOfDateDocZip
# used in Dialog only
# there is a similar code in UpdateLastUpdate

proc DeleteChildOutOfDateDocZip {rep} {
# runs with post
	global homePath
	
	set childRepositories [GetCitingRepositoryList $rep]
	foreach childRepository $childRepositories {
		if [TestContentType $childRepository Metadata] {continue}
		DeleteChildOutOfDateDocZip $childRepository
		file delete $homePath/col/$childRepository/download/doc.zip
	}
}

# DeleteChildOutOfDateDocZip - end
# ----------------------------------------------------------------------
proc EnableOKButton {win valueList} {
	if {[string compare {} $valueList] != 0} {
		$win configure -state normal
	}
}

# EnableOKButton - end
# ----------------------------------------------------------------------
# ProcessPermissionCheckButton
# directory values are doc or download

# proc ProcessPermissionCheckButton {parent directory}
proc ProcessPermissionCheckButton {parent} {
#	if {[string compare $directory doc] == 0} {set vx v1}
#	if {[string compare $directory download] == 0} {set vx v2}
#	regsub {d} $directory {D} directory
#	upvar #0 xx${directory}DefaultPermission xxDirectoryDefaultPermission
	global xxDefaultPermission
#	if $xxDirectoryDefaultPermission
	if $xxDefaultPermission {
#		pack $parent.tab.$vx.h1 -side top
#		pack $parent.tab.$vx.h2 -side top -expand true
#		pack $parent.tab.$vx.h3 -side bottom
		pack $parent.tab.v1.h1 -side top
		pack $parent.tab.v1.h2 -side top -expand true
		pack $parent.tab.v1.h3 -side bottom
		pack $parent.tab.v2.h1 -side top
		pack $parent.tab.v2.h2 -side top -expand true
		pack $parent.tab.v2.h3 -side bottom
	} else {
		pack forget $parent.tab.v1.h3 $parent.tab.v1.h2 $parent.tab.v1.h1
		pack forget $parent.tab.v2.h3 $parent.tab.v2.h2 $parent.tab.v2.h1
	} 
}

# ProcessPermissionCheckButton - end
# ----------------------------------------------------------------------
# Dialog_Create
# Example 33-1

# arrayName not used

proc Dialog_Create {top englishText args} {
# runs with start
	global dialog
	upvar #0 $top var
	upvar #0 Text::$englishText varText
## declare a global variable like spDialogLanguage
#	regsub {\.(.*)} $top {\1DialogLanguage} varName
#	upvar #0 $varName dialogLanguage
#puts $varName
#puts $dialogLanguage
## declare a global variable like spDialogLanguage - end
#	set currentLanguage $array(spLanguageEntry)
#	if {[winfo exists $top] && \
		([string compare $currentLanguage $dialogLanguage] == 0 || \
		$currentLanguage == "")}
	if [winfo exists $top] {
		switch -- [wm state $top] {
			normal {
				# Raise a buried window
				raise $top
			}
			withdrawn -
			iconified {
				# Open and restore geometry
				wm deiconify $top
				catch {wm geometry $top $dialog(geo,$top)}
			}
		}
		return 0
	} else {
		if [winfo exists $top] {destroy $top}
		eval {toplevel $top} $args
		wm title $top $varText
		wm resizable $top 1 0
#		wm iconify $top
		return 1
	}
}

# Dialog_Create - end
# ----------------------------------------------------------------------
# Dialog_Wait

proc Dialog_Wait {top varName {focus {}} \
	{parameters {}} {entryNames {}} {grab {1}}} {
# runs with start
	upvar $varName var
# Poke the variable if the user nukes the window
	bind $top <Destroy> [list set $varName $var]

# Grab focus for the dialog
	if {[string length $focus] == 0} {
		set focus $top
	}
	set old [focus -displayof $top]
	focus $focus
#	catch {tkwait visibility $top}	;# doesn't work when pack doesn't occur immediatly
	if $grab {catch {grab $top}}

# Wait for the dialog to complete
	wm deiconify $top
	while 1 {
		vwait $varName
# window has changed size
# update the menus
		if {$var == "dd"} {		;# var == dd(ok)
			set aWhich [lindex $parameters 0]
			set aWhere [lindex $parameters 1]
			set entryName1 [lindex $entryNames 0]
			set entryName2 [lindex $entryNames 1]
# add a delay for the case of the empty "which" entry
			after 500 UpdateMenu $aWhich $entryName1 dd(result1)
			after 500 UpdateMenu $aWhere $entryName2 dd(result2)
			after 500 UpdateMenu2 $aWhich $entryName1 dd(result1)
			after 500 UpdateMenu2 $aWhere $entryName2 dd(result2)
		}
		if {$var == "sp"} {		;# var == sp(ok)
			set aPreference [lindex $parameters 0]
			set entryName1 [lindex $entryNames 0]
# add a delay for the case of the empty "which" entry
			after 500 UpdateMenu $aPreference $entryName1 \
				sp(result1)
			after 500 UpdateMenu2 $aPreference $entryName1 \
				sp(result1)
		}
		if {$var == "0" || $var =="1"} {break}
# window has changed size - end
	}
	catch {grab release $top}
	focus $old
}

# Dialog_Wait - end
# ----------------------------------------------------------------------
# Dialog_Dismiss

proc Dialog_Dismiss {top} {
# runs with start
	global dialog
	# Save current size and position
	catch {
		# window may have been deleted
		set dialog(geo,$top) [wm geometry $top]
		wm withdraw $top
	}
}

# Dialog_Dismiss - end
# ----------------------------------------------------------------------
# ConfigText

proc ConfigText {widget {englishText {}}} {
# runs with start
	upvar #0 Text::$widget var
	if {$englishText == ""} {
		$widget configure -text $var
	} else {
		$widget configure -text [Translate $englishText]
	}
}

# ConfigText - end
# ----------------------------------------------------------------------
# Translate

proc Translate {englishText \
	{var1 {}} {var2 {}} {var3 {}} {var4 {}} {var5 {}}} {
# runs with start
	upvar #0 Text::$englishText varText
	upvar #0 Text::Mon Mon
	upvar #0 Text::Tue Tue
	upvar #0 Text::Wed Wed
	upvar #0 Text::Thu Thu
	upvar #0 Text::Fri Fri
	upvar #0 Text::Sat Sat
	upvar #0 Text::Sun Sun
	upvar #0 Text::Jan Jan
	upvar #0 Text::Feb Feb
	upvar #0 Text::Mar Mar
	upvar #0 Text::Apr Apr
	upvar #0 Text::May May
	upvar #0 Text::Jun Jun
	upvar #0 Text::Jul Jul
	upvar #0 Text::Aug Aug
	upvar #0 Text::Sep Sep
	upvar #0 Text::Oct Oct
	upvar #0 Text::Nov Nov
	upvar #0 Text::Dec Dec
	if [info exists $var1] {
		set var1 [subst $$var1]
	}
	if [info exists $var2] {
		set var2 [subst $$var2]
	}
	if [info exists $var3] {
		set var3 [subst $$var3]
	}
	if [info exists $var4] {
		set var4 [subst $$var4]
	}
	if [info exists $var5] {
		set var5 [subst $$var5]
	}
	return [subst $varText]	;# may use var1, var2, ...
}

# Translate - end
# ----------------------------------------------------------------------
# TextStyles

proc TextStyles {t} {
# runs with start
	set font [lindex [lindex [$t configure -font] end] 0]
	$t tag configure italic8 -font {$font 8 italic}
	$t tag configure italic -font {$font 10 italic}
	$t tag configure italic11 -font {$font 11 italic}
	$t tag configure bold -font {$font 10 bold}
	$t tag configure bold12 -font {$font 12 bold}
	$t tag configure current9 -font {$font 9}
	$t tag configure fixed -font {courier 10}
	$t tag configure fixed9 -font {courier 9}
	$t tag configure courier11 -font {courier 11}
	$t tag configure times -font {times 10}
	$t tag configure magenta -background #ffccff
	$t tag configure cyan -background #ccffff
	$t tag configure blue -foreground #000099
	$t tag configure green -foreground #00bb00
	$t tag configure blackgreen -foreground #007700
	$t tag configure gray -foreground #888888
	$t tag configure underline -underline true
	$t tag configure wrap -wrap word
	$t tag configure indent -lmargin1 0.1i -lmargin2 0.1i
}

# TextStyles - end
# ----------------------------------------------------------------------
# Insert

proc Insert {widget where englishText {flag {}} \
	{var1 {}} {var2 {}} {var3 {}} {var4 {}} {var5 {}}} {
# runs with start
	set text [Translate $englishText $var1 $var2 $var3 $var4 $var5]
	$widget insert $where $text $flag
}

# Insert - end
# ----------------------------------------------------------------------
# TagAdd
# option value can be -backward

proc TagAdd {t tagName englishText {option {-forward}} \
	{var1 {}} {var2 {}}} {
# runs with start
	upvar #0 Text::$englishText varText
	set text [subst $varText]	;# may use var1
	regsub -all {\$} $text {\$} text	;# $ -> \$ (eg., target file name: ccc$.doc)
	set linestart "insert linestart"
	set lineend "insert lineend"
	if {$option == "-forward"} {
# puts [list $t search $option -count cnt -regexp -- $text $linestart $lineend]
# => .ddhelp.h.t search -forward -count cnt -regexp -- which {insert linestart} {insert lineend}
#		set start [$t search -forward -count cnt -regexp -- $text $linestart $lineend]
		set start [$t search -forward -count cnt -- $text $linestart $lineend]
	} else {
#		set start [$t search -backward -count cnt -regexp -- $text $lineend $linestart]
		set start [$t search -backward -count cnt -- $text $lineend $linestart]
	}
	if [info exists cnt] {
# puts [list $t tag add $tagName $start "$start +$cnt chars"]
# cnt may not exist - for example, when opening the URLibService Check window and clicking the left mouse button with the ctrl button pressed
		$t tag add $tagName $start "$start +$cnt chars"
	}
}

# TagAdd - end
# ----------------------------------------------------------------------
# ComputeGeometry
# computes geometry for Dialog and Warning procedures

proc ComputeGeometry {w t extraW extraH} {
# runs with start
	set font [list [lindex [lindex [$t configure -font] end] 0]]
	set text [split [$t get 1.0 end] \n]
	set numberOfLines [llength $text]
	set maxLineWidth 0
	foreach line $text {
		set maxLineWidth \
			[Max $maxLineWidth [font measure $font $line]]
	}
	$t configure -height $numberOfLines
# .25c instead of .5c (= 1c/2)
# 1.2c instead of 1.4c (= 2.8c/2)
	set center [expr $maxLineWidth. / [winfo pixels $w 2c] + 1.2]c
	$t configure -tabs "$center center"
	$t configure -state disabled
	set W [expr $maxLineWidth + [winfo pixels $w $extraW]]
	set H [expr 20 * $numberOfLines + [winfo pixels $w $extraH]]
	set sw [winfo screenwidth .]
	set sh [winfo screenheight .]
	set x [expr $sw / 2 - $W / 2]
	set y [expr $sh / 2 - $H / 2]
	wm geometry $w ${W}x$H+$x+$y
}

# ComputeGeometry - end
# ----------------------------------------------------------------------
# LogInsert
# example:
# LogInsert [list $log insert end \n]

proc LogInsert {cmd {load 1} {store 1} {display 1}} {
# runs with start and post
	global textLog
	if $load {LoadTextLog}
	lappend textLog $cmd
	if $display {DisplayTextLog}
	if $store {
		if $display {DisplayTextLog}
		StoreTextLog
	}
}

# LogInsert - end
# ----------------------------------------------------------------------
# DisplayTextLog

proc DisplayTextLog {} {
# runs with start and post
	global textLog
	global log
	global applicationName
	global homePath

	if {$applicationName == "start"} {
		$log delete 1.0 end
		if [catch {foreach cmd $textLog {eval [join $cmd \n]}} message] {
			set textLog {}
			lappend textLog {{Insert .window.main.output.log end {new line}}}
			lappend textLog {{Insert .window.main.output.log insert {cleared Log}}}
			lappend textLog {{Insert .window.main.output.log end {new line}}}
			foreach cmd $textLog {eval [join $cmd \n]}
			StoreTextLog
			set log2 "DisplayTextLog: $message"
			Store log2 $homePath/@errorLog auto 0 a
		}
		$log yview moveto 1.0
	}
}

# DisplayTextLog - end
# ----------------------------------------------------------------------
# NukedWindow

proc NukedWindow {} {
# runs with start
	global w
	global closing	;# set in Run-close
#	if [winfo exists .dd] {wm withdraw .dd}
#	if [winfo exists .sp] {wm withdraw .sp}
	if [winfo exists .ddhelp] {wm withdraw .ddhelp}
	if [winfo exists .sphelp] {wm withdraw .sphelp}
	if [winfo exists .xxdirectory] {wm withdraw .xxdirectory}
	if [winfo exists .xxrepository] {wm withdraw .xxrepository}
#	Run-exit
	if {![winfo exists $w] && ![info exists closing]} {Run-exit}
}

# NukedWindow - end
# ----------------------------------------------------------------------
# Scroll_Set
# Example 27-2
# Scroll_Set manages optional scrollbars.
#

proc Scroll_Set {scrollbar geoCmd offset size} {
	if {$offset != 0.0 || $size != 1.0} {
		eval $geoCmd	;# Make sure it is visible
		$scrollbar set $offset $size
	} else {
		set manager [lindex $geoCmd 0]
		$manager forget $scrollbar	;# hide it
	}
}

# Scroll_Set - end
# ----------------------------------------------------------------------
# Scrolled_Widget
# Adapted form Example 27-3
# Widget with optional scrollbars.
# Examples:
# Scrolled_Widget text $f log $args
# Scrolled_Widget listbox $f list $args
#

proc Scrolled_Widget {widget f win args} {
	frame $f
	$widget $f.$win \
		-xscrollcommand [list Scroll_Set $f.xscroll \
			[list grid $f.xscroll -row 1 -column 0 -sticky we]] \
		-yscrollcommand [list Scroll_Set $f.yscroll \
			[list grid $f.yscroll -row 0 -column 1 -sticky ns]]
	eval {$f.$win configure} $args
	scrollbar $f.xscroll -orient horizontal \
		-command [list $f.$win xview]
	scrollbar $f.yscroll -orient vertical \
		-command [list $f.$win yview]
	grid $f.$win $f.yscroll -sticky news
	grid $f.xscroll -sticky news
	grid rowconfigure $f 0 -weight 1
	grid columnconfigure $f 0 -weight 1
	return $f.$win
}

# Scrolled_Widget - end
# ----------------------------------------------------------------------
# CreateRepMetadataRep
# Creates a repository and its associated metadata repository
# documentType values are empty or default or directory
# empty means to deposit nothing in the new repository
# default means to deposit the document from the default repository
# directory means to deposit a folder document named documentPath
# metadataEntryList is a list of field names and field values
# example of metadataEntryList: {{area SO150000} {date 1997} {base Landsat-TM}}
# these entries are ADDED to the default metadata
# used in:
# ProvideRepository (utilitiesMirror.tcl)
# DDDialog (DDDialog.tcl)
# Examples:
# return [CreateRepMetadataRep empty {} $metadataEntryList]
#
# set metadataCaptured [GetClipboard]	;# to paste the metadata
# set repositoryName [CreateRepMetadataRep $ddChoice1 $dd(result1) {} $metadataCaptured]
# metadataCaptured is meaningful only when documentPath is relative to a repository
# targetFileOption value is disable or enable
# option value is "copy" or "preserve" or "delete" (see DDRoutine)
# unzip value is 0 or 1; 1 means to unzip or unrar the deposited document
# $reference ==>
# {%0 Misc} {%@tertiarytype } {%A aa} {%I Deposited in the URLib collection.} {%X aa} {%T tt} {%@secondarykey INPE--/} 
# start value is 0 or 1; 1 means to start the apache server
# 0 is used only when CreateRepMetadataRep is launched via socket (cf. cgi/submit.tcl)
# in this case apache is started in ServeLocalCollection
# otherwise Submit (in utilities1.tcl) wouldn't receive the readable event
# when running under UNIX platform
# repName and metadataRepName are used when $documentType == "directory"
# if both are empty then two repositories are created, the second being the metadata repository
# userName is the name of the user who is submitting the document
# contentType values are Metadata, External Contribution, ...
# documentStage value is any string (it is defined in displayControl.tcl)
## documentStage is just used to detect ePrint
# documentStage not used any more
# readPermission values examples are {} (means to use default permission)
# or {deny from all and allow from 150.163}
# or {150.163}
# or intranet
# nextUser value is {} or a user name (advanced user) for the next update
## copyToSource value is 0 or 1; 1 means to deposit the document into the source as well
# copyToSource value is 0 or 1; 1 means to deposit the document into the source (only)
# readUserList value is {} or a list of read user names
# childRepositories is a list of child repositories for the repository to be created
# used by the review system (see ProcessReview) - not used anymore
# visibility value is 0 or 1; 0 means shown, 1 means hidden repository at search
# readUserListForParentRepositories is used for a workRepository of the review system
# copyAbstractToDoc value is 0 or 1; 1 means to deposit the abstract as an html file in doc
# used when documentType value is {empty}
# used by the 8ICSHMM
# postSubmissionScriptRepList is a list of repositories containing scripts to process
# the submitted files
# Examples of repositories containing post submission scripts:
# iconet.com.br/banon/2005/12.29.23.16 (A script to process the INPE Clippings)
# iconet.com.br/banon/2005/09.07.19.12 (A script to process the INPE CRI-Clippings)
# ePrintAdministrator is defined in displayControl.tcl (used when an ePrint is closed - see previous edition)
# previousEditionSite (used when an ePrint is closed - see previous edition)
# password is the administrator coded password - needed to update a previous edition
# copyright value is a copyright repository
# submissionAgreementText is a list containing the submission agreement text

proc CreateRepMetadataRep {
	{documentType {empty}} {documentPath {}}
	{metadataEntryList {}} {metadataCaptured 0} {targetFileOption disable}
	{reference {}} {option copy} {unzip 0} {start 1} {repName {}}
	{metadataRepName {}} {userName {}} {contentType {}} {documentStage {}}
	{saveMetadata2 1} {readPermission {}} {nextUser {}} {copyToSource 0}
	{readUserList {}} {childRepositories {}} {visibility 0}
	{readUserListForParentRepositories {}} {copyAbstractToDoc 0}
	{postSubmissionScriptRepList {}} {languageFieldValue {}}
	{ePrintAdministrator {}} {previousEditionSite {}} {password {}}
	{copyright {}} {submissionAgreementText {}}
} {
# runs with start and post
# must run also under start because of the warning dialogs
# set xxx [CallTrace]
# Store xxx C:/tmp/bbb auto 0 a
	global col
	global defaultMetadataRepository
#	global searchRepository
	global commonWords
#	global metadataArray
#	global saveMetadata
	global homePath
	global bcChoice
	global URLibServiceRepository
	global applicationName
	global keyRepositoryList
	global loCoInRep
	
# puts --$metadataEntryList--
# puts --$reference--

# set enableTrace 0
Load $homePath/col/$URLibServiceRepository/auxdoc/@enableTrace enableTrace
TraceProcedure CreateRepMetadataRep
TraceProcedure [clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]
TraceProcedure [CallTrace]

TraceProcedure	;# add executing time interval
TraceProcedure [list targetFileOption = $targetFileOption]

	if [file isdirectory $col/$repName/doc] {return $repName}

	if {$documentType == "directory"} {
		if {[regexp "$homePath/col/(\[^/\]*/\[^/\]*/\[^/\]*/\[^/\]*)/doc" \
		$documentPath m whichRep] && !$metadataCaptured || \
		[info exists bcChoice] && [string equal {add} $bcChoice]} {
			if [Eval TestContentType $whichRep Metadata] {
# add a metadata repository (this is used to create metadata in several languages)
# CREATE (metadata repository)
				set repName [CreateNewRepository $documentType $documentPath disable copy 0 {} 0 Metadata 0 $userName]
				if {[info exists bcChoice] && [string equal add $bcChoice]} {
# the metadata was put on the clipboard by the option "add"
					Load $homePath/clipboard/@metadata.refer metadataRefer
					file delete $homePath/clipboard/@metadata.refer
				} else {
# the metadata is in $col/$whichRep/doc/@metadata.refer
					Load $col/$whichRep/doc/@metadata.refer metadataRefer
				}
				
# Add userName to the usergroup field value
# added by GJFB on 2015-12-18
				set userGroup [GetReferField $metadataRefer @usergroup]
				lappend userGroup $userName
				set userGroup [lsort -unique $userGroup]
				set metadataRefer [UpdateRefer $metadataRefer [concat usergroup $userGroup]]
# Add userName to the usergroup field value - end

# Update the metadata
# drop %2
#				regsub {(%2[^%]*)} $metadataRefer {} metadataRefer
				regsub "%2 \[^\n\]*\n" $metadataRefer\n {} metadataRefer	;# it is assumed that the field values don't contain \n - this is undertaken in Submit (cgi/submmit.tcl) - see DROP NEWLINES
				set metadataRefer [string trim $metadataRefer \n]
# add metadata repository name field (%2)
				regsub {(%0[^%]*)} $metadataRefer "\\1%2 $repName\n" metadataRefer
				Store metadataRefer $col/$repName/doc/@metadata.refer
# Update the metadata - end

# Set service/reference
# repositoryName
				regexp "%4 (\[^\n\]*)" $metadataRefer m repositoryName
				set reference "../$col/col/$repositoryName
../$col/col/$whichRep +"
				Store reference $col/$repName/service/reference
				set reference {}	;# to avoid the creation of a metadata repository below
# Set service/reference - end

				set targetFile metadata.cgi
#				Set repositoryProperties($repName,targetfile) $targetFile
				Store targetFile $col/$repName/service/targetFile
				Eval UpdateCollection $repName
				if {$applicationName == "start"} {
					UpdateKeyRepositoryList $repName
#					StoreList keyRepositoryList ../auxdoc/.keyRepositoryList.tcl
				}
			} else {
# use as metadata the metadata of whichRep (if no metadata has been captured)
# CREATE (not a metadata repository)
#				set repName [CreateNewRepository $documentType $documentPath $targetFileOption copy 0 {} 0 {} 0 $userName]
				set repName [CreateNewRepository $documentType $documentPath $targetFileOption $option 0 {} 0 {} 0 $userName]	;# added by GJFB on 2012-06-26 -  - allows the use of the preserve option
				set metadataRep [Eval FindMetadataRep $whichRep]
				if ![file isdirectory $homePath/col/$metadataRep] {
					UpdateVariables $metadataRep
					set metadataRep ""
				}
				if {$metadataRep == ""} {
					set metadataRep $defaultMetadataRepository
				}
				Load $col/$metadataRep/doc/@metadata.refer reference
			}
		} else {
# set xxx [list $documentType $documentPath $targetFileOption $option $unzip $repName 0 $contentType]
# Store xxx C:/tmp/bbb auto 0 a
# CREATE (not a metadata repository)
# used when submitting a non empty document
			set repName [CreateNewRepository $documentType $documentPath $targetFileOption $option $unzip $repName 0 $contentType $copyToSource $userName $postSubmissionScriptRepList $reference]
# set xxx $repName
# Store xxx C:/tmp/aaa auto 0 a
			set reference [LoadReference 0 $reference]
		}
	} else {
# not directory (ex.: empty)
		if $copyAbstractToDoc {
# copy abstract
			set index [lsearch -regexp $reference {^%T }]
			regsub {^%T } [lindex $reference $index] {} title
			set index [lsearch -regexp $reference {^%X }]
			regsub {^%X } [lindex $reference $index] {} abstract
			set abstract [CopyAbstract $title $abstract]
			set documentPath $homePath/clipboard2
			file mkdir $documentPath
			Store abstract $documentPath/abstract.html
# CREATE (not a metadata repository)
			set repName [CreateNewRepository directory $documentPath/ enable preserve 0 {} 0 {} 0 $userName $postSubmissionScriptRepList $reference]
		} else {
# don't copy the abstract
# CREATE (not a metadata repository)
#			set repName [CreateNewRepository $documentType $documentPath $targetFileOption copy 0 {} 0 {} 0 $userName $postSubmissionScriptRepList $reference]
			set repName [CreateNewRepository $documentType $documentPath $targetFileOption copy 0 {} 0 $contentType 0 $userName $postSubmissionScriptRepList $reference]
		}
		set reference [LoadReference 0 $reference]
	}

	if [string equal {} $repName] {return}	;# MakeRepository fails 

# set xxx $reference
# Store xxx C:/tmp/bbb auto 0 a
# drop %4 and %2
#	regsub {%4[^%]*} $reference {} reference
#	regsub {%2[^%]*} $reference {} reference
	regsub "%4 \[^\n\]*\n" $reference\n {} reference	;# it is assumed that the field values don't contain \n - this is undertaken in Submit (cgi/submmit.tcl) - see DROP NEWLINES
	regsub "%2 \[^\n\]*\n" $reference\n {} reference	;# it is assumed that the field values don't contain \n - this is undertaken in Submit (cgi/submmit.tcl) - see DROP NEWLINES
	
# Update the targetfile field %3
# useful when the document content only one file
# and the target file option is enable
# puts OK3
# Load $homePath/col/$repName/service/targetFile xxx
# puts --$xxx--
	if [Info exists repositoryProperties($repName,targetfile)] {
if 0 {
		set targetFile [Get repositoryProperties($repName,targetfile)]
} else {
# added by GJFB on 2021-01-21 because Get lost extra white spaces disfiguring the target file name
		LoadService $repName targetFile targetFile 0 1
}
# puts --$targetFile--
#		regsub {%3[^%]*} $reference {} reference
		regsub "%3 \[^\n\]*\n" $reference\n {} reference	;# it is assumed that the field values don't contain \n - this is undertaken in Submit (cgi/submmit.tcl) - see DROP NEWLINES
		regsub -all {&} $targetFile {\\&} targetFile	;# xx&yy.doc -> xx\&yy.doc - needed for the next regsub
		regsub {(%0[^%]*)} $reference "\\1%3 $targetFile\n" reference
	}
	
#	set reference [string trim $reference \n]	;# with this command here, regsub below leads to an error when using option 20 of the administrator page - comented by GJFB on 2011-02-22
	set reference [string trim $reference \n]\n	;# leave only one new line - added by GJFB on 2011-02-22
	
# puts OK4
# Update the targetfile field %3 - end

# puts 1--$reference--
# add repository name field (%4)
	regsub {(%0[^%]*)} $reference "\\1%4 $repName\n" reference
# puts 2--$reference--

	set reference [string trim $reference \n]	;# added by GJFB on 2011-02-22

# puts 3--$reference--
# puts --$metadataEntryList--
# Add metadataEntryList
	foreach newEntry $metadataEntryList {
		set reference [UpdateRefer $reference $newEntry]
	}
# Add metadataEntryList - end
# puts 4--$reference--

# Add userName and nextUser (if any) to the usergroup field value
	if ![string equal {} $reference] { 
# not a "add a metadata repository"
		set userGroup [GetReferField $reference @usergroup]
# set xxx --$userGroup--
# Store xxx C:/tmp/bbb auto 0 a 
		lappend userGroup $userName
		if ![string equal $userName $nextUser] {
			lappend userGroup $nextUser	;# added by GJFB on 2016-06-06
		}
		set userGroup [lsort -unique $userGroup]
		set reference [UpdateRefer $reference [concat usergroup $userGroup]]
	}
# Add userName and nextUser (if any) to the usergroup field value - end

# Store submission agreement
	if ![string equal {} $submissionAgreementText] {
# there exists an agreement
		file mkdir $homePath/col/$repName/agreement
		set fileContent [join $submissionAgreementText \n]
#		Store fileContent $homePath/col/$repName/agreement/agreement.html	;# commented by GJFB on 2016-05-08
		Store fileContent $homePath/col/$repName/agreement/agreement.html auto 0 w 0 iso8859-1	;# added by GJFB on 2016-05-08 - solves the accent/channel problem in mtc-m16d.sid.inpe.br when opening the file agreement.html using Firefox - similar code is used in submit.tcl
		set htaccessContent {Require user administrator}
		Store htaccessContent $homePath/col/$repName/agreement/.htaccess
		Store htaccessContent $homePath/col/$repName/agreement/.htaccess2
# CREATE A NEW VERSION STAMP
 		set seconds [RepositoryMTime $repName $homePath]
		set versionStamp [CreateVersionStamp $seconds $userName]
		UpdateHistory $repName $versionStamp
	}
# Store submission agreement - end

# Create a metadata repository
# puts --$reference--
# CREATE (metadata repository)
#	set metadataList [LoadMetadata $reference $metadataRepName]	;# startApacheServer
	set metadataList [LoadMetadata $reference $metadataRepName $userName 1 $targetFileOption]	;# startApacheServer
# Create a metadata repository - end

# metadataRepName
	regsub -- {-0,.*} [lindex $metadataList 0] {} metadataRepName

TraceProcedure $metadataRepName

# ADD METADATA
# the two lines below were added by GJFB on 2013-01-28 in order to SetAccessPermission below be able to get the year and the group values
#	Eval AddMetadata $metadataList	;# metadataList must not be too big, otherwise Eval doesn't return - commented by GJFB on 2020-08-18
	Eval AddMetadata2 $metadataList	;# added by GJFB on 2020-08-18
	set metadataList {}
	
# identifier
	LoadService $repName identifier identifier 1 1
	file delete $homePath/col/$metadataRepName/service/identifier	;# identifier is not used for metadata repository - added by GJFB on 2010-08-02
# visibility
	StoreService visibility $repName visibility 1 1
#	UpdateRobotstxtFile $repName $visibility	;# commented by GJFB on 2011-06-13 - now below
# copyright
	if ![string equal {} $copyright] {
		StoreService copyright $repName copyright 0 1
		set metadataList [concat $metadataList [list $metadataRepName-0,copyright $copyright]]	;# added by GJFB on 2012-08-14
	}
# transferableFlag
	LoadService $repName transferableFlag transferableFlag 1 1

# Update repositoryProperties, metadataArray and repArray
	set metadata2List {}
	set metadataList [concat $metadataList [list $metadataRepName-0,identifier $identifier]]
	set metadataList [concat $metadataList [list $metadataRepName-0,visibility [expr $visibility?{hidden}:{shown}]]]
	UpdateMetadataField $metadataRepName transferableflag $transferableFlag metadataList metadata2List	;# added by GJFB on 2010-10-09
	
# Add metadatalastupdate in metadataList
# useful to force the update of mostRecentReferences and mostRecentFullTexts
# because there is two calls to AddMetadata in LoadMetadata (the second one already adds metadatalastupdate)
# and LoadMetadata doesn't return metadatalastupdate
#	set history [Get repositoryProperties($metadataRepName,history)]
#	set versionStamp [lindex $history end]
	set versionStamp [Eval GetVersionStamp $metadataRepName]
	set metadataList [concat $metadataList [list $metadataRepName-0,metadatalastupdate $versionStamp]]
# Add metadatalastupdate in metadataList - end

	if [regexp "%@parentrepositories (\[^\n\]*)" $reference m parentRepNameList] {
		foreach parentRepName $parentRepNameList {
			set reference2 "../$col/col/$parentRepName"
			Store reference2 $homePath/col/$repName/service/reference auto 0 a
			set parentMetadataRepName [Eval FindMetadataRep $parentRepName]
			UpdateCrossReferences $repName $metadataRepName metadataList metadata2List
			UpdateCrossReferences $parentRepName $parentMetadataRepName metadataList metadata2List
		}
		Eval UpdateReferenceTable $repName
	}
	
if 0 {
	if {[string compare {} $childRepositories] != 0} {
		set reference2 "../$col/col/$repName"
		foreach childRepName $childRepositories {
			Store reference2 $homePath/col/$childRepName/service/reference auto 0 a
			Eval UpdateReferenceTable $childRepName
			set childMetadataRepName [Eval FindMetadataRep $childRepName]
			UpdateCrossReferences $childRepName $childMetadataRepName metadataList metadata2List
			UpdateCrossReferences $repName $metadataRepName metadataList metadata2List
		}
	}
}

# Store read permission
	set xxDefaultPermission [expr [string compare {} $readPermission]?0:1]
# puts [list --$readPermission-- $xxDefaultPermission]
	SetAccessPermission $repName $readPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission	;# if readPermission value is "intranet" and the field year is empty then SetAccessPermission sets the read permission to "deny from all" 
	StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
	$repName $metadataRepName Permission permission 0 Permission metadataList metadata2List
# set the SAME permissions for the remote permission
	StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
	$repName $metadataRepName RemotePermission remotepermission 1 {Remote Permission} metadataList metadata2List
# Store read permission - end

	set booleanDocPermission [regexp {deny} $xxDocAccessPermission]
	UpdateRobotstxtFile $repName $visibility $booleanDocPermission	;# put here by GJFB on 2011-06-13

# Store language
	if [string equal {} $languageFieldValue] {
		file delete $homePath/col/$repName/service/language
	} else {
		StoreService languageFieldValue $repName language 0 1
	}
	Eval UpdateRepositoryProperties $repName language
	UpdateMetadataField $metadataRepName language $languageFieldValue metadataList metadata2List 1
# Store language - end

# nextUser -> userName
	if ![string equal {} $nextUser] {
		StoreService nextUser $repName userName 1 1
		Eval UpdateRepositoryProperties $repName username
#		MakeCgiScript $URLibServiceRepository $repName update update.tcl Update cgi2
		MakeCgiScript $URLibServiceRepository $repName update mirror.tcl {CreateMirror 1} cgi2
		UpdateMetadataField $metadataRepName username $nextUser metadataList metadata2List
		
# Update the read user list
# used with review form
		if ![string equal {} $readUserList] {
# this part runs with post only
# update authenticatedUsers
			set authenticatedUsers $readUserList
 			Store authenticatedUsers $homePath/col/$repName/service/authenticatedUsers
			UpdateMetadataField $metadataRepName readergroup $authenticatedUsers metadataList metadata2List
			UpdateRepositoryProperties $repName authenticatedusers	;# better solution because may delete empty authenticatedUsers file
#			set startApacheServer 1
		}
# Update the read user list - end

# Update the read user list for the work repository of the review system
# used with review form
		if ![string equal {} $readUserListForParentRepositories] {
# Update authenticatedUsers
# this part runs with post only
			set authenticatedUsers $readUserListForParentRepositories
			set workRepository [CreateCitedRepositoryList $repName]
 			Store authenticatedUsers $homePath/col/$workRepository/service/authenticatedUsers
#			set workMetadataRep [Eval FindMetadataRep $workRepository]
			set workMetadataRep [FindMetadataRep $workRepository]
# Make review cgi script
#			MakeCgiScript $URLibServiceRepository $workRepository review review.tcl Review cgi2
			MakeCgiScript $URLibServiceRepository $workRepository review review.tcl Review cgi3
# Make review cgi script - end
			UpdateMetadataField $workMetadataRep readergroup $authenticatedUsers metadataList metadata2List
#			Eval UpdateRepositoryProperties $workRepository authenticatedusers	;# better solution because may delete empty authenticatedUsers file
			UpdateRepositoryProperties $workRepository authenticatedusers	;# better solution because may delete empty authenticatedUsers file
##			Set startApacheServer 1
#			set startApacheServer 1
			UpdateAccessFile $workRepository
		}
# Update the read user list for the work repository of the review system - end

	}
	UpdateAccessFile $repName

	if ![string equal {} $contentType] {
		UpdateMetadataField $metadataRepName contenttype $contentType metadataList metadata2List
	}

TraceProcedure saving...

# SAVE
#	Eval StoreArray repositoryProperties ../auxdoc/.repositoryProperties.tcl
#	Eval StoreArray referenceTable ../auxdoc/.referenceTable.tcl
	Eval SaveRepositoryProperties
	Eval SaveReferenceTable
# SAVE - end

# Add file service/metadataRepositoryList
# added by GJFB on 2015-12-15 in order to have the names of the metadata repositories in the proper original repository - useful when one need to rescue a metadata repository from backup
	if [string equal {} $reference] {
# add a metadata repository
		set repName2 $repositoryName
	} else {
		set repName2 $repName
	}
# puts --$repName2--
	set metadataRepList [FindMetadataRepList $repName2]
# puts --$metadataRepList--
	set fileContent [join $metadataRepList \n]
	StoreService fileContent $repName2 metadataRepositoryList 0 1
# Add file service/metadataRepositoryList - end

	set metadataRepList {}

# Update @metadata.refer of the previous edition
	set previousEditionRep [GetReferField $reference {\(}]
	if ![string equal {} $previousEditionRep] {
# there exists a previous edition
		set previousEditionMetadataRep [Execute $previousEditionSite [list FindMetadataRep $previousEditionRep]]
		if {$previousEditionMetadataRep != {}} {
#			SetFieldValue $previousEditionSite $previousEditionMetadataRep-0 {documentstage lastupdatedate language}
			SetFieldValue $previousEditionSite $previousEditionMetadataRep-0 {referencetype lastupdatedate language}
			if [regexp {Electronic Source} $referencetype] {
# ePrint
				set nextUser $ePrintAdministrator
			} else {
				set nextUser $userName
			}
# nextedition
			set newEntryList [list [list nextedition $repName]]
			if [regexp {Electronic Source} $referencetype] {
# ePrint
				regsub -- {-.*} $lastupdatedate {} year
# year
				lappend newEntryList [list year $year]
				lappend newEntryList [list lastupdatedate {}]
# Migration 2009-09-04
# documentstage is not used anymore for ePrint
# lappend below could be dropped in the future
				lappend newEntryList [list documentstage {}]
# Migration 2009-09-04 - end
#				lappend newEntryList [list notes {}]
# stageofalternatepublication
				lappend newEntryList [list stageofalternatepublication published]
			}
# administratorCodedPassword
			Load $homePath/col/$loCoInRep/auxdoc/xxx data binary
			set data [UnShift $data]
			set administratorCodedPassword [lindex $data end]
			Execute $previousEditionSite [list UpdateReferMetadata $previousEditionMetadataRep $newEntryList administrator $administratorCodedPassword]
			set startApacheServer [Execute $previousEditionSite [list UpdateRepMetadataRep \
			$previousEditionRep $previousEditionMetadataRep $userName $password \
			preserve 0 1 {} 1 {} $nextUser {} \
			disable {} \
			{} {} 0 \
			$language 1 0 \
			{} 0 $visibility]]
		}
	}
# Update @metadata.refer of the previous edition - end

TraceProcedure {add metadata...}

# ADD METADATA
#	Eval AddMetadata $metadataList	;# metadataList must not be too big, otherwise Eval doesn't return - commented by GJFB on 2020-08-18
	Eval AddMetadata2 $metadataList	;# added by GJFB on 2020-08-18
# SAVE
	Set saveMetadata $saveMetadata2
	Eval SaveMetadata
	lappend metadataRepList $metadataRepName
	Eval UpdateRepositoryListForPost [concat $repName $metadataRepList]
# Append repName and metadataRepName to the repositoryListForStart file content
# (used to update keyRepositoryList in SetIndicator)
	if {$applicationName == "post"} {
		Store repName $homePath/col/$URLibServiceRepository/auxdoc/repositoryListForStart auto 0 a 
		Store metadataRepName $homePath/col/$URLibServiceRepository/auxdoc/repositoryListForStart auto 0 a
	}
# Append repName and metadataRepName to the repositoryListForStart file content - end
# Update repositoryProperties, metadataArray and repArray - end

# Start apache server
	if $start {Eval StartApacheServer}
# Start apache server - end

# Register repository name
	if [Info exists repositoryProperties($repName,numberoffiles)] {
# not an empty repository
#		Eval RegisterRepository $repName	;# RegisterRepositoryName need to be updated to include registration of copies (now a copy has an empty host collection value)
	}
# Register repository name - end

	return $repName
}

# CreateRepMetadataRep - end
# ----------------------------------------------------------------------
# CopyAbstract

proc CopyAbstract {title abstract} {
	set abstract "<HTML><HEAD><TITLE>Abstract</TITLE></HEAD><BODY>
<P ALIGN=CENTER><I>$title</I></P>
<P>Abstract</P>
<P>$abstract</P>
<TABLE ALIGN=CENTER><TR><TD WIDTH=100><BR><HR></TD></TR></TABLE>
</BODY></HTML>"
	return $abstract
}

# CopyAbstract - end
# ----------------------------------------------------------------------
# UpdateRepMetadataRep

# password must be coded
# option value is "copy" or "preserve" or "delete" (see DDRoutine)
# noFile value is 0 or 1; 1 means that no file was defined
# used by Submit, Script (administrator page) and ReviewerAssignment only
# contentType values are Metadata, External Contribution, ...
# readPermission values examples are {} (means to use the default permission)
# or {deny from all and allow from 150.163}
# or {150.163}
# nextUser value is {} or a user name (advanced user) for the next update
# readUserList value is {} or a list of read user names
# targetFileOption values are disable or enable
# enable means to adjust the target file if needed
# readUserListForParentRepositories is used for a workRepository of the review system
# reference used just for post-submission processing
# $reference ==>
# {%0 Misc} {%@tertiarytype } {%A Aa, Gg,} {%A Banon, Francis,} {%I Deposited in the URLib collection.} {%X aa} {%T tt} {%@secondarykey INPE--/}
# see for example script.tcl in iconet.com.br/banon/2005/12.29.23.16
# postSubmissionScriptRepList is a list of repositories containing scripts to process
# the submitted files
# Examples of repositories containing post submission scripts:
# iconet.com.br/banon/2005/12.29.23.16 (A script to process the INPE Clippings)
# iconet.com.br/banon/2005/09.07.19.12 (A script to process the INPE CRI-Clippings)

# copyAbstractToDoc value is 0 or 1; 1 means to deposit the abstract as an html file in doc
# deleteDocContentBeforeUpdate value is 0 or 1; 1 means to delete the doc content before depositing the new document - 1 is default
## copyToSource value is 0 or 1; 1 means to update the document into the source as well
# copyToSource value is 0 or 1; 1 means to update the document into the source (only)
# moveToSource value is 0 or 1 ; 0 means don't move, 1 move the doc content to source - added by GJFB on 2016-05-10 to preserve old doc content before updating it - set in Administrator page for customizing the conference submission forms (iconet.com.br/banon/2006/07.02.02.18)
# moveBackToDoc value is 0 or 1 ; 0 means don't move, 1 move the source content to doc - added by GJFB on 2021-05-27 to give access to previously hidden video (ex: id 8JMKD3MGPGW34M/44N7JSP)
# updateAgreement value is 0 or 1; 1 means to update the agreement folder
# visibility value is 0 or 1; 0 means shown, 1 means hidden repository at search

proc UpdateRepMetadataRep {
	rep metadataRep userName password option unzip
	noFile contentType saveMetadata2 readPermission nextUser {readUserList {}}
	{targetFileOption enable} {readUserListForParentRepositories {}}
	{reference {}} {postSubmissionScriptRepList {}} {copyAbstractToDoc 0}
	{languageFieldValue {}} {deleteDocContentBeforeUpdate 1} {copyToSource 0}
	{folderName {}} {updateAgreement 0} {visibility 0} {moveToSource 0}
	{moveBackToDoc 0}
} {
# runs with post
	global homePath
	global saveMetadata
	global repositoryProperties
#	global startApacheServer	;# apache must be restarted after a read permission change or a new read user
#	global pwd
	global URLibServiceRepository
	global environmentArray
	global serverAddressWithIP

# set enableTrace 0
Load $homePath/col/$URLibServiceRepository/auxdoc/@enableTrace enableTrace
TraceProcedure UpdateRepMetadataRep
TraceProcedure	;# add executing time interval
TraceProcedure [clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]
TraceProcedure [CallTrace]

TraceProcedure	;# add executing time interval
TraceProcedure [list targetFile exists? = [file exists $homePath/col/$rep/service/targetFile]]

	set message [CheckAccess $rep $userName $password]
	if ![string equal {} $message] {
		return $message
	}

	Load $homePath/col/$metadataRep/doc/@metadata.refer referMetadata
# puts $referMetadata
# Store referMetadata C:/tmp/bbb.txt auto 0 a 
	if [string equal {} $referMetadata] {
		return "UpdateRepMetadataRep: $homePath/col/$metadataRep/doc/@metadata.refer not found"
	}
# puts 1-$referMetadata
	
	if $copyAbstractToDoc {
# copy abstract
		set title [GetReferField $referMetadata T]
		set abstract [GetReferField $referMetadata X]
		set abstract [CopyAbstract $title $abstract]
		set documentPath $homePath/clipboard2
		file mkdir $documentPath
		Store abstract $documentPath/abstract.html
		set noFile 0
	}
# puts OK
	set fileName [file tail [join [glob -nocomplain $homePath/clipboard2/*]]]
# puts $fileName
#	if {!$noFile && [DirectorySize $homePath/clipboard2] != 0} #	;# commented by GJFB on 2021-01-31
# puts [expr !$noFile && ([DirectorySize $homePath/clipboard2] != 0 || [string equal {@siteList.txt} $fileName])]
#	if {!$noFile && ([DirectorySize $homePath/clipboard2] != 0 || [string equal {@siteList.txt} $fileName])} #	;# added by GJFB on 2021-01-31 - an empty @siteList.txt is meaningful
#	if {!$noFile && ([DirectorySize $homePath/clipboard2] != 0 || [string equal {@siteList.txt} $fileName]) || $moveToSource} #	;# added by GJFB on 2021-05-25
	if {!$noFile && ([DirectorySize $homePath/clipboard2] != 0 || [string equal {@siteList.txt} $fileName]) || $moveToSource || $moveBackToDoc} {	;# added by GJFB on 2021-05-27
# depositing a new document
# DEPOSIT
		UpdateRepository $rep directory $homePath/clipboard2/ \
		$targetFileOption $option $unzip $userName \
		$postSubmissionScriptRepList $reference $deleteDocContentBeforeUpdate \
		$copyToSource $folderName $updateAgreement $moveToSource $moveBackToDoc
# RunPostSubmissionScript is called within UpdateRepository

		Load $homePath/col/$rep/service/targetFile targetFile
# puts --$targetFile--

# set xxx OK
# Store xxx C:/tmp/bbb auto 0 a
	} else {
# puts OK
		set targetFile [RunPostSubmissionScript $rep $postSubmissionScriptRepList $reference]
# puts --$targetFile--
		if [string equal {} $targetFile] {
			Load $homePath/col/$rep/service/targetFile targetFile
# Ajust the target file
#			if [string equal {enable} $targetFileOption] #
				set targetFile2 [AjustTargetFile $rep $targetFile $targetFileOption]
# puts [list $targetFile2 $targetFile]
				if ![string equal $targetFile2 $targetFile] {
# correct targetFile
					set targetFile $targetFile2
					Store targetFile $homePath/col/$rep/service/targetFile
				}
#			#
# Ajust the target file - end
		}
	}
# puts --$targetFile--

TraceProcedure	;# add executing time interval
TraceProcedure [list targetFile = $targetFile]

# Update @metadata.refer
# $targetFile -> @metadata.refer
# puts 2-$referMetadata
	set referMetadata [UpdateRefer $referMetadata [concat targetfile $targetFile]]
# puts $targetFile
# puts 3-$referMetadata

# Add nextUser (if any) to the usergroup field value
	if ![string equal $userName $nextUser] {
# add $nextUser (if it doesn't exist) to @metadata.refer (usergroup)
		set userGroup [GetReferField $referMetadata @usergroup]
# puts --$userGroup--
#		set indexUserGroup [lsearch -exact $userGroup $nextUser]	;# commented by GJFB on 2016-06-06
#		set userGroup [lreplace $userGroup $indexUserGroup $indexUserGroup]	;# commented by GJFB on 2016-06-06
		lappend userGroup $nextUser
		set userGroup [lsort -unique $userGroup]	;# insertion order is lost
		set referMetadata [UpdateRefer $referMetadata [concat usergroup $userGroup]]
	}
# Add nextUser (if any) to the usergroup field value - end

if 0 {
# this code could be use in case of infinite loop
	set nextHigherUnit [GetReferField $referMetadata @nexthigherunit]
	if ![string equal {} $nextHigherUnit] {
# identifier
		LoadService $rep identifier identifier 1 1
		set index [lsearch -exact $nextHigherUnit $identifier]
		set nextHigherUnit [lreplace $nextHigherUnit $index $index]
		set referMetadata [UpdateRefer $referMetadata [concat nexthigherunit $nextHigherUnit]]
	}
}

if 1 {
# migration 14/9/21
# ensure the nexthigherunit field value is a list of ibip or ibin (not rep)
# useful to transfer previousedition value to nexthigherunit value for Audiovisual Material records using the administrator page
	set nextHigherUnit [GetReferField $referMetadata @nexthigherunit]
	set ibiList {}
	foreach ibi $nextHigherUnit {
		if {[regexp -all {/} $ibi] == 3} {
# rep
			LoadService $ibi identifier identifier 1 1
			if ![string equal {} $identifier] {
				set ibi $identifier
			}
		}
		lappend ibiList $ibi
	}
	set referMetadata [UpdateRefer $referMetadata [concat nexthigherunit $ibiList]]
# migration 14/9/21 - end
}

# puts 4-$referMetadata
	Store referMetadata $homePath/col/$metadataRep/doc/@metadata.refer
# Store referMetadata C:/tmp/bbb.txt auto 0 a 
# Update @metadata.refer - end

# Update contentDescription.tcl
	set referenceType [GetReferField $referMetadata 0]
	if [string equal {Image} $referenceType] {
		UpdateContentDescriptionFile $rep $targetFile
	}
# Update contentDescription.tcl - end
	
# CREATE A NEW VERSION STAMP
 	set seconds [RepositoryMTime $rep $homePath]
	set versionStamp [CreateVersionStamp $seconds $userName]
# puts $versionStamp
	UpdateHistory $rep $versionStamp

TraceProcedure	;# add executing time interval
TraceProcedure [list seconds = $seconds]

#	LoadMetadata $referMetadata	;# set (again): lastupdate, metadatalastupdate, size and numberoffiles 
#	LoadMetadata $referMetadata {} $userName 0	;# set (again): lastupdate, metadatalastupdate, size and numberoffiles 
	LoadMetadata $referMetadata {} $userName 0 disable 0	;# added by GJFB on 2018-04-17 - lastupdate, metadatalastupdate, size and numberoffiles are updated in UpdateLastUpdate below
															;# disable is to keep the empty target file unchanged for 1 file document - obsolete after 2019-12-21 

TraceProcedure	;# add executing time interval
TraceProcedure {LoadMetadata done}

# at this point metadataArray and repArray are not yet updated

# Update metadataArray and repArray
	set metadataList {}
	set metadata2List {}
if 0 {
# commented by GJFB on 2012-09-23 because agreement should be updated whenever the agreement past is removed	
# Set agreement field
	set dir $homePath/col/$rep/agreement
	if [file isdirectory $dir] {
		set fileList {}
		DirectoryContent fileList $dir $dir
		UpdateMetadataField $metadataRep agreement $fileList metadataList metadata2List
	} else {
# nothing to do - previous agreement value doesn't go through the client browser
	}
# Set agreement field - end
}
# Set agreement field
	set dir $homePath/col/$rep/agreement
	set fileList {}
	if [file isdirectory $dir] {DirectoryContent fileList $dir $dir}
	UpdateMetadataField $metadataRep agreement $fileList metadataList metadata2List
# Set agreement field - end

	set repList [list $rep $metadataRep]
	
# nextUser -> userName
# puts $nextUser
#	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName
	if ![string equal $userName $nextUser] {
		StoreService nextUser $rep userName 1 1
		UpdateMetadataField $metadataRep username $nextUser metadataList metadata2List
	}
	
# Update the read user list
# puts --$readUserList--
	Load $homePath/col/$rep/service/authenticatedUsers fileContent	;# added by GJFB on 2018-11-02
	set readUserListFlag [string equal $fileContent $readUserList]	;# added by GJFB on 2018-11-02
	if !$readUserListFlag {	;# added by GJFB on 2018-11-02
		if [string equal {} $readUserList] {
			file delete $homePath/col/$rep/service/authenticatedUsers	;# added by GJFB on 2018-11-02
		} else {
# update authenticatedUsers
			set authenticatedUsers $readUserList
 			Store authenticatedUsers $homePath/col/$rep/service/authenticatedUsers
#			UpdateMetadataField $metadataRep readergroup $authenticatedUsers metadataList metadata2List	;# done in CreateExtraFields called in UpdateCollection
#			UpdateRepositoryProperties $rep authenticatedusers
#			SaveRepositoryProperties
		}
	}
# Update the read user list - end

# Update the read user list for the work repository of the review system
# used with review form
# needed when the reviewer has declined the review
	if ![string equal {} $readUserListForParentRepositories] {
# update authenticatedUsers
		set authenticatedUsers $readUserListForParentRepositories
		set workRepository [CreateCitedRepositoryList $rep]
 		Store authenticatedUsers $homePath/col/$workRepository/service/authenticatedUsers
		set workMetadataRep [FindMetadataRep $workRepository]
		UpdateMetadataField $workMetadataRep readergroup $authenticatedUsers metadataList metadata2List
		UpdateRepositoryProperties $workRepository authenticatedusers	;# better solution because may delete empty authenticatedUsers file
		SaveRepositoryProperties
#		set startApacheServer 1	;# not necessary because of the file access use
		lappend repList $workRepository
	}
# Update the read user list for the work repository of the review system - end

# Load $homePath/col/$metadataRep/doc/@metadata.refer xxx
# Store xxx C:/tmp/bbb.txt auto 0 a 

TraceProcedure	;# add executing time interval
TraceProcedure {UpdateCollection...}

	UpdateCollection $repList	;# updates metadataArray and repArray from @metadata.refer (uses ConvertMultipleRefer2MetadataList)

TraceProcedure	;# add executing time interval
TraceProcedure {UpdateCollection done}

# Load $homePath/col/$metadataRep/doc/@metadata.refer xxx
# Store xxx C:/tmp/bbb.txt auto 0 a 
# set xxx [GetFieldValue $metadataRep-0 title]
# Store xxx C:/tmp/bbb.txt binary 0 a 

	LoadService $rep docPermission oldDocPermission 0 1
	LoadService $rep visibility oldBooleanVisibility 1 1

# Store read permission
# puts --$readPermission--
#	set xxDefaultPermission [expr [string compare {} $readPermission]?0:1]
	set xxDefaultPermission [string equal {} $readPermission]
	SetAccessPermission $rep $readPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission
#	set startApacheServer [expr $startApacheServer || [StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
#		$rep $metadataRep Permission permission 0 Permission metadataList metadata2List]]
# puts [list $xxDefaultPermission $xxDocAccessPermission $xxDownloadAccessPermission]
	StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
	$rep $metadataRep Permission permission 0 Permission metadataList metadata2List
if 0 {
# commented by GJFB on 2105-0419 - the remote permission must be preserved, otherwise it should be set again manually with Dialog
## set the SAME permissions for the remote permissions
	StoreReadPermission xxDefaultPermission xxDocAccessPermission xxDownloadAccessPermission \
	$rep $metadataRep RemotePermission remotepermission 1 {Remote Permission} metadataList metadata2List
}
# Store read permission - end

# Store visibility
# before was in Submit
	if ![string equal $visibility $oldBooleanVisibility] {
		StoreService visibility $rep visibility 1 1
		set visibilityString [expr $visibility?{hidden}:{shown}]
		UpdateMetadataField $metadataRep visibility $visibilityString metadataList metadata2List
	}
# Store visibility - end

	if {![string equal $visibility $oldBooleanVisibility] || \
	![string equal $xxDocAccessPermission $oldDocPermission]} {
		set booleanDocPermission [regexp {deny} $xxDocAccessPermission]
		UpdateRobotstxtFile $rep $visibility $booleanDocPermission	;# added by GJFB on 2011-06-13
	}
	
# Create and store identifier
if 0 {
# commmented by GJFB on 2023-03-07
# for old repositories (up to 2011)
	if ![file exists $homePath/col/$rep/service/identifier] {
		if [catch {ConvertFromRepository [string tolower $rep]} id] {
# identifier syntax error
# rep == cptec.inpe.br/adm_conf/2005/10.31.12.09 (ICSHMO)
# rep == bighost.com.br/gabi_sf/2005/12.11.22.35 (gprb0705)
# can't read "inverseDigitArray(_)": no such element in array
		} else {
			StoreService id $rep identifier 1 1
			UpdateMetadataField $metadataRep identifier $id metadataList metadata2List
		}
	}
} else {
# added by GJFB on 2023-03-07 to solve repository name having an underline caracter (_)
# for old repositories (up to 2011)
	if ![file exists $homePath/col/$rep/service/identifier] {
		regsub {_} $rep {-} rep2	;# to be able to convert the two old repository names below which don't satisfy the norm of 2011 
# rep == cptec.inpe.br/adm_conf/2005/10.31.12.09 (ICSHMO)
# rep == bighost.com.br/gabi_sf/2005/12.11.22.35 (gprb0705)
		set id [ConvertFromRepository [string tolower $rep2]]
		StoreService id $rep identifier 1 1
		UpdateMetadataField $metadataRep identifier $id metadataList metadata2List
	}
}
# Create and store identifier - end

# Store language
	if [string equal {} $languageFieldValue] {
		file delete $homePath/col/$rep/service/language
	} else {
		StoreService languageFieldValue $rep language 0 1
	}
	UpdateRepositoryProperties $rep language
	UpdateMetadataField $metadataRep language $languageFieldValue metadataList metadata2List 1
# Store language - end

#	UpdateMetadataField $metadataRep username $userName metadataList metadata2List

#	Load $homePath/col/$rep/service/type contentType
	UpdateMetadataField $metadataRep contenttype $contentType metadataList metadata2List
	if [string equal {} $contentType] {
		file delete $homePath/col/$rep/service/type
	} else {
		Store contentType $homePath/col/$rep/service/type
	}
	UpdateRepositoryProperties $rep contenttype

# puts "metadata2List = --$metadata2List--"
# puts "metadataList = --$metadataList--"

	UpdateAccessFile $rep
	UpdateLastUpdate $rep $metadataRep none $userName 0	;# added by GJFB on 2018-04-17 to update size and numberoffiles (UpdateAccessFile, by creating or deleting .htaccess files, may change the size and the number of files)

	SimplifyMetadataLists metadataList metadata2List
# REMOVE and ADD METADATA
if 0 {
# commented by GJFB on 2020-08-18
	RemoveMetadata $metadata2List
	AddMetadata $metadataList
} else {
	UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
# Store metadataList C:/tmp/bbb.txt binary 0 a 

# SAVE
	set saveMetadata $saveMetadata2
	SaveMetadata
#	UpdateRepositoryListForPost [concat $rep $metadataRep]	;# already called in UpdateCollection above
# Update metadataArray and repArray - end

# at this point metadataArray and repArray have been updated

	file delete $homePath/col/$rep/download/doc.zip

TraceProcedure	;# add executing time interval
TraceProcedure {metadataArray and repArray have been updated}

# Append rep and metadataRep to the repositoryListForStart file content
# (used to update keyRepositoryList in SetIndicator)
	Store rep $homePath/col/$URLibServiceRepository/auxdoc/repositoryListForStart auto 0 a 
	Store metadataRep $homePath/col/$URLibServiceRepository/auxdoc/repositoryListForStart auto 0 a
# Append rep and metadataRep to the repositoryListForStart file content - end

# Register repository name
	if [info exists repositoryProperties($rep,numberoffiles)] {
# not an empty repository
#		RegisterRepository $rep	;# RegisterRepositoryName need to be updated to include registration of copies (now a copy has an empty host collection value)
	}
# Register repository name - end

TraceProcedure	;# add executing time interval
TraceProcedure {end of UpdateRepMetadataRep}

# Create environmentArray(permissionList) and environmentArray(languagePreference)
	if [TestContentType $rep {Mirror}] {
		CreatePermissionList $rep
		CreateEnvironmentArray	;# to update LANGUAGE_PREFERENCE
	}
# Create environmentArray(permissionList) and environmentArray(languagePreference) - end

if 0 {
# commented by GJFB on 2018-11-02
# restarting Apache in UpdateRepMetadataRep results in an unexpected new call to Submit (gprb0705 experienced this problem)
# Restart Apache server
# added by GJFB on 2018-07-22
# similar code in Script (see col/dpi.inpe.br/banon-pc@1905/2005/02.19.00.40/doc/script.cgi)
#	SourceWithBackup $homePath/col/$URLibServiceRepository/auxdoc/.environmentArray.tcl environmentArray 1	;# added by GJFB on 2018-07-22
	ConditionalSet defaultAuthenticationFlag environmentArray(spUseUserAuthentication) 0
	if $defaultAuthenticationFlag {
# reader group might have changed and the Apache virtual host configuration file should updated restarting Apache
		Load $homePath/col/$URLibServiceRepository/auxdoc/pid pid
		Execute $serverAddressWithIP "set $pid startApacheServer 1"	;# Set startApacheServer 1
		Execute $serverAddressWithIP [list StartApacheServerAfterSubmission]
	}
# Restart Apache server - end
}

# set xxx [GetFieldValue $metadataRep-0 title]
# Store xxx C:/tmp/bbb.txt binary 0 a
# global serverAddressWithIP
# SetFieldValue $serverAddressWithIP $metadataRep-0 title
# Store title C:/tmp/bbb.txt binary 0 a
 
#	return $startApacheServer
	return 0	;# 0 means no error (socket may return an error)
}

# UpdateRepMetadataRep - end
# ----------------------------------------------------------------------
# LoadReference
# flag values are 0 or 1
# 1 means to just consider the isis reference (if it exists)
# doesn't consider the default reference if the isis reference doesn't exist
# 0 means consider the default reference if the isis reference doesn't exist

proc LoadReference {{flag 0} {reference {}}} {
# runs with start and post
	global homePath
	global isis2referRepository
	global defaultMetadataRepository
	global applicationName
	global environmentArray
	if ![string equal {} $reference] {return [join $reference \n]}	;# the reference already exists
	set list [glob -nocomplain $homePath/clipboard/?.*]	;# a.txt
	if {[llength $list] > 0} {
# use as metadata the isis reference in the clipboard
		set fileName [lindex $list 0]	;# use the first in list
#		Load $fileName fileContent
		Load $fileName fileContent binary
		set reference [${isis2referRepository}::Isis2Refer $fileContent]
# Remove the metadata having the same label (MFN)
		regexp {%F ([0-9]+)} $reference m MFN
		if [info exists MFN] {
			if {$applicationName == "start"} {
if 0 {
## Look for a mirror without hide restriction
## There should exist at least one
#				foreach mirrorRep $environmentArray(mirrorRepList) {
#					Load $homePath/col/$mirrorRep/doc/@hidedMetadataRepositoryList.txt fileContent
## no or empty @hidedMetadataRepositoryList.txt file means show all
#					set fileContent [string trim $fileContent " \n"]
#					if {[string compare {All Metadata Repositories} $fileContent] != 0} {break}
#				}
## Look for a mirror without hide restriction - end
} else {
	set mirrorRep {}
}
				set searchResult [Eval GetMetadataRepositories $mirrorRep 0 "label, $MFN" no no 1]
				set metadata2List [Eval GetMetadata $searchResult*]
#				Eval RemoveMetadata $metadata2List	;# metadata2List must not be too big, otherwise Eval doesn't return - commented by GJFB on 2020-08-18
				Eval RemoveMetadata2 $metadata2List	;# added by GJFB on 2020-08-18
			}
		}
# Remove the metadata having the same label (MFN) - end
		eval file delete $list
	} elseif $flag {
		set reference {}
	} else {
# use as metadata the default metadata
		set metadataRep $defaultMetadataRepository
		Load $homePath/col/$metadataRep/doc/@metadata.refer reference
	}
	return $reference
}

# LoadReference  end
# ----------------------------------------------------------------------
# LoadMetadata
# references is a list of refer metadata
# Examples:
# LoadMetadata $clipboard   (in GetClipboard)
# LoadMetadata $reference   (in CreateRepMetadataRep)
# used in GetClipboard, CreateRepMetadataRep and UpdateRepMetadataRep
# userName is the name of the advanced user who is creating the version stamp
# in each reference, referenceType must be in the first line
# targetFileOption value is enable or disable
# updateLastupdateFlag value is 0 or 1,
# 1 (default value) means to update lastupdate, metadatalastupdate, size and numberoffiles
# 0 means to do no update, used only by UpdateRepMetadataRep

proc LoadMetadata {
	references {metadataRepName {}} {userName {}} {computeReturnValue 1}
	{targetFileOption {disable}} {updateLastupdateFlag 1}
} {
# runs with start and post
	global environmentArray
	global URLibServiceRepository
	global defaultMetadataRepository
	global col
	global homePath
	global loCoInRep
	global serverAddress

# Store references C:/tmp/bbb.txt auto 0 a
# puts $references
# =>
# %0 Newspaper Article
# %D 2002
# %9 URLibService test
# %A Ribeiro, João,
# %A Batista, Laura,
# %T Teste2
# %8 2002-03-12
# %@nexthigherunit J8LNKB5R7W/3GFJKM8 J8LNKB5R7W/3LBEQ3H
# %@usergroup banon
# %3 clipping1.html
# %@copyholder SID/SCD
# %2 iconet.com.br/banon/2005/12.30.19.29.37
# %@affiliation Instituto Nacional de Pesquisas Espaciais (INPE)
# %4 iconet.com.br/banon/2005/12.30.19.29
# %@documentstage not transferred
# %B O Globo

 
# set enableTrace 0
Load $homePath/col/$URLibServiceRepository/auxdoc/@enableTrace enableTrace
TraceProcedure LoadMetadata
TraceProcedure	;# add executing time interval
TraceProcedure [clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]
TraceProcedure [CallTrace]

# site
#	set site [GetServerAddress]
	set site $serverAddress

	regsub -all "\n+" $references "\n" references
	regsub -all {@} $references {#!#} references	;# @ > #!#
	regsub -all {%0} $references {@%0} references

# FOREACH
	foreach entry [lrange [split $references @] 1 end] {
		regsub -all {#!#} $entry {@} entry	;# #!# > @
# the two lines below have not been tested
#		regsub -all "\[^-\]\n" $entry { } entry2
#		regsub -all -- "-\n" $entry2 {} entry2	;# hyphen 
# Update the metadata repository or create a metadata repository
# rep
		if [info exists rep] {unset rep}
		if [info exists callingRep] {unset callingRep}
# WARNING: when editing a refer metadata (with EndNote for example)
# if the field value contains a % followed by no space or no
# punctuation mark (.;,), then this % must not appear at the
# begining of a line (it may appear in the middle of a line).

# entry2
		set entry2 \n[string trim $entry \n]
		regsub -all {@} $entry2 {#!#} entry2	;# @ > #!#
		regsub -all "\n%(\[^ \\.;,\])" $entry2 {@\1} entry2
#		regsub -all "\n" $entry2 { } entry2
		regsub -all "\n+" $entry2 { } entry2
# Store entry2 C:/tmp/bbb.txt auto 0 a
# =>
# @0 Newspaper Article@D 2002@9 URLibService test@A Ribeiro, João,@A Batista, Laura,@T Teste2@8 2002-03-12@#!#nexthigherunit J8LNKB5R7W/3GFJKM8 J8LNKB5R7W/3LBEQ3H@#!#usergroup banon@3 clipping1.html@#!#copyholder SID/SCD@2 iconet.com.br/banon/2005/12.30.19.29.37@#!#affiliation Instituto Nacional de Pesquisas Espaciais (INPE)@4 iconet.com.br/banon/2005/12.30.19.29@#!#documentstage not transferred@B O Globo

		set fieldList {}
		set targetFile {}
# FOREACH 2
		foreach field [lrange [split $entry2 @] 1 end] {
			regsub -all {#!#} $field {@} field	;# #!# > @
			set field [string trimright $field]
			regexp "^0 (.*)" $field m referenceType
			regexp "^2 (.*)" $field m callingRep	;# metadata repository
			regexp "^3 (.*)" $field m targetFile
			regexp "^4 (.*)" $field m rep
#			if [regexp "^(\[AEY\]) (.*)" $field m letter name] # (drop on 11/5/04)
			if [regexp {^([AEY?]) (.*)} $field m letter name] {
#				regsub { *;$} $name {} name	;# drop trailing semicolon
#				set field "$letter [FormatName $name]"
#				set field "$letter [ProcessCapitalString [FormatName $name]]"
# set xxx $name
# Store xxx C:/tmp/bbb.txt auto 0 a 
# set xxx [ProcessCapitalString $name]
# Store xxx C:/tmp/bbb.txt auto 0 a 
#				if [regexp {,.+} $name] {set name [string toupper $name]}	;# name is not the name of an instituition - appropriate only with the Portuguese language - forces turning De into de
				if [regexp {,.+} $name] {
# name is not the name of an instituition
					set field "$letter [ProcessCapitalString $name]"	;# FormatName is now in ProcessAuthorField
				}
			}
			if [regexp "^(T) (.*)" $field m letter title] {
				set field "$letter [ProcessCapitalString $title title]"
			}
			if {[info exists referenceType] && [string equal {Thesis} $referenceType] && [regexp "^(J) (.*)" $field m letter title]} {
# alternatetitle
				set field "$letter [ProcessCapitalString $title title]"
			}
			if {[info exists referenceType] && ![string equal {Data} $referenceType] && [regexp "^(B) (.*)" $field m letter value]} {
# journal ...
				set field "$letter [ProcessCapitalString $value]"
			}
			if {[info exists referenceType] && [string equal {Image} $referenceType] && [regexp "^N (.*)" $field m value]} {
# imageSize
				set imageSize $value
			}
			lappend fieldList %$field
		}

# Store fieldList C:/tmp/bbb.txt auto 0 a
# puts $fieldList
# =>
# {%0 Newspaper Article} {%D 2002} {%9 URLibService test} {%A Ribeiro, João,} {%A Batista, Laura,} {%T Teste2} {%8 2002-03-12} {%@nexthigherunit J8LNKB5R7W/3GFJKM8 J8LNKB5R7W/3LBEQ3H} {%@usergroup banon} {%3 clipping1.html} {%@copyholder SID/SCD} {%2 iconet.com.br/banon/2005/12.30.19.29.37} {%@affiliation Instituto Nacional de Pesquisas Espaciais (INPE)} {%4 iconet.com.br/banon/2005/12.30.19.29} {%@documentstage not transferred} {%B O Globo}
 
TraceProcedure fieldList...
TraceProcedure $fieldList

# Drop possible nexthigherunit value == identifier to avoid infinite Arrangements
# when calling the BuildReturnPathArray recurrent procedure
# added by GJFB on 2021-08-17
# identifier
		LoadService $rep identifier identifier 1 1
		if ![string equal {} $identifier] {	;# if added by GJFB on 2023-07-30 - otherwise old item without identifier cannot have nexthigherunit (ex: URLibService Copyright)
			set index [lsearch -regexp $fieldList %@nexthigherunit\\s+$identifier\\s*]
			set fieldList [lreplace $fieldList $index $index]
		}
# Drop possible nexthigherunit value == identifier to avoid infinite Arrangements - end
	
		if ![string equal {UpdateRepMetadataRep} [lindex [info level [expr [info level] - 1]] 0]] {	;# added by GJFB on 2019-12-21 - the code below is redundant for UpdateRepMetadataRep
# LoadMetadata is called by CreateRepMetadataRep
# Ajust the target file
#		if [string equal {enable} $targetFileOption] #
			set targetFile2 [AjustTargetFile $rep $targetFile $targetFileOption]	;# example of target file: {*,*/*,*/*/*}.[pP][dD][fF]
			if ![string equal $targetFile2 $targetFile] {
# correct targetFile
				UpdateMetadataEntryList fieldList %3 $targetFile2
				set targetFile $targetFile2	;# added by GJFB on 2011-05-31
#				Store targetFile $col/$repName/service/targetFile	;# done later in DDRoutine
			}
#		#		
# Ajust the target file - end
		}

#		set targetFile [GetReferField $entry 3]	;# commented by GJFB on 2018-05-19 - already defined above
		
# puts --$targetFile--

if 0 {
# commented by GJFB on 2019-12-21 - similar code now in AjustTargetFile
# Force the target file name of the bibliographic mirror - added by GJFB on 2018-05-19 - useful when submitting a file (like @siteList.txt) to an empty doc
		if [TestContentType $rep {Mirror}] {
			set targetFile mirror.cgi	;# the name mirror.cgi must be preserved
			UpdateMetadataEntryList fieldList %3 $targetFile
		}
# Force the target file name of the bibliographic mirror - end
}

TraceProcedure	;# add executing time interval
TraceProcedure [list targetFile = $targetFile]
		
TraceProcedure	;# add executing time interval
TraceProcedure $fieldList
TraceProcedure {Updating repositoryProperties (targetfile)...}

# Store fieldList C:/tmp/bbb.txt auto 0 a

# Update repositoryProperties (targetfile)
# metadata -> repositoryProperties -> service
# puts $entry

# puts [Info exists repositoryProperties($rep,targetfile)]
		set oldTargetFile {}
		if [Info exists repositoryProperties($rep,targetfile)] {
			set oldTargetFile [Get repositoryProperties($rep,targetfile)]
			set oldTargetFile [join $oldTargetFile]	;# {RBMET_SAULO[1].pdf} -> RBMET_SAULO[1].pdf - braces appear while executing: lappend replyList $reply, within GetReply
			if ![string equal {} $targetFile] {
				if {$oldTargetFile != "$targetFile"} {
# new target file setting
					Set repositoryProperties($rep,targetfile) $targetFile	;# Set preserve extra white spaces unlike Get
					Store targetFile $col/$rep/service/targetFile
				} else {
					if ![file exists $col/$rep/service/targetFile] {
# the target file has been deleted
						Store targetFile $col/$rep/service/targetFile
					}
				}
			} else {
# no more target file setting
				Unset repositoryProperties($rep,targetfile)
				file delete $col/$rep/service/targetFile
			}
		} else {
			if ![string equal {} $targetFile] {
# first target file setting
				Set repositoryProperties($rep,targetfile) $targetFile
				Store targetFile $col/$rep/service/targetFile
			}
		}
# Update repositoryproperties (targetfile) - end

TraceProcedure {Updating repositoryProperties (targetfile) done}

# puts $fieldList
# => {%0 Image} {%@mirrorrepository dpi.inpe.br/banon/1999/06.19.17.00} {%T Testando submissao bmp} {%@format bmp} {%@secondarytype color} {%@usergroup banon} {%3 ClaraModeloIV.bmp} {%2 urlib.net/www/2012/06.17.23.30.16} {%4 urlib.net/www/2012/06.17.23.30} {%D 2005} {%A Banon, Gerald Jean Francis,}
		if [string equal {Image} $referenceType] {
			if ![info exists imageSize] {set imageSize {}}
# puts --$targetFile--
# puts --$oldTargetFile--
# puts --$imageSize--
			set imageSize [MakeThumbnail $rep $referenceType $targetFile $oldTargetFile $imageSize]
			UpdateMetadataEntryList fieldList %N $imageSize
		}

TraceProcedure $fieldList

		set entry [join $fieldList \n]	;# now names have been formated
# OBS: the %2 field (Metadata Repository) is used to make the difference
# between more than one metadata for the same repository

# Store entry C:/tmp/bbb.txt auto 0 a 
# =>
# %0 Newspaper Article
# %D 2002
# %9 URLibService test
# %A Ribeiro, João,
# %A Batista, Laura,
# %T Teste2
# %8 2002-03-12
# %@nexthigherunit J8LNKB5R7W/3GFJKM8 J8LNKB5R7W/3LBEQ3H
# %@usergroup banon
# %3 clipping1.html
# %@copyholder SID/SCD
# %2 iconet.com.br/banon/2005/12.30.19.29.37
# %@affiliation Instituto Nacional de Pesquisas Espaciais (INPE)
# %4 iconet.com.br/banon/2005/12.30.19.29
# %@documentstage not transferred
# %B O Globo

		if ![info exists rep] {
			if ![info exists callingRep] {
# the entry is candidate to update the default metadata
#				set path $col/$defaultMetadataRepository/doc/@metadata.refer
				Store entry $col/$defaultMetadataRepository/doc/@metadata.refer
#				break
			} else {
# there is a metadata repository name in entry but there is no repository name
# add the fields targetfile and repName
				foreach {repName fieldList} \
				[Eval AddTwoFields $callingRep $referenceType $targetFile $fieldList] \
				{break}	;# uses referenceTable to recreate repName
# repName not used
#				set fieldList [lsort -command ReferFieldCompare $fieldList]	;# now in AddTwoFields
				set entry [join $fieldList \n]
				Store entry $col/$callingRep/doc/@metadata.refer
## there could be a warning message here
#				break
			}
		}
TraceProcedure {Testing Info...}
# TraceProcedure [list Info exists repositoryProperties($rep,history) == [Info exists repositoryProperties($rep,history)]]

		if ![Info exists repositoryProperties($rep,history)] {continue} ;# the repositry ($rep) may not exist

TraceProcedure {Creating or updating a metadata repository...}

# Create or update a metadata repository
		set updated 0
		if [info exists callingRep] {
			if [Eval TestContentType $callingRep Metadata] {
				if [file exists $col/$callingRep] {
# a metadata repository already exists
TraceProcedure {a metadata repository already exists}
#					set path $col/$callingRep/doc/@metadata.refer
#					Load $path fileContent
#					if {[string compare $entry $fileContent] != 0} {
## update the @metadata.refer file content
# STORE entry
TraceProcedure $entry
						Store entry $col/$callingRep/doc/@metadata.refer
# puts stored
#					}
# Create reference
# when creating a new repository with no metadata and this repository
# is for metadata then we need to create service/reference
					if ![file exists $col/$callingRep/service/reference] {
						set reference ../$col/col/$rep
						Store reference $col/$callingRep/service/reference
						Set referenceTable($callingRep,$rep) 1
					}
# Create reference - end
					set updated 1
				} else {
# no metadata repository exists for $rep
					Eval UpdateVariables $callingRep
				}
			}
		}

# Load $col/$callingRep/doc/@metadata.refer xxx
# Store xxx C:/tmp/bbb.txt auto 0 a
 
TraceProcedure {Creating or updating a metadata repository (continue)...}
TraceProcedure $updated

		if !$updated {
# no metadata repository exists for $rep - create a metadata repository
# something is probably missing since one gets the following error:
# {catched error from mtc-m21b.sid.inpe.br} {can't read "metadataArray(sid.inpe.br/mtc-m21b/2015/04.22.15.32-0,referencetype)": no such element in array}
# when pressing "access"

# Save @metadata.refer in the URLib clipboard
			set docPath $homePath/clipboard
# STORE entry
			Store entry $docPath/@metadata.refer
# Save @metadata.refer in the URLib clipboard - end

			set argument ""
#			set argument "$argument -targetfile enable"
			set argument "$argument -documenttype directory"
			set argument "$argument -repositorytype new"
			set argument "$argument -option preserve"
			set argument "$argument -reverse 0"
			set argument "$argument -documentpath [list $docPath/]"
			set argument "$argument -makeauxdoc 0"
			set argument "$argument -makesource 0"
			set argument "$argument -fileinfo 0"
			set argument "$argument -username $userName"
			set return [DDRoutine $argument 0 $metadataRepName]
			if {$return == 1} {continue}
			if {$return == 0} {continue}
			set callingRep $return
			file delete $col/$callingRep/service/transferableFlag	;# added by GJFB on 2010-10-09 - metadata repository doesn't need a transferable flag
			
			Load $col/$callingRep/doc/@metadata.refer entry
##			set imageSize [MakeThumbnail $rep $referenceType $targetFile]	;# when reference type is Image
#			if {[info exists imageSize] && [string equal {Image} $referenceType]} {
#				regsub {(%0[^%]*)} $entry "\\1%N $imageSize\n" entry
#			}
			regsub {(%0[^%]*)} $entry "\\1%2 $callingRep\n" entry
			Store entry $col/$callingRep/doc/@metadata.refer

# Update repositoryProperties and service directory
			set typeContent Metadata
			Set repositoryProperties($callingRep,type) $typeContent
			Store typeContent $col/$callingRep/service/type
			set targetFile metadata.cgi
			Set repositoryProperties($callingRep,targetfile) $targetFile
			Store targetFile $col/$callingRep/service/targetFile
# Update repositoryProperties and service directory - end
			
# Add fields
# Add the site field
			set metadataList [list $callingRep-0,site $site]
# Add the site field - end
# Add the hostcollection field
			set metadataList [concat $metadataList [list $callingRep-0,hostcollection $loCoInRep]]
# Add the hostcollection field - end
# Add agreement field
			set dir $homePath/col/$rep/agreement
			if [file isdirectory $dir] {
				set fileList {}
				DirectoryContent fileList $dir $dir
				set metadataList [concat $metadataList [list $callingRep-0,agreement $fileList]]
			}
# Add agreement field - end
#			Eval AddMetadata $metadataList	;# metadataList must not be too big, otherwise Eval doesn't return - commented by GJFB on 2020-08-18
			Eval AddMetadata2 $metadataList	;# added by GJFB on 2020-08-18
# Add fields - end

# Start apache server
			Set startApacheServer 1
# Start apache server - end
# Update referenceTable
			set reference ../$col/col/$rep
			Store reference $col/$callingRep/service/reference
			Eval UpdateReferenceTable $callingRep
#			Eval UpdateReferenceFileForLoCoInRep
# Update referenceTable - end
		}

TraceProcedure {Updating history...}

# Update history
# CREATE A NEW VERSION STAMP (for the metadata repository (callingRep))
#		set seconds [Eval RepositoryMTime $callingRep $homePath]
		set seconds [clock seconds]
		set metadataVersionStamp [CreateVersionStamp $seconds $userName $entry]
		Eval UpdateHistory $callingRep $metadataVersionStamp	
# Update history - end

# Update metadataArray and repArray
		set metadataList {}
		set metadata2List {}

		if $updateLastupdateFlag {	;# added by GJFB on 2018-04-17
TraceProcedure {Updating lastupdate and metadatalastupdate...}

# Update lastupdate and metadatalastupdate
# lastupdate doesn't exist after executing CreateNewRepository
TraceProcedure $rep
if 0 {
# testing socket
# old code - time consuming when history is large - useful to test socket with large history
			set history [Get repositoryProperties($rep,history)]
			set versionStamp [lindex $history end]
} else {
# new code - faster
			set versionStamp [Eval GetVersionStamp $rep]
}
TraceProcedure {history captured}
			UpdateMetadataField $callingRep lastupdate $versionStamp metadataList metadata2List
TraceProcedure {lastupdate updated}
			UpdateMetadataField $callingRep metadatalastupdate $metadataVersionStamp metadataList metadata2List
# Update lastupdate and metadatalastupdate - end

TraceProcedure {Updating size and numberOfFiles...}

# Update size and numberOfFiles
			foreach {size numberOfFiles} [ComputeInfo $rep] {break}
#			if [string equal {0 Kbyte} $size] #
			if [string equal {0 KiB} $size] {
				file delete $homePath/col/$rep/service/size
				set size {}	;# used by UpdateMetadataField below (to remove size)	
			} else {
				Store size $homePath/col/$rep/service/size
				Set repositoryProperties($rep,size) $size
			}	
			if [string equal {0} $numberOfFiles] {
				file delete $homePath/col/$rep/service/numberOfFiles
				set numberOfFiles {}	;# used by UpdateMetadataField below (to remove numberoffiles)
				catch {file delete $homePath/col/$rep/auxdoc} 	
				catch {file delete $homePath/col/$rep/source} 	
			} else {
				Store numberOfFiles $homePath/col/$rep/service/numberOfFiles
				Set repositoryProperties($rep,numberoffiles) $numberOfFiles
				file mkdir $homePath/col/$rep/auxdoc
				file mkdir $homePath/col/$rep/source
			}
			UpdateMetadataField $callingRep size $size metadataList metadata2List 1
			UpdateMetadataField $callingRep numberoffiles $numberOfFiles metadataList metadata2List 1
# Update size and numberOfFiles - end
		}

#		if [string equal {Image} $referenceType] {
#			UpdateMetadataField $callingRep imagesize $imageSize metadataList metadata2List 1
#		}

# puts "metadata2List = --$metadata2List--"
# puts "metadataList = --$metadataList--"

if 0 {
# commented by GJFB on 2020-08-18
		Eval RemoveMetadata $metadata2List
		Eval AddMetadata $metadataList
} else {
		Eval UpdateMetadata $metadata2List $metadataList	;# added by GJFB on 2020-08-18 - uses metadata2List and metadataList
}
		Set saveMetadata 1
# Update metadataArray and repArray - end

# Create or update a metadata repository - end

# Update the metadata repository or create a metadata repository - end

# Load $col/$callingRep/doc/@metadata.refer xxx
# Store xxx C:/tmp/bbb.txt auto 0 a
 
		if $computeReturnValue {
			array set localMetadataArray [ConvertRefer2MetadataList $entry $callingRep 0]
		}
	}	;# end FOREACH
# puts $entry
# puts {}
# set xxx [array get localMetadataArray]
# puts $xxx
# Store xxx C:/tmp/bbb.txt auto 0 a

	return [array get localMetadataArray]
}

# LoadMetadata - end
# ----------------------------------------------------------------------
# MakeThumbnail
# used in LoadMetadata only
# the target file should be submited explicitly (not through a zip file) in order to mtime2 be the submission time
# image size value must be preserved if no thumbnail is made

proc MakeThumbnail {rep referenceType targetFile oldTargetFile imageSize} {
	global homePath
	global pythonPath
	
	set docPath $homePath/col/$rep/doc
	set thumbnailDirectoryPath $homePath/col/$rep/images
	file mkdir $thumbnailDirectoryPath	;# added by GJFB on 2025-08-28
	if [string equal {} $targetFile] {
		file delete -force $thumbnailDirectoryPath
		set imageSize {}
	} else {
# targetFileExtension
		set targetFileExtension [file extension $targetFile]
		set fileRootName thumbnail
if 1 {
# added by GJFB on 2025-08-28
# making thumbnails in "Image" repository containing a PDF and a jpg image both with the same root name
		if [string equal -nocase {.pdf} $targetFileExtension] {
# the target file is a PDF
			set targetFileRoot [file root $targetFile]
			if [file exists $docPath/$targetFileRoot.jpg] {
				set imageFilePath $docPath/$targetFileRoot.jpg	;# must be after the ifs - added by GJFB on 2020-03-25 to work with images in directories
				set imageName [file tail $imageFilePath]
				set message [exec $pythonPath makeThumbnail.py $imageFilePath $thumbnailDirectoryPath $fileRootName .jpg 2 $imageName]	;# added by GJFB on 2025-08-28
			}
		}
}
#		if [regexp -nocase {\.(bmp|jpg)$} $targetFileExtension] #
		if [regexp -nocase {\.(bmp|jpg|jpeg)$} $targetFileExtension] {	;# added by GJFB on 2020-07-27
			if ![string equal {} $pythonPath] {
				set targetFilePath $docPath/$targetFile
#				file mkdir $thumbnailDirectoryPath	;# commented by GJFB on 2025-08-28
#				set fileRootName thumbnail
				set targetDirName [file dirname $targetFile]	;# added by GJFB on 2020-03-25 to work with images in directories
# Create imageList
				set pwd [pwd]
#				cd $docPath
				cd $docPath/$targetDirName	;# added by GJFB on 2020-03-25 to work with images in directories
#				set imageList [glob -nocomplain *$targetFileExtension]
				set imageList {}
				set imageList [concat $imageList [glob -nocomplain {*.[bB][mM][pP]}]]
				set imageList [concat $imageList [glob -nocomplain {*.[jJ][pP][gG]}]]
				set imageList [concat $imageList [glob -nocomplain {*.[jJ][pP][eE][gG]}]]	;# added by GJFB on 2020-07-27
				cd $pwd
# Create imageList - end
				foreach imageName $imageList {
					set encodingSystem [encoding system]	;# to preserve the current encoding system
#					if ![file exists $homePath/col/$rep/doc/$imageName] {encoding system iso8859-1}	;# try iso8859-1 - solves the accent problem in md-m09, col/sid.inpe.br/md-m09/2013/07.31.14.14/doc contain files whose names were iso coded (because created under a iso Linux operating system and then migrated to an utf Linux operating system (machine change hosting the site md-m09.sid.inpe.br) - added by GJFB on 2013-08-30 - same code as in CreateDirectoryContentList (see GJFB on 2012-08-18)
#					if ![file exists $homePath/col/$rep/doc/$imageName] {encoding system utf-8}	;# try utf-8 - solves the accent problem - added by GJFB on 2013-08-30 - same code as in CreateDirectoryContentList (see GJFB on 2012-08-18)
#					set imageFilePath $homePath/col/$rep/doc/$imageName	;# must be after the ifs
					if ![file exists $homePath/col/$rep/doc/$targetDirName/$imageName] {encoding system iso8859-1}	;# try iso8859-1 - solves the accent problem in md-m09, col/sid.inpe.br/md-m09/2013/07.31.14.14/doc contain files whose names were iso coded (because created under a iso Linux operating system and then migrated to an utf Linux operating system (machine change hosting the site md-m09.sid.inpe.br) - added by GJFB on 2013-08-30 - same code as in CreateDirectoryContentList (see GJFB on 2012-08-18) - added by GJFB on 2020-03-25 to work with images in directories
					if ![file exists $homePath/col/$rep/doc/$targetDirName/$imageName] {encoding system utf-8}	;# try utf-8 - solves the accent problem - added by GJFB on 2013-08-30 - same code as in CreateDirectoryContentList (see GJFB on 2012-08-18) - added by GJFB on 2020-03-25 to work with images in directories
					set imageFilePath $homePath/col/$rep/doc/$targetDirName/$imageName	;# must be after the ifs - added by GJFB on 2020-03-25 to work with images in directories
#					if [string equal $targetFile $imageName] #
#					if [string equal [file tail $targetFile] $imageName] #	;# added by GJFB on 2020-03-25 to work with images in directories - commented by GJFB on 2025-08-28
					if [string equal [file root [file tail $targetFile]] [file root $imageName]] {	;# added by GJFB on 2020-03-25 to work with images in directories - added by GJFB on 2025-08-28
# process the target file
						set thumbnailFilePath $thumbnailDirectoryPath/${fileRootName}1$targetFileExtension
						set targetFileFlag [TestMTime $thumbnailFilePath $targetFilePath]
						if {$targetFileFlag || $oldTargetFile != "$targetFile"} {
							set message [exec $pythonPath makeThumbnail.py $imageFilePath $thumbnailDirectoryPath $fileRootName $targetFileExtension 1 $imageName]
							set imageSize $message
# puts --$message--
							regsub {\((\d+), (\d+)\)} $imageSize {\1 x \2} imageSize	;# (1026, 772) -> 1026 x 772
						}
					} else {
# process the other files
						if [TestMTime $homePath/col/$rep/images/thumbnail4-$imageName $imageFilePath] {
							if [file exists $homePath/col/$rep/images/thumbnail4-$imageName] {file delete $homePath/col/$rep/images/thumbnail4-$imageName}
							if [file exists $homePath/col/$rep/images/thumbnail5-$imageName] {file delete $homePath/col/$rep/images/thumbnail5-$imageName}
#							exec $pythonPath makeThumbnail.py $imageFilePath $thumbnailDirectoryPath $fileRootName $targetFileExtension 0 $imageName
							if [catch {exec $pythonPath makeThumbnail.py $imageFilePath $thumbnailDirectoryPath $fileRootName {} 0 $imageName} message] {
								error "MakeThumbnail (1): error while processing image $imageFilePath: $message"
							}
						}
# puts --$message--
					}
					encoding system $encodingSystem	;# to preserve the current encoding system
				}
# Delete thumbail files of deleted images
				cd $homePath/col/$rep/images
#				set imageList2 [glob -nocomplain thumbnail\[45\]-*$targetFileExtension]
				set imageList2 [glob -nocomplain {thumbnail[45]-*}]
				cd $pwd
				foreach imageName $imageList2 {
					regsub {thumbnail[45]-} $imageName {} imageName2
					if {[lsearch $imageList $imageName2] == -1} {
						file delete $homePath/col/$rep/images/$imageName
					}
				}
# Delete thumbail files of deleted images - end
			} else {
				error "MakeThumbnail (2): python missing - Please, install python and PIL and do unpost/post"
			}
		}
	}
	return $imageSize
}

# MakeThumbnail - end
# ----------------------------------------------------------------------
# TestMTime
# used in MakeThumbnail only
# returns 1 if filePath1 is older than filePath2 or than 2012-12-15 (when changing height from 400 to 480)

proc TestMTime {filePath1 filePath2} {
	if [file exists $filePath1] {
		set mtime1 [file mtime $filePath1]
	} else {
		set mtime1 0
	}
	if [file exists $filePath2] {
		set mtime2 [file mtime $filePath2]
	} else {
		set mtime2 0
	}
	return [expr $mtime1 < $mtime2 || $mtime1 < 1355619991]
}

# TestMTime - end
# ----------------------------------------------------------------------
# MultipleEval
# Example:
# MultipleEval GetMetadataRepositories $mirrorRep 0 $var no no 1

proc MultipleEval {args} {
# runs with start and post
	global serverAddressWithIP
	set command "list $args"
	return [MultipleExecute [list $serverAddressWithIP] $command]
}

# MultipleEval - end
# ----------------------------------------------------------------------
# Info
# example:
# Info exists repositoryProperties($rep,type)

proc Info {args} {
# runs with start and post
	global serverAddressWithIP
	global applicationName
	
	if {![info exists applicationName] || $applicationName == "start"} {
		return [Execute $serverAddressWithIP "info $args" 0]	;# not async
	} else {
# post
# Info doesn't work with Execute when UpdateAccessFile is called from a cgi script (Get or Get-) (with mtc-m19)
		global environmentArray	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddress	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddressWithIP	;# used remotely by start (see SPOK) (Set procedure)
		global localSite	;# used remotely by start (see SPOK) (Set procedure)
		global repositoryProperties ;# used remotely by start
		global referenceTable ;# used remotely by start
		global metadataArray ;# used remotely by start (see SPOK)
		global repArray ;# used remotely by start (see SPOK)
		global saveMetadata ;# used remotely by start
		global startApacheServer ;# used remotely by start
		global startApplicationInUse ;# used remotely by start
		return [eval info $args]
	}
}

# Info - end
# ----------------------------------------------------------------------
# Set
# example:
# Set repositoryProperties($rep,type) $type

proc Set {args} {
# runs with start and post
	global serverAddressWithIP
	global applicationName
	
	if {![info exists applicationName] || $applicationName == "start"} {
		Load ../auxdoc/pid pid
		return [Execute $serverAddressWithIP "set $pid $args" 0]	;# not async
	} else {
# post
		global environmentArray	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddress	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddressWithIP	;# used remotely by start (see SPOK) (Set procedure)
		global localSite	;# used remotely by start (see SPOK) (Set procedure)
		global repositoryProperties ;# used remotely by start
		global referenceTable ;# used remotely by start
		global metadataArray ;# used remotely by start (see SPOK)
		global repArray ;# used remotely by start (see SPOK)
		global saveMetadata ;# used remotely by start
		global startApacheServer ;# used remotely by start
		global startApplicationInUse ;# used remotely by start
		global queueLengthArray ;# used in MultipleSubmit
		
		return [eval set $args]
	}
}

# Set - end
# ----------------------------------------------------------------------
# Lappend
# example:
# Lappend repList $rep

proc Lappend {args} {
# runs with start and post
	global serverAddressWithIP
	global applicationName
	
	if {![info exists applicationName] || $applicationName == "start"} {
		Load ../auxdoc/pid pid
		return [Execute $serverAddressWithIP "lappend $pid $args" 0]	;# not async
	} else {
# post
		global environmentArray	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddress	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddressWithIP	;# used remotely by start (see SPOK) (Set procedure)
		global localSite	;# used remotely by start (see SPOK) (Set procedure)
		global repositoryProperties ;# used remotely by start
		global referenceTable ;# used remotely by start
		global metadataArray ;# used remotely by start (see SPOK)
		global repArray ;# used remotely by start (see SPOK)
		global saveMetadata ;# used remotely by start
		global startApacheServer ;# used remotely by start
		global startApplicationInUse ;# used remotely by start
		return [eval lappend $args]
	}
}

# Lappend - end
# ----------------------------------------------------------------------
# Unset
# example:
# Unset repositoryProperties($repName,targetfile)

proc Unset {args} {
# runs with start and post
	global serverAddressWithIP
	global applicationName
	
	if {![info exists applicationName] || $applicationName == "start"} {
		Load ../auxdoc/pid pid
		return [Execute $serverAddressWithIP "unset $pid $args" 0]	;# not async
	} else {
# post
		global environmentArray	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddress	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddressWithIP	;# used remotely by start (see SPOK) (Set procedure)
		global localSite	;# used remotely by start (see SPOK) (Set procedure)
		global repositoryProperties ;# used remotely by start
		global referenceTable ;# used remotely by start
		global metadataArray ;# used remotely by start (see SPOK)
		global repArray ;# used remotely by start (see SPOK)
		global saveMetadata ;# used remotely by start
		global startApacheServer ;# used remotely by start
		global startApplicationInUse ;# used remotely by start
		return [eval unset $args]
	}
}

# Unset - end
# ----------------------------------------------------------------------
# Get
# example:
# set type [Get repositoryProperties($rep,type)]

proc Get {varName} {
# runs with start and post
#	global serverAddressWithIP
	Load ../auxdoc/pid pid
#	return [Execute $serverAddressWithIP "GetValue $pid $varName"]	;# did not return with big service/history (29K)
	return [MultipleEval GetValue $pid $varName]
}

# Get - end
# ----------------------------------------------------------------------
# Array
# example:
# Array names referenceTable *$rep*

proc Array {args} {
# runs with start and post
	global serverAddressWithIP
	global applicationName
	
	if {![info exists applicationName] || $applicationName == "start"} {
		Load ../auxdoc/pid pid
		return [Execute $serverAddressWithIP "array $pid $args" 0]	;# not async
	} else {
# post
		global environmentArray	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddress	;# used remotely by start (see SPOK) (Set procedure)
		global serverAddressWithIP	;# used remotely by start (see SPOK) (Set procedure)
		global localSite	;# used remotely by start (see SPOK) (Set procedure)
		global repositoryProperties ;# used remotely by start
		global referenceTable ;# used remotely by start
		global metadataArray ;# used remotely by start (see SPOK)
		global repArray ;# used remotely by start (see SPOK)
		global saveMetadata ;# used remotely by start
		global startApacheServer ;# used remotely by start
		global startApplicationInUse ;# used remotely by start
		return [eval array $args]
	}
}

# Array - end
# ----------------------------------------------------------------------
# DownloadFileExists
# used in SynchronizeRepository only

proc DownloadFileExists {rep} {
	global homePath
	
	return [file exists $homePath/col/$rep/download/doc.zip]
}

# DownloadFileExists - end
# ----------------------------------------------------------------------
# DownloadFileMtime
# used in SynchronizeRepository only

proc DownloadFileMtime {rep} {
	global homePath
	
	return [file mtime $homePath/col/$rep/download/doc.zip]
}

# DownloadFileMtime - end
# ----------------------------------------------------------------------
# GetMetadataArrayNames
# used in iconet.com.br/banon/2004/11.15.21.08::CreateXRefer 
# used in col/dpi.inpe.br/banon-pc@1905/2005/02.19.00.40/doc/cgi/script.tcl

proc GetMetadataArrayNames {pattern} {
# runs with post
	global metadataArray
	return [array names metadataArray $pattern]
}

# GetMetadataArrayNames - end
# ----------------------------------------------------------------------
# PostLocalCollection
# used in start only
# arg was added by GJFB on 2020-06-02

proc PostLocalCollection {{arg {}}} {
# runs with start
	global tclPath
	
	set message {}
# POST
	exec $tclPath post $arg &
#	while {![file exists ../auxdoc/messageForStart]}
# while above doesn't work with UNIX because writing the file content may be time consuming
# the file may be created but not written when it is read
	while {[string equal {} $message]} {
		set x 0; after 100 {set x 1}; vwait x
		Load ../auxdoc/messageForStart message	;# used in start
	}
# puts $message
	return $message
}

# PostLocalCollection - end
# ----------------------------------------------------------------------
# SetCursor
# examples:
#	$t tag bind $copyrightRep <Enter> "SetCursor $t hand2"
#	$t tag bind $copyrightRep <Leave> "SetCursor $t double_arrow"

proc SetCursor {widget cursor} {
	global performCheckRunning
	global updateTargetFileRunning
	global dialogRunning
	if {!$performCheckRunning && !$updateTargetFileRunning && !$dialogRunning} {
# not running
		$widget config -cursor $cursor
	}
}

# SetCursor
# ----------------------------------------------------------------------
# CheckPassword
# type value is write or read
# seekInOtherSites value is 0 or 1
# 1 means to seek for user name and password in the sites
# listed in >>> $loCoInRep/doc/@siteList.txt
# returns 0 if the password is correct
# returns 1 if the password is incorrect (and the user name exists)
# returns 2 if the user name doesn't exist
# password must be coded
# checkOnlyUserName value is 0 or 1 (used in CheckUsernamePassword only)
# 1 means to check only the user name
# sessionTime value are miliseconds - added by GJFB on 2019-01-16

proc CheckPassword {
	userName password {type write} {seekInOtherSites 1}
	{checkOnlyUserName 0} {sessionTime {}}
} {
	global homePath
	global htpasswdPath
	global loCoInRep
	global environmentArray

# set xxx [list $userName --$password--]
# Store xxx C:/tmp/bbb.txt auto 0 a
# puts [list $userName --$password--] 
# Find administrator user name
# this part cannot be omitted despite the fact that the administrator is part of
# the @passwords.txt file (because it is not part of .userArray.tcl
	regsub {@.*$} $environmentArray(spMailEntry) {} administratorUserName
if 0 {
# commented by GJFB on 2014-04-07 - doesn´t work when changing the administrator name
	if [string equal {administrator} $userName] {
# administrator is alias for administrator user name
		set userName $administratorUserName
	}
}
# Find administrator user name - end
#	set passwordList [GetUserData * $type {encryptedpassword}]	;# commented by GJFB on 2014-04-07 - doesn´t find the administrator
	set passwordList [GetUserData * {} {encryptedpassword}]	;# added by GJFB on 2014-04-07 in order to return the administrator
# puts $passwordList
	set userName [FilterEMailAddress $userName]
# puts [list $userName $password]
	catch {exec $htpasswdPath -nbs $userName [DecodeKey $password $sessionTime]} htpasswdLine
# puts $htpasswdLine 
	set htpasswdLine [string trim $htpasswdLine \n]	;# some htpasswd add a blank line (ex: Kurumin 4.1)
#	if {[lsearch -exact [split $fileContent \n] $htpasswdLine] != -1}
	if {[lsearch -exact $passwordList $htpasswdLine] != -1} {
# same password
		return 0	;# the password is correct
	} else {
# user name not found or password is incorrect
		set return 2	;# the user name doesn't exist
#		foreach line [split $fileContent \n]
		foreach line $passwordList {
			regexp {^[^:]*} $line userName2
			if [string equal $userName $userName2] {
# the user name exists
				if $checkOnlyUserName {
					return 0 	;# the user name exists
				} else {
					set return 1	;# the password is incorrect (and the user name exists)
					break
				}
			}
		}
	}

# Store return C:/tmp/bbb.txt auto 0 a
# puts >>>>$return
# puts $seekInOtherSites
#	if {$seekInOtherSites && ![string equal $administratorUserName $userName] && \
#	($return == 2 || ![string equal {} $password])} #
#	if {$seekInOtherSites && ![string equal $administratorUserName $userName] && $return != 0} #
#	if {$seekInOtherSites && !([string equal $administratorUserName $userName] || [string equal {administrator} $userName]) && $return != 0} #	;# commented by GJFB on 2022-07-03
	if {![string equal {} $password] && ($seekInOtherSites && !([string equal $administratorUserName $userName] || [string equal {administrator} $userName])) && $return != 0} {	;# new condition added by GJFB on 2022-07-03 - empty passord should be ignored to leave any existing stored password unchanged
# uses @siteList.txt in loCoInRep
		Load $homePath/col/$loCoInRep/doc/@siteList.txt fileContent
		set fileContent [string trim $fileContent]
		regsub -all "\n+" $fileContent "\n" fileContent
# set xxx --$fileContent--
# Store xxx C:/tmp/bbb.txt auto 0 a
# set xxx [llength [split $fileContent \n]]
# Store xxx C:/tmp/bbb.txt auto 0 a
		foreach siteRepIp [split $fileContent \n] {
			foreach {site2 loCoInRep2 ip2} $siteRepIp {break}
			foreach {serverName urlibPort} [ReturnCommunicationAddress $site2] {break}
#			set serverAddressWithIP [list $ip2 $urlibPort]]
#			set return2 [Execute $serverAddressWithIP [list CheckPassword $userName $password $type 0]]	;# 0 is to avoid infinite loops
			set siteList [list [list $ip2 $urlibPort]]
			set command [list list CheckPassword $userName $password $type 0]	;# 0 is to avoid infinite loops
# MULTIPLE SUBMIT
			set return2 [MultipleExecute $siteList $command]
#			set return2 [MultipleExecute $siteList $command 1]
# puts --$return2--
#			if {$return2 == 0} #
#			if {$return2 == 0 || ($return2 == 1 && [string equal {} $password])} #	;# commented by GJFB on 2023-05-10
			if {$return2 == 0 && $return == 2} {	;# added by GJFB on 2023-05-10 - do local updating only if the user name were not found - if it exists, password and local data should be preserve (ex: user banon has diferent passwords in different Archives)
# user name found and password is correct
## or user name found and password is empty
# and no local user name exists

# Capture user data
# htpasswdLine
				set command [list list GetUserData $userName {} {encryptedpassword}]
# MULTIPLE SUBMIT
				set htpasswdLine [MultipleExecute $siteList $command]
# userArray
				if [file exists $homePath/col/$loCoInRep/auxdoc/.userArray.tcl] {
					source $homePath/col/$loCoInRep/auxdoc/.userArray.tcl
				}
				set command [list list GetUserData $userName {} {fullname}]
# MULTIPLE SUBMIT
				set fullName [MultipleExecute $siteList $command]
				if ![string equal {} $fullName] {
					set userArray($userName,fullname) $fullName
				}
				set command [list list GetUserData $userName {} {e-mailaddress}]
# MULTIPLE SUBMIT
				set eMailAddress [MultipleExecute $siteList $command]
				if ![string equal {} $eMailAddress] {
					set userArray($userName,e-mailaddress) $eMailAddress
				}
# Capture user data - end

# Update user data
# Waiting for the completion of other authentications
				WaitQueue CheckPassword authentication
# Waiting for the completion of other authentications - end

				Load $homePath/col/$loCoInRep/auxdoc/@passwords.txt passwords
				set passwordList [split $passwords \n]
				if {$return == 1} {
					set index [lsearch -regexp $passwordList "^$userName:"]
					set passwordList [lreplace $passwordList $index $index]
				}
				lappend passwordList $htpasswdLine
				set passwords [join $passwordList \n]
# STORE passwords
				Store passwords $homePath/col/$loCoInRep/auxdoc/@passwords.txt

# STORE userArray
				StoreArray userArray $homePath/col/$loCoInRep/auxdoc/.userArray.tcl w list array 1

				LeaveQueue [pid] authentication
# Update user data - end

				return $return2
			} elseif {$return2 == 0 && $return == 1} {	;# elseif added by GJFB on 2023-05-10 - if the user name exists, other correct passwords from other Archives are accepted (ex: user banon has diferent passwords in different Archives)
				set return 0
			} elseif {$return2 == 1} {
				set return 1
#				if [string equal {} $password] {break}
			}
		}
	}
# puts $return
	return $return
}

if 0 {
set homePath {C:/Gerald/URLib 2}
set htpasswdPath {C:/Gerald/URLib 2/col/iconet.com.br/banon/2002/12.15.15.27/doc/htpasswd.exe}
set loCoInRep dpi.inpe.br/banon/1999/01.09.22.14
source utilities1.tcl	;# CreateWebLanguageTable called in LoadGlobalVariables
source utilities2.tcl
source cgi/mirrorfind-.tcl
source utilitiesStart.tcl
# set installInitialCollection 0
LoadGlobalVariables	;# environmentArray(spMailEntry)
puts [CheckPassword gerald 123]
}

# CheckPassword - end
# ----------------------------------------------------------------------
# Check-htpasswd
# returns 0 if htpasswd program was found
# and 1 otherwise

proc Check-htpasswd {} {
	global htpasswdPath
	if [file exists $htpasswdPath] {
		return 0
	} else {
		return 1
	}
}

# Check-htpasswd - end
# ----------------------------------------------------------------------
# CheckUsernamePassword
# if restrictedSubmission is 1 then the second password field is hidden
# and no new user can be authenticated.
# if restrictedSubmission is 0 then the second password field is displayed
# and a new user can be authenticated just by repeating his password
# in the second field
# for a given reference type, restrictedSubmission is effective
# if and only if the corresponding User Name field is set to be
# displayed
# type value is write or read
# formType value is {}, submissionform or registrationform
# formState value is {} or {nothingtoupdate} (used for the registration forms)
# sessionTime value is miliseconds - added by GJFB on 2019-01-16

proc CheckUsernamePassword {
	userName password1 password2
	restrictedSubmission type {formType {}} {currentPassword {}}
	{formState {}} {seekInOtherSites 1} {sessionTime {}}
} {
	if [string equal {} $userName] {
		return {empty username}
	}
#	if [regexp {[: ]|^administrator$} $userName]
	if [regexp {[: ]} $userName] {
		return {wrong username}
	}
	if $restrictedSubmission {
# password2 field doesn't exist
		set flag [CheckPassword $userName $password1 $type $seekInOtherSites]
		if [string equal 2 $flag] {
# unknown username
			return {unknown username}
		}
		if [string equal {} $password1] {
			return {empty password}
		}
		if $flag {
# password is wrong
			return {wrong password}
		}
	} else {
# password2 field exists
		if [regexp {^$|^submissionform$} $formType] {
# submission form
# type is write
			if [string equal {} $password1] {
				return {empty password1 at submission}
			}
			set flag [CheckPassword $userName $password1 $type $seekInOtherSites]
			if $flag {
# flag is 1 or 2
				if [string equal 1 $flag] {
# user name exists and password is wrong
					return {existing user name and wrong password}
				} else {
# user name doesn't exist
					if [string equal {} $password2] {
					return {empty password2 at submission}
					}
					if ![string equal $password1 $password2] {
						return {passwords are different}
					}
				}
			}	
		} else {
# registrationform
# type is read or write
			if [string equal {} $currentPassword] {
				if [string equal {} $formState] {
# first submission
					if {[string equal {} $currentPassword] && \
					[string equal {} $password1] && \
					[string equal {} $password2]} {
# check only the user name
# puts OK1
						set checkOnlyUserName 1
						set flag [CheckPassword $userName $password1 $type $seekInOtherSites $checkOnlyUserName] 
						if [string equal 2 $flag] {
							return {unknown username}
						} else {
#							return {nothing to do}
							return {existing user name}
						}
					}
#					set flag [CheckPassword $userName {} $type $seekInOtherSites]
					set flag [CheckPassword $userName {} read $seekInOtherSites]	;# a write user is also a read user
					if [string equal 1 $flag] {
# the user name exists
						return {existing user name}
					}
					if [string equal {} $password1] {
					return {empty password1}
					}
					if [string equal {} $password2] {
						return {empty password2}
					}
					if ![string equal $password1 $password2] {
						return {passwords are different}
					}
#					if {[string compare {} $eMailAddress] == 0} {
#						return {empty e-mail address}
#					}
#					if {[string compare {write} $type] == 0 } {
#						if {[string compare {} $fullName] == 0} {
#							return {empty full name}
#						}
#					}
				} else {
# not the first submission (nothingtoupdate state)
					return {empty current password}
				}
			} else {
# update
# change password
# puts OK2
#				set flag [CheckPassword $userName $currentPassword $type $seekInOtherSites]
				set flag [CheckPassword $userName $currentPassword read $seekInOtherSites]	;# read user may become write user
				if [string equal 2 $flag] {
# unknown username
					return {unknown username}
				}
				if $flag {
# password is wrong
					return {wrong password}
				} else {
#					if {[string compare {} $password1] == 0 && \
#						[string compare {} $password2] == 0 && \
#						[string compare {} $eMailAddress] == 0} {
#						return {nothing to update}
#					}
					if {![string equal {} $password1] || \
					![string equal {} $password2]} {
						if [string equal {} $password1] {
							return {empty password1}
						}
						if [string equal {} $password2] {
							return {empty password2}
						}
						if ![string equal $password1 $password2] {
							return {passwords are different}
						}
					}
				}
			}
		}
	}
}

# CheckUsernamePassword - end
# ----------------------------------------------------------------------
# CheckReadUsernamePassword

proc CheckReadUsernamePassword {userName password rep} {
	global environmentArray
	global repositoryProperties
	if {[string compare {} $userName] == 0} {
		return {empty username}
	}
	if [regexp {[: ]} $userName] {
		return {wrong username}
	}
	if [info exists repositoryProperties($rep,authenticatedusers)] {
# there are users with read permission for this repository
		if {[lsearch -exact $repositoryProperties($rep,authenticatedusers) $userName] == -1} {
			return {unknown username}
		}
	} else {
# there is no user with read permission for this repository
		if {![info exists environmentArray(spUseUserAuthentication)] || \
			!$environmentArray(spUseUserAuthentication)} {return}
# there are users with read permission for this local collection
	}
	set flag [CheckPassword $userName $password read]
	if {[string compare 2 $flag] == 0} {
# unknown username
		return {unknown username}
	}
	if {[string compare {} $password] == 0} {
		return {empty password}
	}
	if $flag {
# password is wrong
	return {wrong password}
	}
}

# CheckReadUsernamePassword - end
# ----------------------------------------------------------------------
# StoreRepository
# Juliana's work (not used any more)
# repName and metadataRepName values are empty or are data repository name and metadata repository name
# data value is empty or is the repository content in the coded form
# if not empty, the document name will be doc
# if empty, no document is created unless the metadataEntry contains a valid URL
# example of metadataEntry:
# {<METADATA ReferenceType="Misc"><TITLE></TITLE><AUTHOR></AUTHOR></METADATA>}
# binary values are 0 or 1; 1 means to use binary procedure (meaningless when data is empty)
## download values are dontgeturl geturldonttransfercopyright and geturltransfercopyright
# download value is yes or no

proc StoreRepository {repName data metadataRepName metadataEntry userName password {binary 1} {download yes}} {
# runs with post
	global col
	global homePath
	global URLibServiceRepository
	global inverseTable

# return [list [llength $data] [lindex $data 0] [lindex $data end]]
	if {![string equal {} $repName] && [file isdirectory $homePath/col/$repName]} {return "<repository $repName already exists>"}
	if {![string equal {} $metadataRepName] && [file isdirectory $homePath/col/$metadataRepName]} {return "<repository $metadataRepName already exists>"}

	set return [CheckUsernamePassword $userName $password {} 1 write]
	if {[string compare {} $return] != 0} {
		return $return
	}

# referenceType
#	regexp {<REFERENCE_TYPE>(.*)</REFERENCE_TYPE>} $metadataEntry m referenceType
#	regexp {^<[mM][eE][tT][aA][dD][aA][tT][aA] +[rR][eE][fF][eE][rR][eE][nN][cC][eE][tT][yY][pP][eE]="?([^>"]*)"?>} $metadataEntry m referenceType
	regexp {^ *<[mM][eE][tT][aA][dD][aA][tT][aA] +[rR][eE][fF][eE][rR][eE][nN][cC][eE][tT][yY][pP][eE]="?([^>"]*)"?>} $metadataEntry m referenceType	;# "

## inverseTable
#	set fieldList [ReturnReferModel $referenceType 1]
#	foreach field $fieldList {
#		set inverseTable([lindex $field 1]) [lindex $field 0]
#	}

# reference
	set reference [list [list %0 $referenceType]]
	set metadataEntry [string trim $metadataEntry]
	regsub {^ *<[mM][eE][tT][aA][dD][aA][tT][aA] +[rR][eE][fF][eE][rR][eE][nN][cC][eE][tT][yY][pP][eE]=[^>]*>} $metadataEntry {} metadataEntry
	regsub {</[mM][eE][tT][aA][dD][aA][tT][aA]> *$} $metadataEntry {} metadataEntry
	regsub -all {!} $metadataEntry {#%#} metadataEntry
	regsub -all {(</[^>]*>)[^<]*(<[^/][^>]*>)} $metadataEntry {\1 ! \2} metadataEntry
	foreach field [split $metadataEntry !] {
		regsub -all {#%#} $field {!} field
		regexp {<([^>]*)>([^<]*)<} $field m fieldName fieldValue
		set fieldName [string tolower $fieldName]
		lappend reference "$inverseTable($referenceType,$fieldName) $fieldValue"
		if {[string compare url $fieldName] == 0} {set url $fieldValue}
	}

# Waiting for the completion of other repository insertions
	WaitQueue StoreRepository
# Waiting for the completion of other repository insertions - end

	if [string equal {} $data] {
		set noFile 1
	} else {
		set noFile 0
		if $binary {
#			Store data $documentPath/doc	;# doesn't work
			set data [binary format c* $data]
#			Store data $documentPath/doc binary 0 w
#		} else {
#			Store data $documentPath/doc
##			Store data $documentPath/doc binary 0 w
		}
	}

	if ![info exists url] {set url {}}

	if [catch {PutDocumentOnClipboard $noFile $download $homePath $url {} data doc 0 {} [encoding system]} message] {
		foreach {message itemName} $message {break}
		LeaveQueue [pid]
		return "<$message: $itemName>"
	} else {
#		foreach {noFile getURL documentPath unzip contentType2} $message {break}
		foreach {noFile documentPath unzip contentType2} $message {break}
	}

	if {[string compare {} $documentPath] == 0} {
		set documentType empty
	} else {
		set documentType directory
	}

# CREATE
	set repName [CreateRepMetadataRep $documentType \
		$documentPath/ {} 0 enable $reference preserve $unzip 0 \
		$repName $metadataRepName $userName $contentType2]

	LeaveQueue [pid]
	return $repName
}

# StoreRepository - end
# ----------------------------------------------------------------------
# LoadRepository
# returns the repository content in the coded form
# the first list element values are 0 or 1, 0 means no error
# justMetadata values are 0 or 1
# 1 means to return just the metadata (not the data}
# 0 means to return both (data and metadata)
# outputMetadataFormat values are 0 or 1
# 1 means to return the metadata as a tcl list (one list element for one tag)
# 0 means to return the metadata as a simple string without the list struture
# binary values are 0 or 1; 1 means to use binary procedure

proc LoadRepository {metadataRepName userName password {justMetadata 0} {outputMetadataFormat 0} {binary 1}} {
# runs with post
	global homePath
	if ![file isdirectory $homePath/col/$metadataRepName/doc] {return [list 1 "repository $metadataRepName doesn't exist"]}
	set repName [ReturnRepositoryName $metadataRepName]
	if ![file isdirectory $homePath/col/$repName/doc] {return [list 1 "repository $repName doesn't exist"]}
	set return [CheckReadUsernamePassword $userName $password $repName]
	if {[string compare {} $return] != 0} {return [list 1 $return]}
# dataC
	if $justMetadata {
		set dataC {}
	} else {
		if $binary {
			Load $homePath/col/$repName/doc/doc fileContent binary
			binary scan $fileContent c* dataC
		} else {
			Load $homePath/col/$repName/doc/doc dataC
#			Load $homePath/col/$repName/doc/doc dataC binary
			set dataC [split $dataC \n]
		}
	}
	set metadata [ConvertMetadata2XML $metadataRepName-0 $outputMetadataFormat]
	return [list 0 $dataC $metadata]
}

# LoadRepository - end
# ----------------------------------------------------------------------
# ConvertMetadata2XML
# outputMetadataFormat values are 0 or 1
# 1 means to return the metadata as a tcl list (one list element for one tag)
# 0 means to return the metadata as a simple string without the list struture
# used in LoadRepository and CreateFullXMLEntry only

proc ConvertMetadata2XML {rep-i {outputMetadataFormat 0} {site {}}} {
# runs with post
	global metadataArray
#	global field::conversionTable
# referenceType
	set referenceType $metadataArray(${rep-i},referencetype)
	if $outputMetadataFormat {
		set metadata [list "\t<metadata ReferenceType=\"$referenceType\">"]
	} else {
		set metadata "<metadata ReferenceType=\"$referenceType\">"
	}
	foreach index [lsort -command FieldCompare [array names metadataArray ${rep-i},*]] {
		regsub "${rep-i}," $index {} fieldName	;# author
# drop some fields
		if [regexp {^first|^index$|^referencetype$} $fieldName] {continue}
		set fieldValue $metadataArray($index)
		regsub -all {\\} $fieldValue {\\\\} fieldValue	;# \% -> \\% - added by GJFB on 2014-05-29 otherwise \% in metadataList is displayed %
#		regsub -all {\$} $fieldValue {\$} fieldValue	;# $ -> \$ ($w$-operator)	;# commented by GJFB on 2018-06-14 - for some reason doesn't make any difference when displaying XML
		regsub -all {\&} $fieldValue {\\&amp;} fieldValue	;# & -> &amp;
# puts $fieldValue
		set fieldValue [EscapeUntrustedData $fieldValue]	;# added by GJFB on 2018-06-08 - escape untrusted data - XSS prevention
# puts $fieldValue
		if [regexp {^repository$} $fieldName] {set rep $fieldValue}
		if [regexp {^size$} $fieldName] {set size xxx}
		set pairList [CreateXMLNameValuePairs $fieldName $fieldValue $fieldName 0 1]
# puts $pairList 
		if $outputMetadataFormat {
			set metadata [concat $metadata $pairList]
		} else {
			set metadata $metadata$pairList
		}
	}
	if {[string compare {} $site] != 0 && [info exists rep] && [info exists size]} {
		if $outputMetadataFormat {
			lappend metadata \t\t<url>http://$site/rep-/$rep</url>
		} else {
			append metadata <url>http://$site/rep-/$rep</url>
		}
	}
	if $outputMetadataFormat {
		lappend metadata \t</metadata>
	} else {
		append metadata </metadata>
	}
	return $metadata
}

# ConvertMetadata2XML - end
# ----------------------------------------------------------------------
# SearchRepository
# returns a list of metadata repositories matching the search expression

proc SearchRepository {siteList query} {
# runs with post
	set metadataRepList [MultipleExecute $siteList [list list GetMetadataRepositories {} 1 $query yes yes 0]]
	set metadataRepList2 {}
	foreach index $metadataRepList {
		if ![regsub -- {-0$} $index {} siteMetadataRep] {continue}
		lappend metadataRepList2 $siteMetadataRep
	}
	return $metadataRepList2
}

# SearchRepository - end
# ----------------------------------------------------------------------
# ConfirmSubmission
# used in Submit to confirm submission to the history host
# cf. Juliana work

# not used
proc ConfirmSubmission {rep} {
	global col
	global pythonCgiScriptForHistoryCaptureRepository
	regsub -all {/} $rep {=} rep2
	if [file exists $col/$pythonCgiScriptForHistoryCaptureRepository/auxdoc/confirm/$rep2] {
#		file mkdir $col/$pythonCgiScriptForHistoryCaptureRepository/auxdoc/confirm
		set message submitted
		Store message $col/$pythonCgiScriptForHistoryCaptureRepository/auxdoc/confirm/$rep2
	}
}

# ConfirmSubmission - end
# ----------------------------------------------------------------------
# ProcessCapitalString
# type value is author or title

proc ProcessCapitalString {string {type author}} {
# set xxx $string
# Store xxx C:/tmp/bbb auto 0 a
# puts --$string--

	regsub -all {""} $string {"} string	;# "" -> " - Deteccao de ""fumagina"" -> Deteccao de "fumagina" - suppress double quotes coming from isis migration
#	if {[llength $string] <= 1} {return $string}	;# doesn't work because we get "list element in quotes followed by ":" instead of space" with: Projeto IBDF-INPE "SEQE": ano 1987
	if ![regexp { +} $string] {return $string}	;# one word string
	set capitalString [string toupper $string]
	if ![string equal $string $capitalString] {return $string}
	if [string equal author $type] {
		foreach word [split $string] {
			set word2 {}
			foreach item [split $word {-'}] {
				set item [string tolower $item]
#				if ![regexp {^de$|^da$|^of$} $item] #
				if ![regexp {^e,?$|^de,?$|^das?,?$|^dos?,?$|^of,?$} $item] {
					if [regexp {^.} $item firstLetter] {
						set firstLetter [string toupper $firstLetter]
						regsub {^.} $item $firstLetter item
					}
				}
				lappend word2 $item
			}
			set token [regexp {[-']} $word character]
			if $token {
				set word2 [join $word2 $character]
			}
			lappend string2 $word2
		}
		set string [join $string2]
	} elseif {[string equal title $type]} {
		set string [string tolower $string]
		regexp {^.} $string firstLetter
		set firstLetter [string toupper $firstLetter]
		regsub {^.} $string $firstLetter string
	}
	return $string
}

# source utilities1.tcl
# source utilities2.tcl
# puts [ProcessCapitalString {PRACTICAL PROGRAMMING} title]
# => Practical programming
# puts [ProcessCapitalString {PRACTICAL Programming} title]
# => PRACTICAL Programming
# puts [ProcessCapitalString {VICTOR HUGO}]
# => Victor Hugo
# puts [ProcessCapitalString {VICTOR-HUGO, JULIO}]
# => Victor-Hugo, Julio
# puts [ProcessCapitalString {SANT'ANA, JULIO}]
# => Sant'Ana, Julio
# puts [ProcessCapitalString {SILVA, JULIO DA}]
# => Silva, Julio da
# puts [ProcessCapitalString {SILVA, JULIO DA,}]
# => Silva, Julio da,
# puts [ProcessCapitalString {GOMES, ANA CARLA DOS SANTOS}]
# => Gomes, Ana Carla dos Santos
# puts [ProcessCapitalString {SILVA, EXCELSA TERESINHA DO MENINO JESUS DA COSTA E,}]
# => Silva, Excelsa Teresinha do Menino Jesus da Costa e,

# ProcessCapitalString -  end
# ----------------------------------------------------------------------
# Convert2OneHostPerLine

proc Convert2OneHostPerLine {accessPermission} {
	set accessPermission2 {}
	foreach line [split $accessPermission \n] {
		if [regexp {(.* +from +)(.*)} $line m permission hostList] {
			foreach host $hostList {
				lappend accessPermission2 "$permission$host"
			}
		}
	}
	return [join $accessPermission2 \n]
}

# Convert2OneHostPerLine {allow from 150.163 234}
# =>
# allow from 150.163
# allow from 234

# Convert2OneHostPerLine - end
# ----------------------------------------------------------------------
# AjustTargetFile
## called by UpdateRepMetadataRep and LoadMetadata only
# called by UpdateRepMetadataRep only
# targetFile is the new target file name or glob-expression
# targetFileOption is enable or disable (the automatic setting of target file for repositories containing just one file)

proc AjustTargetFile {rep targetFile targetFileOption} {
	global homePath
	global URLibServiceRepository

# puts "targetFile = --$targetFile--"
# puts "targetFileOption = $targetFileOption"

# set enableTrace 0
Load $homePath/col/$URLibServiceRepository/auxdoc/@enableTrace enableTrace
TraceProcedure	;# add executing time interval
TraceProcedure AjustTargetFile
TraceProcedure	;# add executing time interval
TraceProcedure [clock format [clock seconds] -format %Y:%m.%d.%H.%M.%S]
TraceProcedure [CallTrace]

	if {[TestContentType $rep {Mirror} $homePath]} {
		return mirror.cgi	;# preserve the target file (mirror.cgi) - Case 0
	}
	
	set docPath $homePath/col/$rep/doc
	set docContent ""
	DirectoryContent docContent $docPath $docPath
	if [string equal {} $targetFile] {
		if [string equal {enable} $targetFileOption] {
# enable

#			set targetFile2 {}
#		# else #
#			set docPath $homePath/col/$rep/doc
#		1	set docContent ""
#			DirectoryContent docContent $docPath $docPath
			set i 0	;# added by GJFB on 2019-12-21
			foreach file $docContent {
				if ![regexp -nocase {^\.htaccess2?$} $file] {
					incr i
					if {$i == 2} {break}
					set firstFile $file
				}
			}
#			if {[llength $docContent] == 1} #	;# commented by GJFB on 2019-12-21
			if {$i == 1} {	;# added by GJFB on 2019-12-21 to ignore the .htaccess files
#				set targetFile [join $docContent]
				set targetFile2 $firstFile	;# Case 1
			} else {	;# added by GJFB on 2019-12-23 to behave as was originally planned 
				set targetFile2 {}	;# Case 7
			}
		} else {
# disable
			set targetFile2 {}	;# Case 6
		}
	} elseif {[lsearch -exact $docContent $targetFile] != -1} {	;# added by GJFB on 2019-12-21
		set targetFile2 $targetFile	;# confirm - Case 2
	} else {
# Looking for the target file name
# example of target file: {*,*/*,*/*/*}.[pP][dD][fF]
# example of target file: {fullpaper,*/fullpaper,*/*/fullpaper}.pdf
		regsub -all {\[} $targetFile {\[} targetFile	;# added by GJFB on 2010-11-26 - othherwise glob don't regognize file name like cartaz Prof[1]. Gerald Banon 19.6.ppt
		regsub -all {\]} $targetFile {\]} targetFile	;# added by GJFB on 2010-11-26 - othherwise glob don't regognize file name like cartaz Prof[1]. Gerald Banon 19.6.ppt
# cartaz Prof[1]. Gerald Banon 19.6.ppt -> cartaz Prof\[1\]. Gerald Banon 19.6.ppt
		set encodingSystem [encoding system]	;# to preserve the current encoding system
		set fileNameList [glob -nocomplain $homePath/col/$rep/doc/$targetFile]
# puts "fileNameList = --$fileNameList--"
		if {[llength $fileNameList] == 0} {encoding system iso8859-1}	;# try iso8859-1 - solves the accent problem in md-m09, col/sid.inpe.br/md-m09/2013/07.31.14.14/doc contain files whose names were iso coded (because created under a iso Linux operating system and then migrated to an utf Linux operating system (machine change hosting the site md-m09.sid.inpe.br) - added by GJFB on 2013-08-30 - similar code as in CreateDirectoryContentList (see GJFB on 2012-08-18)
		set fileNameList [glob -nocomplain $homePath/col/$rep/doc/$targetFile]
		if {[llength $fileNameList] == 0} {encoding system utf-8}	;# try utf-8 - solves the accent problem - added by GJFB on 2013-08-30 - same code as in CreateDirectoryContentList (see GJFB on 2012-08-18)
		set fileNameList [glob -nocomplain $homePath/col/$rep/doc/$targetFile]
		if {[llength $fileNameList] == 1} {
			regsub $homePath/col/$rep/doc/ $fileNameList {} targetFile2	;# {edicoes.pdf}
			set targetFile2 [join $targetFile2]	;# edicoes.pdf - Case 3
		} else {
#			if [TestContentType $rep {Mirror}] #
#				set targetFile2 mirror.cgi	;# the name mirror.cgi must be preserved
#			# else #
			if [string equal {enable} $targetFileOption] {
# enable
				set targetFile2 {}	;# Case 4
			} else {
# disable
				set targetFile2 $targetFile	;# Case 5
			}
#			#
		}
		encoding system $encodingSystem	;# to preserve the current encoding system
# Looking for the target file name - end
	}
# puts "targetFile2 = --$targetFile2--"

TraceProcedure	;# add executing time interval
TraceProcedure {end of AjustTargetFile}

	return $targetFile2
}

# AjustTargetFile - end
# ----------------------------------------------------------------------
# MultipleArrayGet
# example: MultipleArrayGet repArray *:2007:*,citationkey
# => {{AABE:2007:AbReMu,citationkey iconet.com.br/banon/2007/11.04.16.54.01-0} {AABE:2007:AdBaCo,citationkey iconet.com.br/banon/2007/11.04.21.58.01-0}}
# used in DisplayDuplicates through MultipleExecute2

proc MultipleArrayGet {arrayName pattern} {
	upvar #0 $arrayName array
	
	set outputList {}
	foreach {name value} [array get array $pattern] {
		lappend outputList [list $name $value]
	}
	return $outputList
}

# MultipleArrayGet - end
# ----------------------------------------------------------------------
# Select
# searchExpression may be empty (== no searchExpression)
# examples
# set newExpression "au [join [Select supervisor {ref thesis}] { or au }]"
# set newExpression "[Select supervisor {ref thesis} au or]" (not implemented)
# Select repository {identifier, LK47B6Y/345LDJB}
# join [Select readpermission [list repository, $rep]]
# Select title {identifier, 3ERPFQRT3W/39M3JJS}
# => {Sistema para geração de identificador com base na Internet (IBI): Norma ABNT}

proc Select {fieldName searchExpression} {
	global searchRepository
	global multipleLineFieldNameList
	
	upvar accent accent
	upvar case case
	
	if ![info exists accent] {set accent yes}
	if ![info exists case] {set case yes}

	set output {}
# puts --[${searchRepository}::MountSearch $searchExpression $accent $case]--
	foreach item [${searchRepository}::MountSearch $searchExpression $accent $case] {
		set fieldValue [GetFieldValue $item $fieldName]
		if {[lsearch -exact $multipleLineFieldNameList $fieldName] != -1} {
# multiple line fields
			set output [concat $output $fieldValue]
		} else {
			lappend output $fieldValue
		}
	}
	return [lsort -unique $output]
}

# to test Select see dpi.inpe.br/banon/1999/04.21.17.06/doc/Search.tcl

# Select - end
# ----------------------------------------------------------------------
# Select2

# Select2 {citationkey repository} {repository, *} - see start
# Select2 repository {repository, *} - see post
# Select2 metadatarepository {repository, *} - see post
# Select2 title {identifier, 3ERPFQRT3W/39M3JJS} - just an example
# => {{Sistema para geração de identificador com base na Internet (IBI): Norma ABNT}}

# used in start and FindRepositoryNameFromIBI only
# codedPassword is to look the hidden records up
# return a list of field values (for example a list of repository names or a list of metadata repository names)

proc Select2 {fieldNameList searchExpression {codedPassword {}}} {
	global searchRepository
	global multipleLineFieldNameList
	
	upvar accent accent
	upvar case case
	
	if ![info exists accent] {set accent yes}
	if ![info exists case] {set case yes}

	set output {}
	foreach item [${searchRepository}::MountSearch $searchExpression $accent $case repArray $codedPassword] {
		set fieldValueList {}
		foreach fieldName $fieldNameList {
			lappend fieldValueList [GetFieldValue $item $fieldName]
		}
		lappend output $fieldValueList
	}
#	return [lsort -unique $output]
	return $output
}

# to test Select2 see dpi.inpe.br/banon/1999/04.21.17.06/doc/Search.tcl

# Select2 - end
# ----------------------------------------------------------------------
# Select3
# returns a list of metadata repositories whose specified field (see fieldName) is empty

# used to find repositories having a missing repository field or a missing metadatarepository field
# ex:
# set repositoryList1 [Select3 repository {repository, *} $administratorCodedPassword]
# => (empty)
# set repositoryList2 [Select3 metadatarepository {repository, *} $administratorCodedPassword]
# => sid.inpe.br/mtc-m21d/2022/05.03.13.29.52-0

# codedPassword is to look the hidden records up

proc Select3 {fieldName searchExpression {codedPassword {}}} {
	global searchRepository
	global multipleLineFieldNameList
	
	set accent yes
	set case yes

	set output {}
	foreach item [${searchRepository}::MountSearch $searchExpression $accent $case repArray $codedPassword] {
		if [string equal {} [GetFieldValue $item $fieldName]] {
			lappend output $item
		}
	}
	return $output
}

# Select3 - end
# ----------------------------------------------------------------------
# Load2
# secure version of Load
# reading is restricted to the specified repository folder content
# fileName is the file path from the specified folder
# writeUserCodedPassword is the coded password of the current write user for rep
# folder may be doc (default), auxdoc or source
# may be used implicitly in CreateTclPage
# when remotly executed via socket, the file content must consist of only one line otherwise the next lines are lost
# multipleLinesFileFlag value is 0 or 1; 1 is a faster alternative to load multiple lines file compare to MultipleLinesLoad2 
# example: see rep iconet.com.br/banon/2009/06.16.21.10, rep urlib.net/www/2019/10.29.01.58 or cgi/test2

proc Load2 {rep fileName writeUserCodedPassword {folder {doc}} {translation {auto}} {multipleLinesFileFlag 0}} {
# runs with post
	global homePath

	LoadService $rep userName userName 1 1
	if [CheckPassword $userName $writeUserCodedPassword] {return {}}	;# wrong password
	Load $homePath/col/$rep/$folder/$fileName var $translation
	if $multipleLinesFileFlag {
		return [split $var \n]	;# added by GJFB on 2019-11-20 - turns a multiple lines data into a one line data
	} else {
		return $var
	}
}

# Load2 - end
# ----------------------------------------------------------------------
# Store2
# secure version of Store
# writing is restricted to the specified repository folder content
# fileName is the file path from the specified folder
# writeUserCodedPassword is the coded password of the current write user for rep
# folder may be doc (default), auxdoc or source
# may be used implicitly in CreateTclPage (see ExecuteStore2, DisplayMultipleSearch or DisplayNumber)
## when remotly executed via socket (may be used with Execute), the file content must consist of only one line otherwise the next lines are lost
# example: see cgi/test2
# used in ExecuteStore2 (see example in id J8LNKB5R7W/3K4L4J8 - xml data creation), DisplayMultipleSearch and DisplayNumber only

proc Store2 {
	var rep fileName writeUserCodedPassword {folder {doc}} {translation {auto}}
	{nonewline 0} {access w} {force 0}
	{encodingName {}} {trialNumber 1}
} {
# runs with post
	global homePath

	LoadService $rep userName userName 1 1
	if [CheckPassword $userName $writeUserCodedPassword] {return {}}	;# wrong password - nothing done
	Store var $homePath/col/$rep/$folder/$fileName $translation $nonewline $access $force $encodingName $trialNumber
#	return $var	;# commented by GJFB on 2015-08-25 - useless
}

# Store2 - end
# ----------------------------------------------------------------------
# StoreURLContent
# url is the URL pointing to content to be stored
# fileName is the relative path from homePath

# proc StoreURLContent {url fileName} #	;# commented by GJFB on 2021-01-14
proc StoreURLContent {url fileName {encodingName {}}} {	;# added by GJFB on 2021-01-14
	global homePath
	
if 1 {
# added by GJFB on 2024-04-03
	if [string equal {} $url] {	;# url is set to empty in DisplayNumberOfEntries
		file delete $homePath/$fileName
		return
	}
}
	package require http
	file mkdir [file dirname $homePath/$fileName]
#	set fileId [open $homePath/$fileName w]	;# commented by GJFB on 2015-09-04 - otherwise spurious strings appear along the file content
	set convertedURL [ConvertURLToHexadecimal $url]
#	if [catch {http::geturl $convertedURL -channel $fileId} token] #	;# commented by GJFB on 2015-09-04 - otherwise spurious strings appear along the file content
	if [catch {http::geturl $convertedURL} token] {
		close $fileId
# Store token C:/tmp/bbb auto 0 a
		file delete $homePath/$fileName
		return "token = $token"
	} else {
#		close $fileId	;# commented by GJFB on 2015-09-04 - otherwise spurious strings appear along the file content
		set ncode [::http::ncode $token] 
		if ![string equal {200} $ncode] {
# for example 404: HTTP/1.1 404 Not Found
# for example 401: HTTP/1.1 401 Authorization Required
			file delete $homePath/$fileName
			set code [::http::code $token] 
			::http::cleanup $token	;# free memory including the array state
			return "state(http) = $code, while getting the url: $convertedURL"
		}
		set urlContent [http::data $token]	;# added by GJFB on 2015-09-04 - to avoid spurious strings to appear along the file content
		set extension [file extension $fileName]
		if [string equal {.zip} $extension] {
			Store urlContent $homePath/$fileName binary	;# added by GJFB on 2015-09-04 - to avoid spurious strings to appear along the file content - added by GJFB on 2015-12-05 - force binary because zip file are binary (otherwise, storing a zip file from m16d to m16 lead to an invalid zip file)
		} else {
#  			Store urlContent $homePath/$fileName	;# added by GJFB on 2015-09-04 - to avoid spurious strings to appear along the file content - commented # added by GJFB on 2021-01-14
			Store urlContent $homePath/$fileName auto 0 w 0 $encodingName	;# added by GJFB on 2021-01-14 - used in DisplayNumberOfEntries
		}
		http::cleanup $token
	}
}

if 0 {
# testing
# tcl 8.6 should be use instead of 8.5 under Windows when using the -channel option - otherwise spurious strings appear along the file content
	source utilities1.tcl
	source utilities2.tcl
	set homePath {C:/Users/Gerald Banon/URLib 2}
	StoreURLContent http://bibdigital.sid.inpe.br/col/sid.inpe.br/bibdigital@80/2006/04.07.15.50.13/doc/mirrorget.cgi?languagebutton=pt-BR&metadatarepository=sid.inpe.br/marciana/2003/04.30.17.29.34&index=0&serveraddress=mtc-m18.sid.inpe.br+800&choice=full xxx.html
	StoreURLContent http://gjfb.home/col/dpi.inpe.br/banon/1999/06.19.17.00/doc/mirrorget.cgi?languagebutton=pt-BR&metadatarepository=urlib.net/www/2013/11.02.01.25.29&index=0&serveraddress=gjfb.home+800&choice=full&lastupdate=2015:08.24.03.53.17+dpi.inpe.br/banon/1999/01.09.22.14+banon+{D+{}}&continue=yes&keywords=ti*+estatuto&accent=no&case=no&imageflag=0 xxx.html
	StoreURLContent http://gjfb.home/col/dpi.inpe.br/banon/1999/06.19.17.00/doc/mirrorsearch.cgi?query=ti+IBI+and+host+*+or+k+xx1&choice=full&languagebutton=pt-BR&returnbutton=no xxx2.html
}
		
# StoreURLContent - end
# ----------------------------------------------------------------------
# StoreURLContent2
# secure version of StoreURLContent
# may be used implicitly in CreateTclPage (see DisplayNumberOfEntries)
# fileName is the relative path from folder in rep of the file for storing the URL content

# proc StoreURLContent2 {url rep fileName writeUserCodedPassword {folder {doc}}} #	;# commented by GJFB on 2021-01-14
proc StoreURLContent2 {url rep fileName writeUserCodedPassword {folder {doc}} {encodingName {}}} {	;# added by GJFB on 2021-01-14 - used in DisplayNumberOfEntries
	LoadService $rep userName userName 1 1
	if [CheckPassword $userName $writeUserCodedPassword] {return {}}	;# wrong password - nothing done
#	return [StoreURLContent $url col/$rep/$folder/$fileName]	;# commented by GJFB on 2021-01-14
	return [StoreURLContent $url col/$rep/$folder/$fileName $encodingName]	;# added by GJFB on 2021-01-14
}
		
# StoreURLContent2 - end
# ----------------------------------------------------------------------
# StoreProgress
# remotly called from DisplayMultipleSearch
# progress value example is 23% (percentage of progress)
# progressKey value example is 1434823291773377 (microsecond)

proc StoreProgress {progress progressKey} {
# runs with post
	global homePath
	global URLibServiceRepository
	
	if [string equal {100%} $progress] {
		file delete $homePath/col/$URLibServiceRepository/doc/progressDir/$progressKey.txt
		file delete $homePath/col/$URLibServiceRepository/doc/progressDir/$progressKey.html
	} else {
		Store progress $homePath/col/$URLibServiceRepository/doc/progressDir/$progressKey.txt
	}
}

# StoreProgress
# ----------------------------------------------------------------------
# MultipleLinesLoad2
# multiple lines version of Load2
# returns a list of file lines
# useful when remotly executed via socket (must be used with MultipleExecute), the file content may consist in one or more lines
# for file having many lines MultipleLinesLoad2 is time consuming, in this case using Load2 with the option multipleLinesFileFlag == 1 is faster
# example: see cgi/test2

proc MultipleLinesLoad2 {rep fileName writeUserCodedPassword {folder {doc}} {translation {auto}}} {
# runs with post
	set var [Load2 $rep $fileName $writeUserCodedPassword $folder $translation]
	return [split $var \n]
}

# MultipleLinesLoad2 - end
# ----------------------------------------------------------------------
# SimplifyMetadataLists
# Update accelerator
# used in UpdateCollection and UpdateRepMetadataRep only
# example: SimplifyMetadataLists metadataList metadata2List

proc SimplifyMetadataLists {newMetadataListName oldMetadataListName} {
	upvar $newMetadataListName metadataList
	upvar $oldMetadataListName metadata2List
	
	array set newMetadataArray $metadataList
	array set oldMetadataArray $metadata2List
	foreach name [array names newMetadataArray] {
		if {[info exists oldMetadataArray($name)] && \
		[string equal $oldMetadataArray($name) $newMetadataArray($name)]} {
# simplify
# puts $name
			unset newMetadataArray($name)
			unset oldMetadataArray($name)
			if [regsub {,committee} $name {,supervisor} name2] {
# committee didn't change therefore supervisor, if any, didn't change and must not be removed from the metadata (i.e., it must not be part of oldMetadataArray)
				if [info exists oldMetadataArray($name2)] {unset oldMetadataArray($name2)}
			}
			if [regsub {,committee} $name {,firstsupervisor} name2] {
# committee didn't change therefore firstsupervisor, if any, didn't change and must not be removed from the metadata (i.e., it must not be part of oldMetadataArray)
				if [info exists oldMetadataArray($name2)] {unset oldMetadataArray($name2)}
			}
			if [regsub {,imagesize} $name {,printingresolution} name2] {
# imagesize didn't change therefore printingresolution, if any, didn't change and must not be removed from the metadata (i.e., it must not be part of oldMetadataArray)
				if [info exists oldMetadataArray($name2)] {unset oldMetadataArray($name2)}
			}
			if [regsub {,hostcollection} $name {,lasthostcollection} name2] {
# hostcollection didn't change therefore lasthostcollection, if any, didn't change and must not be removed from the metadata (i.e., it must not be part of oldMetadataArray)
				if [info exists oldMetadataArray($name2)] {unset oldMetadataArray($name2)}
			}
			if [regsub {,hostcollection} $name {,firsthostcollection} name2] {
# hostcollection didn't change therefore firsthostcollection, if any, didn't change and must not be removed from the metadata (i.e., it must not be part of oldMetadataArray)
				if [info exists oldMetadataArray($name2)] {unset oldMetadataArray($name2)}
			}
		}
	}
# puts new-[array names newMetadataArray]
# puts old-[array names oldMetadataArray]
	set metadataList [array get newMetadataArray]
	set metadata2List [array get oldMetadataArray]
}

# SimplifyMetadataLists - end
# ----------------------------------------------------------------------
# UpdateFileContainingArray
# example of global array: attributeTable
# example of input: year=2012,journal,issn,ACM_Computing_Surveys
# example of output: 0360-0300
# if input doesn't exist, then it is created and the output value is used to set the corresponding output array
# if input exists, then the output value is used to update the corresponding output array
# if the input value is empty, then the input array is unset
# filePath is the path (in the URLib collection) of a tcl file containing the array called arrayName
# example of filePath: col/dpi.inpe.br/banon-pc3/2012/02.07.15.21/doc/year=2012_journal_issn.tcl
# example of file content:
# array set attributeTable {
# 	year=2012,journal,issn,ACM_Computing_Surveys 0360-0300
# 	year=2012,journal,issn,ACM_Journal_of_Experimental_Algorithmics 1084-6654
# }

# not used yet
proc UpdateFileContainingArray {arrayName input output filePath} {
# runs with post
	global homePath
	
	source $homePath/$filePath	;# set an array called arrayName
	if [string equal {} $input] {
		if [info exists $arrayName($input)] {unset $arrayName($input)}
	} else {
		array set $arrayName($input) $output
	}
#	StoreArray attributeTable $homePath/col/$thisRepository/auxdoc/year=${year}_${mappingDomainName}_$attributeName.tcl w list array 1	;# see Administrator page for setting field value attributes
	StoreArray arrayName $homePath/$filePath w list array 1
}

# UpdateFileContainingArray - end 
# ----------------------------------------------------------------------
# GetOptimizedListOfSites
# used remotly by FindURLPropertyList, only
# used by www.urlib.net and agency resolvers

proc GetOptimizedListOfSites {ibi mirror administratorCodedPassword} {
# runs with post
	global homePath
	global serverAddress
	global loCoInRep
	global ibiToArchiveServiceArray	;# updated in UpdateIBIToArchiveServiceArray

# set xxx "[CheckPassword administrator $administratorCodedPassword]"
# Store xxx C:/tmp/bbb.txt auto 0 a

	if [CheckPassword administrator $administratorCodedPassword] {return}	;# wrong password

	Load $homePath/col/$mirror/doc/@siteList.txt fileContent
	foreach siteProtocolList [FormatSiteList $fileContent $serverAddress $loCoInRep {site loCoInRep2 archiveProtocol}] {break}
	
# set xxx --$siteProtocolList--
# Store xxx C:/tmp/bbb.txt auto 0 a
# => --{{gjfb 19050} dpi.inpe.br/banon/1999/01.09.22.14 USP} {{150.163.34.241 800} dpi.inpe.br/banon/2003/12.10.19.30 USP}--

	if {[llength $siteProtocolList] == 1} {return [list 0 $siteProtocolList]}
	
	if [info exists ibiToArchiveServiceArray($ibi)] {
		set optimizedSiteList {}
		foreach archiveServiceIBI $ibiToArchiveServiceArray($ibi) {
			foreach line $siteProtocolList {
#				foreach {serverAddress2 loCoInRep2 archiveProtocol} $line {break}
				set loCoInRep2 [lindex $line 1]
				if [string equal $archiveServiceIBI $loCoInRep2] {
					lappend optimizedSiteList $line
				}
			}
		}
		if [string equal {} $optimizedSiteList] {
# probably an Arquive has been excluded from @siteList.txt 
			set output [list 0 $siteProtocolList]
		} else {
			set output [list 1 $optimizedSiteList]
		}
	} else {
		set output [list 0 $siteProtocolList]
	}
# set xxx --$output--
# Store xxx C:/tmp/bbb.txt auto 0 a
	return $output
}

# GetOptimizedListOfSites - end
# ----------------------------------------------------------------------
# UpdateIBIToArchiveServiceArray
# used remotly by FindURLPropertyList, only
# used by www.urlib.net and agency resolvers
# the inclusion of a new ibi in the ibiToArchiveServiceArray of an agency resolver
# proves that this agency resolver is working properly (used to test licuri.ibict.br)
# Hints: the ibi url must not contain a query string for the ibi be included
# example:
# using http://urlib.net/rep/8JMKD3MGP3W34R/3R6QKJH?ibiurl.language=pt-BR the ibi 8JMKD3MGP3W34R/3R6QKJH will not be included
# using http://urlib.net/rep/8JMKD3MGP3W34R/3R6QKJH the ibi 8JMKD3MGP3W34R/3R6QKJH will be included

# array set ibiToArchiveServiceArray {
# 	CBnmVX32PXQZeBBx/Cb2ne dpi.inpe.br/banon/1999/01.09.22.14
# 	J8LNKB5R7W/3D3EHEL dpi.inpe.br/banon/1999/01.09.22.14
# 	dpi.inpe.br/banon-pc2@1905/2005/10.05.18.39 dpi.inpe.br/banon/1999/01.09.22.14
# }

# proc UpdateIBIToArchiveServiceArray {ibi archiveServiceIBI optimizedListOfSitesFailedFlag administratorCodedPassword} #	;# commented by GJFB on 2025-12-21
proc UpdateIBIToArchiveServiceArray {ibi archiveServiceIBI optimizedListOfSitesFailedFlag} {	;# added by GJFB on 2025-12-21
# runs with post
	global homePath
	global loCoInRep
	global ibiToArchiveServiceArray	;# updated in this procedure - used in GetOptimizedListOfSites only
	global numberOfCallToUpdateIBIToArchiveServiceArray
	
	if ![info exists ibiToArchiveServiceArray] {
		set numberOfCallToUpdateIBIToArchiveServiceArray 0
		if [file exists $homePath/col/$loCoInRep/auxdoc/ibiToArchiveServiceArray.tcl] {
			SourceWithBackup $homePath/col/$loCoInRep/auxdoc/ibiToArchiveServiceArray.tcl ibiToArchiveServiceArray 1	;# array set ibiToArchiveServiceArray
		}
	}
	incr numberOfCallToUpdateIBIToArchiveServiceArray
# remove	
	if $optimizedListOfSitesFailedFlag {
		if [info exists ibiToArchiveServiceArray($ibi)] {unset ibiToArchiveServiceArray($ibi)}
	}
# add
	if [info exists ibiToArchiveServiceArray($ibi)] {
		if {[lsearch $ibiToArchiveServiceArray($ibi) $archiveServiceIBI] == -1} {
			lappend ibiToArchiveServiceArray($ibi) $archiveServiceIBI	;# there may be copies
		}
	} else {
		set ibiToArchiveServiceArray($ibi) $archiveServiceIBI
	}
	
	if {$numberOfCallToUpdateIBIToArchiveServiceArray == 100} {
		StoreArrayWithBackup ibiToArchiveServiceArray $homePath/col/$loCoInRep/auxdoc/ibiToArchiveServiceArray.tcl w list
		set numberOfCallToUpdateIBIToArchiveServiceArray 0
	}
	return done
}

# UpdateIBIToArchiveServiceArray - end
# ----------------------------------------------------------------------
# UpdateURItoResolverURLArray
# created by GJFB on 2025-12-22
# used remotly only by Resolve
# example:
#	http://gjfb:1905/upn:9HFNHE:J8LNKB5R7W/3PGRQD8

# array set uriToResolverURLArray {
# 	upn:9HFNHE:J8LNKB5R7W/3PGRQD8 http://gjfb:1905
#	upn:35SP775:8JMKD3MGP7W/36U89RH http://mtc-m21c.sid.inpe.br
# }

# do not confuse uriToResolverURLArray with namespacePrefixXresolverURLArray (see http://www.urlib.net/ibi:QABCDSTQQW/4E7MG35)

proc UpdateURItoResolverURLArray {uri resolverURL} {
# runs with post
	global homePath
	global loCoInRep
	global uriToResolverURLArray	;# updated in this procedure
	global numberOfCallToUpdateURItoResolverURLArray	;# just used in this procedure
	
	if ![info exists uriToResolverURLArray] {
		set numberOfCallToUpdateURItoResolverURLArray 0
		if [file exists $homePath/col/$loCoInRep/auxdoc/uriToResolverURLArray.tcl] {
			SourceWithBackup $homePath/col/$loCoInRep/auxdoc/uriToResolverURLArray.tcl uriToResolverURLArray 1	;# array set uriToResolverURLArray
		}
	}
	incr numberOfCallToUpdateURItoResolverURLArray
	
	if [string equal {} $resolverURL] {
# remove
		if [info exists uriToResolverURLArray($uri)] {unset uriToResolverURLArray($uri)}		
	} else {
# update	
		set seconds [clock seconds]
		set uriToResolverURLArray($uri) [list $resolverURL $seconds]
	}
	
	if {$numberOfCallToUpdateURItoResolverURLArray == 100} {
		StoreArrayWithBackup uriToResolverURLArray $homePath/col/$loCoInRep/auxdoc/uriToResolverURLArray.tcl w list
		set numberOfCallToUpdateURItoResolverURLArray 0
	}
	return done
}

# UpdateURItoResolverURLArray - end
# ----------------------------------------------------------------------
# GetLastSuccessfulResolverURL
# created by GJFB on 2025-12-22
# called only by Resolve

# array set uriToResolverURLArray {
# 	upn:9HFNHE:J8LNKB5R7W/3PGRQD8 http://gjfb:1905
# }

proc GetLastSuccessfulResolverURL {uri} {
	global uriToResolverURLArray
	
	if [info exists uriToResolverURLArray($uri)] {
		return $uriToResolverURLArray($uri)
	} else {
		return
	}
}

# GetLastSuccessfulResolverURL - end
# ----------------------------------------------------------------------
