#!/bin/sh  
# \
  exec oagwish "$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 apsttk 1

APSApplication . -name "4-Motor GSM Actuator Statistics"


proc SetupGUI {} {
    global status allowedDiff
    set status "Ready..."
    APSScrolledStatus .status \
      -parent .userFrame \
      -textVariable status \
      -withButtons 1 \
      -height 20 \
      -packOption "-fill both -expand true"
    

    ttk::frame .userFrame.df
    pack .userFrame.df -fill x -padx 2 -pady 5

    set allowedDiff 1.0
    ttk::label .userFrame.df.label -text "Maximum allowed encoder difference (mm): "
    ttk::entry .userFrame.df.entry -textvariable allowedDiff

    pack .userFrame.df.label -side left
    pack .userFrame.df.entry -side left -fill x

    ttk::label .tflabel -text "Time Frame"
    ttk::labelframe .userFrame.tf -labelwidget .tflabel
    pack .userFrame.tf -fill x

    if [catch {sdds open /home/helios/oagData/sr/runHistory/runFile} fd] {
	SetFillReviewStatus "error: $fd (ListRuns)"
	bell
	return
    }
    global runStartTimes runEndTimes runList
    set runStartTimes [APSGetSDDSColumn -sddsFD $fd -column StartRun]
    set runEndTimes [APSGetSDDSColumn -sddsFD $fd -column EndRun]
    set runList [APSGetSDDSColumn -sddsFD $fd -column RunName]
    catch {sdds close $fd}
    global runNameList runStart runEnd
    set runNameList Undefined
    set lastEnd ""
    foreach rst $runStartTimes ret $runEndTimes rl $runList {
        if {$rst >= 1355983199.0} {
            lappend runNameList $rl
            if {$lastEnd != ""} {
                if {[clock format [expr int($lastEnd)] -format %T] == "00:00:00"} {
                    set rst $lastEnd
                } else {
                    set rst [expr $lastEnd + 3600]
                }
            }
            set lastEnd $ret
            if {[clock format [expr int($ret)] -format %T] == "00:00:00"} {
                set ret [expr $ret - 1]
            }
            set runStart($rl) $rst
            set runEnd($rl) $ret
        }
    }



    global StartTextDay StartDay StartTextMonth StartYear StartTime
    global EndTextDay EndDay EndTextMonth EndYear EndTime

    spinbox .userFrame.tf.fromtextday -values "Mon Tue Wed Thu Fri Sat Sun" \
      -width 3 -wrap true -textvariable StartTextDay \
      -command {TimeAdjusted Start %W %s %d} -bg white
    grid .userFrame.tf.fromtextday -row 1 -column 3 -sticky w
    spinbox .userFrame.tf.fromday -from 1 -to 31 -width 2 -wrap true \
      -textvariable StartDay \
      -validate key -vcmd {string is integer %P} \
      -command {TimeAdjusted Start %W %s %d} -bg white
    grid .userFrame.tf.fromday -row 1 -column 4 -sticky w
    spinbox .userFrame.tf.frommonth \
      -values "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" \
      -width 3 -wrap true -textvariable StartTextMonth \
      -command {TimeAdjusted Start %W %s %d} -bg white
    grid .userFrame.tf.frommonth -row 1 -column 5 -sticky w
    spinbox .userFrame.tf.fromyear -from 1900 -to 2100 -width 4 -wrap true \
      -textvariable StartYear \
      -validate key -vcmd {string is integer %P} \
      -command {TimeAdjusted Start %W %s %d} -bg white
    grid .userFrame.tf.fromyear -row 1 -column 6 -sticky w    

    bind .userFrame.tf.fromtextday <Return> "TimeAdjustedManually"
    bind .userFrame.tf.fromday <Return> "TimeAdjustedManually"
    bind .userFrame.tf.frommonth <Return> "TimeAdjustedManually"
    bind .userFrame.tf.fromyear <Return> "TimeAdjustedManually"
    set s [clock scan "1/1/2015"]
    set StartTextDay [clock format $s -format %a]
    set StartDay [clock format $s -format %d]
    set StartTextMonth [clock format $s -format %b]
    set StartYear [clock format $s -format %Y]
    set StartTime [clock scan "$StartDay $StartTextMonth $StartYear"]

    spinbox .userFrame.tf.totextday -values "Mon Tue Wed Thu Fri Sat Sun" \
      -width 3 -wrap true -textvariable EndTextDay \
      -command {TimeAdjusted End %W %s %d} -bg white
    grid .userFrame.tf.totextday -row 2 -column 3 -sticky w
    spinbox .userFrame.tf.today -from 1 -to 31 -width 2 -wrap true \
      -textvariable EndDay \
      -validate key -vcmd {string is integer %P} \
      -command {TimeAdjusted End %W %s %d} -bg white
    grid .userFrame.tf.today -row 2 -column 4 -sticky w
    spinbox .userFrame.tf.tomonth \
      -values "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec" \
      -width 3 -wrap true -textvariable EndTextMonth \
      -command {TimeAdjusted End %W %s %d} -bg white
    grid .userFrame.tf.tomonth -row 2 -column 5 -sticky w
    spinbox .userFrame.tf.toyear -from 1900 -to 2100 -width 4 -wrap true \
      -textvariable EndYear \
      -validate key -vcmd {string is integer %P} \
      -command {TimeAdjusted End %W %s %d} -bg white
    grid .userFrame.tf.toyear -row 2 -column 6 -sticky w

    bind .userFrame.tf.totextday <Return> "TimeAdjustedManually"
    bind .userFrame.tf.today <Return> "TimeAdjustedManually"
    bind .userFrame.tf.tomonth <Return> "TimeAdjustedManually"
    bind .userFrame.tf.toyear <Return> "TimeAdjustedManually"
    set s [clock seconds]
    set EndTextDay [clock format $s -format %a]
    set EndDay [clock format $s -format %d]
    set EndTextMonth [clock format $s -format %b]
    set EndYear [clock format $s -format %Y]
    set EndTime [clock scan "$EndTextMonth $EndDay 23:59:59 $EndYear"]

    button .userFrame.tf.last24 -text "Last 24 Hours" -command "AdjustTimeFrame -option 1day" -pady 0
    grid .userFrame.tf.last24 -row 1 -column 7 -sticky ew -padx 2
    button .userFrame.tf.forward1day -text "Forward 1 Day" -command "AdjustTimeFrame -option 1plus" -pady 0
    grid .userFrame.tf.forward1day -row 1 -column 8 -sticky ew
    button .userFrame.tf.lastweek -text "Last 7 Days" -command "AdjustTimeFrame -option 7days" -pady 0
    grid .userFrame.tf.lastweek -row 2 -column 7 -sticky ew -padx 2
    button .userFrame.tf.backward1day -text "Backward 1 Day" -command "AdjustTimeFrame -option 1minus" -pady 0
    grid .userFrame.tf.backward1day -row 2 -column 8 -sticky ew

    APSButton .run -parent .userFrame \
      -text "Plot Encoder Differences" -width "" \
      -command {CombineFiles}
    APSButton .export -parent .userFrame \
      -text "Export Suspect Encoder Data" -width "" \
      -command {CombineFiles -export 1}
}

