#!/bin/sh
# \
exec oagtclsh "$0" "$@"

set auto_path [linsert $auto_path 0 /usr/local/oag/apps/lib/$env(HOST_ARCH)]
set auto_path [linsert $auto_path 0 /usr/local/oag/lib_patch/$env(HOST_ARCH)]

set usage "makeElementNamingTable -twissFile <filename> -sectorEndElement <element-name> -elementSubsTableFile <filename> -guiListFile <filename> \[-makeBpmNamesUnique 1\]"

set args $argv
set twissFile ""
set sectorEndElement ""
set elementSubsTableFile ""
set guiListFile ""
set makeBpmNamesUnique 0
APSParseArguments {twissFile sectorEndElement elementSubsTableFile guiListFile makeBpmNamesUnique}
if {![string length $twissFile] || ![string length $sectorEndElement] \
	|| ![string length $elementSubsTableFile] || ![string length $guiListFile]} {
    puts stderr $usage
    exit
}

set deleteFiles ""
set sectorPref S

#------ Read elements from twiss file:

set ignoreOccurence 1
set tmpRoot aaa
if [catch {open $elementSubsTableFile w} fid] {
    puts stderr "Error opening file for writing: $fid"
    exit
}

#------ Quads treated separately to find skew quads:

#------ Need to remember that in LOCO GUI both quads and skew quads are shown on "Quads" tab,
#------ and only quads are shown on Tilts tab. Inside LOCO program, Tilts are called Skew (historically)

set varType Quad
if ![info exists paramFile] {set paramFile [file root $twissFile].param}
if ![file exists $paramFile] {puts stderr "Error: $paramFile does not exist."; exit}
exec sddsprocess $paramFile $tmpRoot.tilts -match=col,ElementType=*QUAD* -match=col,ElementParameter=TILT 
exec sddsprocess $twissFile -pipe=out \
    "-match=col,ElementType=*QUAD*,ElementName=$sectorEndElement,|" \
    | sddsxref -pipe=in $tmpRoot.tilts $tmpRoot.$varType -take=ParameterValue -match=ElementName -fillIn -rename=col,ParameterValue=Tilt -nowarning
lappend deleteFiles $tmpRoot.$varType $tmpRoot.tilts
set elementNameList [exec sdds2stream $tmpRoot.$varType -col=ElementName]
set elementOccurList [exec sdds2stream $tmpRoot.$varType -col=ElementOccurence]
set tiltList [exec sdds2stream $tmpRoot.$varType -col=Tilt]

#------ Doing non-skew quads:
set elemIndex 1
set sectorIndex 1
set numberPerSector 0
set elementSuffix Q
foreach element $elementNameList occurence $elementOccurList tilt $tiltList {
    if [string match $sectorEndElement $element] {
	if {$numberPerSector < [expr $elemIndex - 1]} {
	    set numberPerSector [expr $elemIndex - 1]
	}
	incr sectorIndex
	set elemIndex 1
    } else {
	if {$tilt == 0} {
	    if {!$ignoreOccurence || $occurence == 1} {
		set Quad($sectorPref$sectorIndex$elementSuffix$elemIndex) $element
		puts $fid "set Quad($sectorPref$sectorIndex$elementSuffix$elemIndex) $element"
		set Skew($sectorPref$sectorIndex$elementSuffix$elemIndex) $element
		puts $fid "set Skew($sectorPref$sectorIndex$elementSuffix$elemIndex) $element"
		incr elemIndex
	    }
	}
    }
}
set quadNumberPerSector $numberPerSector
#------ Doing skew quads:
set elemIndex 1
set sectorIndex 1
set numberPerSector 0
set elementSuffix SQ
foreach element $elementNameList occurence $elementOccurList tilt $tiltList {
    if [string match $sectorEndElement $element] {
	if {$numberPerSector < [expr $elemIndex - 1]} {
	    set numberPerSector [expr $elemIndex - 1]
	}
	incr sectorIndex
	set elemIndex 1
    } else {
	if {$tilt != 0} {
	    if {!$ignoreOccurence || $occurence == 1} {
		set Quad($sectorPref$sectorIndex$elementSuffix$elemIndex) $element
		puts $fid "set Quad($sectorPref$sectorIndex$elementSuffix$elemIndex) $element"
		incr elemIndex
	    }
	}
    }
}
set skewNumberPerSector $numberPerSector
set elementNumbers(Quad) [expr $quadNumberPerSector + $skewNumberPerSector]