proc SelectRun {} {
    global selectedRun runStart runEnd
    global StartTextDay StartDay StartTextMonth StartYear StartTime
    global EndTextDay EndDay EndTextMonth EndYear EndTime
    
    if {$selectedRun == "Undefined"} {return}

    set s [expr int($runStart($selectedRun))]
    set StartTextDay [clock format $s -format %a]
    set StartDay [clock format $s -format %d]
    set StartTextMonth [clock format $s -format %b]
    set StartYear [clock format $s -format %Y]
    set StartTime [clock scan "$StartDay $StartTextMonth $StartYear"]
    set s [expr int($runEnd($selectedRun))]
    set EndTextDay [clock format $s -format %a]
    set EndDay [clock format $s -format %d]
    set EndTextMonth [clock format $s -format %b]
    set EndYear [clock format $s -format %Y]
    set EndTime [clock scan "$EndTextMonth $EndDay 23:59:59 $EndYear"]

}


proc AdjustTimeFrame {args} {
    APSStrictParseArguments {option}
    global StartTextDay StartDay StartTextMonth StartYear StartTime
    global EndTextDay EndDay EndTextMonth EndYear EndTime
    set s [clock seconds]
    if {($option == "1day") || ($option == "7days")} {
	set EndTextDay [clock format $s -format %a]
	set EndDay [clock format $s -format %d]
	set EndTextMonth [clock format $s -format %b]
	set EndYear [clock format $s -format %Y]
	set EndTime [clock scan "$EndTextMonth $EndDay 23:59:59 $EndYear"]
	if  {$option == "1day"} {
	    set s [expr $s - 60 * 60 * 24]
	} else {
	    set s [expr $s - 60 * 60 * 24 * 7]
	}
	set StartTextDay [clock format $s -format %a]
	set StartDay [clock format $s -format %d]
	set StartTextMonth [clock format $s -format %b]
	set StartYear [clock format $s -format %Y]
	set StartTime [clock scan "$StartTextMonth $StartDay 00:00:00 $StartYear"]
    } elseif {($option == "1plus") || ($option == "1minus")} {
	foreach var "Start End" {
	    if {$option == "1plus"} {
		incr ${var}Time [expr 60 * 60 * 24]
	    } else {
		incr ${var}Time [expr -60 * 60 * 24]
	    }
	    set ${var}TextDay [clock format [set ${var}Time] -format %a]
	    set ${var}Day [clock format [set ${var}Time] -format %d]
	    set ${var}TextMonth [clock format [set ${var}Time] -format %b]
	    set ${var}Year [clock format [set ${var}Time] -format %Y]
	}
    }
}
proc TimeAdjustedManually {args} {
    foreach var "Start End" {
        global ${var}TextDay ${var}Day ${var}TextMonth ${var}Year ${var}Time
        if {$var == "End"} {
	    set ${var}Time [clock scan "[set ${var}TextMonth] [set ${var}Day] 23:59:59 [set ${var}Year]"]
	} else {
	    set ${var}Time [clock scan "[set ${var}Day] [set ${var}TextMonth] [set ${var}Year]"]
	}
        set ${var}TextDay [clock format [set ${var}Time] -format %a]
        set ${var}Day [clock format [set ${var}Time] -format %d]
        set ${var}TextMonth [clock format [set ${var}Time] -format %b]
        set ${var}Year [clock format [set ${var}Time] -format %Y]
    }
}

proc TimeAdjusted {var widget value direction} {
    global ${var}TextDay ${var}Day ${var}TextMonth ${var}Year ${var}Time

    if {[lsearch -glob [lindex [split $widget .] end] "*textday"] != -1} {
        if {$direction == "up"} {
            set direction "+"
        } else {
            set direction "-"
        }
        set ${var}Time [expr "[set ${var}Time] $direction (24 * 60 * 60)"]
        set initTextDay [set ${var}TextDay]
        set ${var}TextDay [clock format [set ${var}Time] -format %a]
        if {$initTextDay != [set ${var}TextDay]} {
            #This is needed for the transition to daylight savings time.
            set ${var}Time [expr "[set ${var}Time] $direction (1 * 60 * 60)"]
            set ${var}TextDay [clock format [set ${var}Time] -format %a]
        }
        set ${var}Day [clock format [set ${var}Time] -format %d]
        set ${var}TextMonth [clock format [set ${var}Time] -format %b]
        set ${var}Year [clock format [set ${var}Time] -format %Y]
    } elseif {[lsearch -glob [lindex [split $widget .] end] "*day"] != -1} {
        if {$direction == "up"} {
            set direction "+"
        } else {
            set direction "-"
        }
        set ${var}Time [expr "[set ${var}Time] $direction (24 * 60 * 60)"]
        set initTextDay [set ${var}TextDay]
        set ${var}TextDay [clock format [set ${var}Time] -format %a]
        if {$initTextDay == [set ${var}TextDay]} {
            #This is needed for the transition to daylight savings time.
            set ${var}Time [expr "[set ${var}Time] $direction (1 * 60 * 60)"]
            set ${var}TextDay [clock format [set ${var}Time] -format %a]
        }
        set ${var}Day [clock format [set ${var}Time] -format %d]
        set ${var}TextMonth [clock format [set ${var}Time] -format %b]
        set ${var}Year [clock format [set ${var}Time] -format %Y]
    } elseif {[lsearch -glob [lindex [split $widget .] end] "*month"] != -1} {
        set month [clock format [set ${var}Time] -format %b]
        set year [clock format [set ${var}Time] -format %Y]
        set s1 [clock scan "$month 01 00:00:00 $year"]
        if {$direction == "up"} {
            if {$month == "Dec"} {
                incr year
            }
        } else {
            if {$month == "Jan"} {
                incr year -1
            }
        }
        set s2 [clock scan "[set ${var}TextMonth] 01 00:00:00 $year"]
        set s [expr {$s2 - $s1 + (60 * 60)}]
        set ${var}Time [expr "[set ${var}Time] + $s"]
        while {[set ${var}TextMonth] != [clock format [set ${var}Time] -format %b]} {
            if {$month == [clock format [set ${var}Time] -format %b]} {
                if {$direction == "up"} {
                    set ${var}Time [expr "[set ${var}Time] + (12 * 60 * 60)"]
                } else {
                    set ${var}Time [expr "[set ${var}Time] - (12 * 60 * 60)"]
                }
            } else {
                if {$direction == "up"} {
                    set ${var}Time [expr "[set ${var}Time] - (12 * 60 * 60)"]
                } else {
                    set ${var}Time [expr "[set ${var}Time] + (12 * 60 * 60)"]
                }
            }
        }
        set ${var}TextDay [clock format [set ${var}Time] -format %a]
        set ${var}Day [clock format [set ${var}Time] -format %d]
        set ${var}TextMonth [clock format [set ${var}Time] -format %b]
        set ${var}Year [clock format [set ${var}Time] -format %Y]
    } elseif {[lsearch -glob [lindex [split $widget .] end] "*year"] != -1} {
        if {([set ${var}Day] == "29") && ([set ${var}TextMonth] == "Feb")} {
            set ${var}Day 28
        }
        set ${var}Time [clock scan "[set ${var}Day] [set ${var}TextMonth] [set ${var}Year]"]
        set ${var}TextDay [clock format [set ${var}Time] -format %a]
    }
    if {$var == "End"} {
	set ${var}Time [clock scan "[set ${var}TextMonth] [set ${var}Day] 23:59:59 [set ${var}Year]"]
    } else {
	set ${var}Time [clock scan "[set ${var}Day] [set ${var}TextMonth] [set ${var}Year]"]
    }
}