#------ Non-quad elements:
set elementTypeList [list HKICK VKICK *MON* *MON* *SEX*]
set varTypeList [list HCorr VCorr HBPM VBPM Sext]
set elementSuffixList [list H V P P S]
if $makeBpmNamesUnique {
    set elementEndList [list "" "" "X" "Y" ""]
} else {
    set elementEndList [list "" "" "" "" ""]
}
foreach elementType $elementTypeList varType $varTypeList elementSuffix $elementSuffixList elementEnd $elementEndList {
    exec sddsprocess $twissFile $tmpRoot.$varType \
	"-match=col,ElementType=$elementType,ElementName=$sectorEndElement,|"
    lappend deleteFiles $tmpRoot.$varType
    set elementNameList [exec sdds2stream $tmpRoot.$varType -col=ElementName]
    set elementOccurList [exec sdds2stream $tmpRoot.$varType -col=ElementOccurence]

    set elemIndex 1
    set sectorIndex 1
    set numberPerSector 0
    foreach element $elementNameList occurence $elementOccurList {
	if [string match $sectorEndElement $element] {
	    if {$numberPerSector < [expr $elemIndex - 1]} {
		set numberPerSector [expr $elemIndex - 1]
	    }
	    incr sectorIndex
	    set elemIndex 1
	} else {
	    if $ignoreOccurence {
		if {$occurence == 1} {
		    set ${varType}($sectorPref$sectorIndex$elementSuffix$elemIndex) $element
		    puts $fid "set ${varType}($sectorPref$sectorIndex$elementSuffix$elemIndex$elementEnd) $element$elementEnd"
		    incr elemIndex
		}
	    } else {
		puts $fid "set ${varType}($sectorPref$sectorIndex$elementSuffix$elemIndex$elementEnd) $element$elementEnd"
		incr elemIndex
	    }
	}
    }
    set elementNumbers(${varType}) $numberPerSector
}
set elementNumbers(sectors) [expr $sectorIndex - 1]
close $fid

#------ Create lists for GUI:

if [catch {open $guiListFile w} fid1] {
    puts stderr "Error opening file for writing: $fid"
    exit
}

set sectorList ""
for {set i 1} {$i <= $elementNumbers(sectors)} {incr i} {
    lappend sectorList $sectorPref$i
}
puts $fid1 "set sectorList \{$sectorList\}"
#------ Doing quads:
set QuadSufList ""
set SkewSufList ""
for {set i 1} {$i <= $quadNumberPerSector} {incr i} {
    lappend QuadSufList Q$i
    lappend SkewSufList Q$i
}
for {set i 1} {$i <= $skewNumberPerSector} {incr i} {
    lappend QuadSufList SQ$i
}
puts $fid1 "set QuadSufList \{$QuadSufList\}"
puts $fid1 "set SkewSufList \{$SkewSufList\}"

#------ Doing non-quads:
foreach varType $varTypeList elementSuffix $elementSuffixList {
    set ${varType}SufList ""
    for {set i 1} {$i <= $elementNumbers($varType)} {incr i} {
	lappend ${varType}SufList $elementSuffix$i
    }
    puts $fid1 "set ${varType}SufList \{[set ${varType}SufList]\}"
}

#------ Create missing element lists:
foreach varType [concat Quad Skew $varTypeList] {
    set ${varType}sMissing ""
    for {set sectorIndex 1} {$sectorIndex <= $elementNumbers(sectors)} {incr sectorIndex} {
	foreach suffix [set ${varType}SufList] {
	    set element $sectorPref$sectorIndex$suffix
	    if ![info exists ${varType}($element)] {
		lappend ${varType}sMissing $element
	    }
	}
    }
    puts $fid1 "set ${varType}sMissing \{[set ${varType}sMissing]\}"
}
close $fid1

eval file delete $deleteFiles