proc CombineFiles {args} {
    set export 0
    APSStrictParseArguments {export}

    
    global status allowedDiff

    global StartTime EndTime StartYear EndYear
    set startMonth [clock format $StartTime -format %N]
    set endMonth [clock format $EndTime -format %N]

    
    set tmpfile1 [APSTmpDir]/[APSTmpString]
    set tmpfile2 ${tmpfile1}.2
    set tmpfile3 ${tmpfile1}.3
    if {$export} {
        set exportFile [APSTmpDir]/4MotorGSMActuators.sdds
        set exportFileList ""
    }
    for {set sector 1} {$sector <= 35} {incr sector} {
        set s [format %02d $sector]
        foreach type "us:USB us:UST us:DSB us:DST ds:USB ds:UST ds:DSB ds:DST" {
            if {[file exists /home/helios/oagData/logging/64/ID${s}${type}GurleyEncoder]} {
                set gurley 1
            } else {
                set gurley 0
            }
            if {[file exists /home/helios/oagData/logging/64/ID${s}${type}LinearEncoder]} {
                set linear 1
            } else {
                set linear 0
            }
            if {[file exists /home/helios/oagData/logging/64/ID${s}${type}RotaryEncoder]} {
                set rotary 1
            } else {
                set rotary 0
            }
            if {$rotary && $gurley} {

                set frotary ""
                set pv1 ID${s}${type}RotaryEncoder
                for {set year $StartYear} {$year <= $EndYear} {incr year} {
                    for {set month 1} {$month <= 12} {incr month} {
                        set m [format %02d $month]
                        if {($year == $StartYear) && ($month < $startMonth)} {
                            continue
                        }
                        if {($year == $EndYear) && ($month > $endMonth)} {
                            continue
                        }
                        append frotary " [glob -nocomplain /home/helios/oagData/logging/64/${pv1}/log-${year}-${m}.xz /home/helios/oagData/logging/64/${pv1}/log-${year}-${m}.????]"
                    }
                }

                set fgurley ""
                set pv2 ID${s}${type}GurleyEncoder
                for {set year $StartYear} {$year <= $EndYear} {incr year} {
                    for {set month 1} {$month <= 12} {incr month} {
                        set m [format %02d $month]
                        if {($year == $StartYear) && ($month < $startMonth)} {
                            continue
                        }
                        if {($year == $EndYear) && ($month > $endMonth)} {
                            continue
                        }
                        append fgurley " [glob -nocomplain /home/helios/oagData/logging/64/${pv2}/log-${year}-${m}.xz /home/helios/oagData/logging/64/${pv2}/log-${year}-${m}.????]"
                    }
                }
                if {[llength $frotary] == 0} {continue}
                if {[llength $fgurley] == 0} {continue}

                if {[catch {eval exec sddscombine $frotary -pipe=out -merge -majororder=column | sddsprocess -pipe -filter=column,CAerrors,-.5,.5 -filter=column,Time,${StartTime},${EndTime} | sddssort -pipe -col=Time | sddsconvert -pipe=in $tmpfile1 -delete=column,CAerrors} results]} {
                    APSSetVarAndUpdate status "Error1: $results"
                    return
                }
                if {[catch {eval exec sddscombine $fgurley -pipe=out -merge -majororder=column | sddsprocess -pipe -filter=column,CAerrors,-.5,.5 -filter=column,Time,${StartTime},${EndTime} | sddssort -pipe -col=Time | sddsconvert -pipe=in $tmpfile2 -delete=column,CAerrors} results]} {
                    APSSetVarAndUpdate status "Error2: $results"
                    return
                }
                if {[catch {exec sddsxref $tmpfile1 $tmpfile2 -pipe=out -equate=Time -take=$pv2 | sddsprocess -pipe=in $tmpfile3 "-define=column,Diff,i_row &${pv1} \[ i_row &${pv2} \[ - abs"} results]} {
                    APSSetVarAndUpdate status "Error3: $results"
                    return
                }
                file delete $tmpfile1 $tmpfile2
                if {[catch {exec sddsprocess $tmpfile3 -pipe=out -process=Diff,max,Max | sdds2stream -pipe=in -para=Max} results]} {
                    APSSetVarAndUpdate status "Error4: $results"
                    return
                }
                if {$results > $allowedDiff} {
                    APSAddToTempFileList $tmpfile3
                    set status "ID${s}${type} Rotary and Gurley encoder differences found"
                    update
                    if {$export} {
                        lappend exportFileList $tmpfile3
                    } else {
                        exec sddsplot -topline=ID${s}${type} -sep=page -split=page -graph=line,vary -legend -tick=xtime $tmpfile3 "-col=Time,(${pv1},${pv2})" -legend=edit=10d -yScalesGroup=ID=one "-col=Time,(Diff)" -legend -yScalesGroup=ID=two &
                    }
                    set tmpfile3 [APSTmpDir]/[APSTmpString]
                    continue
                } else {
                    file delete $tmpfile3
                    set status "ID${s}${type} PASS"
                    update
                }
            }
            if {$rotary && $linear} {

                set frotary ""
                set pv1 ID${s}${type}RotaryEncoder
                for {set year $StartYear} {$year <= $EndYear} {incr year} {
                    for {set month 1} {$month <= 12} {incr month} {
                        set m [format %02d $month]
                        if {($year == $StartYear) && ($month < $startMonth)} {
                            continue
                        }
                        if {($year == $EndYear) && ($month > $endMonth)} {
                            continue
                        }
                        append frotary " [glob -nocomplain /home/helios/oagData/logging/64/${pv1}/log-${year}-${m}.xz /home/helios/oagData/logging/64/${pv1}/log-${year}-${m}.????]"
                    }
                }

                set flinear ""
                set pv2 ID${s}${type}LinearEncoder
                for {set year $StartYear} {$year <= $EndYear} {incr year} {
                    for {set month 1} {$month <= 12} {incr month} {
                        set m [format %02d $month]
                        if {($year == $StartYear) && ($month < $startMonth)} {
                            continue
                        }
                        if {($year == $EndYear) && ($month > $endMonth)} {
                            continue
                        }
                        append flinear " [glob -nocomplain /home/helios/oagData/logging/64/${pv2}/log-${year}-${m}.xz /home/helios/oagData/logging/64/${pv2}/log-${year}-${m}.????]"
                    }
                }
                if {[llength $frotary] == 0} {continue}
                if {[llength $flinear] == 0} {continue}

                if {[catch {eval exec sddscombine $frotary -pipe=out -merge -majororder=column | sddsprocess -pipe -filter=column,CAerrors,-.5,.5 -filter=column,Time,${StartTime},${EndTime} | sddssort -pipe -col=Time | sddsconvert -pipe=in $tmpfile1 -delete=column,CAerrors} results]} {
                    APSSetVarAndUpdate status "Error1: $results"
                    return
                }
                if {[catch {eval exec sddscombine $flinear -pipe=out -merge -majororder=column | sddsprocess -pipe -filter=column,CAerrors,-.5,.5 -filter=column,Time,${StartTime},${EndTime} | sddssort -pipe -col=Time | sddsconvert -pipe=in $tmpfile2 -delete=column,CAerrors} results]} {
                    APSSetVarAndUpdate status "Error2: $results"
                    return
                }
                if {[catch {exec sddsxref $tmpfile1 $tmpfile2 -pipe=out -equate=Time -take=$pv2 | sddsprocess -pipe=in $tmpfile3 "-define=column,Diff,i_row &${pv1} \[ i_row &${pv2} \[ - abs"} results]} {
                    APSSetVarAndUpdate status "Error3: $results"
                    return
                }
                file delete $tmpfile1 $tmpfile2
                if {[catch {exec sddsprocess $tmpfile3 -pipe=out -process=Diff,max,Max | sdds2stream -pipe=in -para=Max} results]} {
                    APSSetVarAndUpdate status "Error4: $results"
                    return
                }
                if {$results > $allowedDiff} {
                    APSAddToTempFileList $tmpfile3
                    set status "ID${s}${type} Rotary and Linear encoder differences found"
                    update
                    if {$export} {
                        lappend exportFileList $tmpfile3
                    } else {
                        exec sddsplot -topline=ID${s}${type} -sep=page -split=page -graph=line,vary -tick=xtime $tmpfile3 "-col=Time,(${pv1},${pv2})" -legend=edit=10d -yScalesGroup=ID=one "-col=Time,(Diff)" -legend -yScalesGroup=ID=two &
                    }
                    set tmpfile3 [APSTmpDir]/[APSTmpString]
                } else {
                    file delete $tmpfile3
                    set status "ID${s}${type} PASS"
                    update
                }
            }
        }
    }
    if {$export} {
        if {[llength $exportFileList] == 1} {
            if {[catch {exec sddsconvert $exportFileList $exportFile -delete=column,Diff -nowarn -ascii} results]} {
                APSSetVarAndUpdate status "Error: $results"
                return
            }
            set status "Data exported to $exportFile"
            update
            catch {exec sddsedit $exportFile &}
        } elseif {[llength $exportFileList] > 1} {
            file copy -force [lindex $exportFileList 0] $exportFile
            for {set j 1} {$j < [llength $exportFileList]} {incr j} {
                if {[catch {exec sddsxref $exportFile [lindex $exportFileList $j] -equate=Time "-leave=Time,Diff" -nowarn} results]} {
                    APSSetVarAndUpdate status "Error: $results"
                    return
                }
            }
            if {[catch {exec sddsconvert $exportFile -delete=column,Diff -nowarn -ascii} results]} {
                APSSetVarAndUpdate status "Error: $results"
                return
            }
            set status "Data exported to $exportFile"
            update
            catch {exec sddsedit $exportFile &}
        } else {
            set status "No data to export"
            update
        }
    }
    set status "Done"
    update
}



SetupGUI
AdjustTimeFrame -option 7days
