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

#
# $Log: not supported by cvs2svn $

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
package require sdds

set CVSRevisionAuthor "\$Revision: 1.1 $ \$Author: jiaox $"
APSApplication . -name "Tcl/TK sddsplot Line Editor" -version $CVSRevisionAuthor 
.menu.file.menu insert 1 separator
.menu.file.menu insert 1 command -label "Save As..." -underline 0 -command "saveAs"
.menu.file.menu insert 1 command  -label "Save..." -underline 0 -command "saveFile"
.menu.file.menu insert 1 command -label "Open..." -underline 0 -command "openFile -fileName \"\" "


set status "Ready..."
set filename ""
APSScrolledStatus .status -parent .userFrame -textVariable status -width 80 -height 6 -packOption "-side top -fill x -expand false"
APSLabeledOutput .name -parent .userFrame  -label "Now Editing: " -textVariable filename -packOption " -expand 0 -fill x" -width 80
pack configure .userFrame.name.entry -expand 1


proc setStatus {text} {
    global status
    set status "[clock format [clock seconds] -format %H:%M:%S]: $text"
    update
}    
 
proc openFile { args } {
   global currentDir
   global filename
   global defRGB  defDash defThickness
   global RGBArray  dashArray thicknessArray
   global eScroll
   global numLines
   set i 0
   
   APSStrictParseArguments  { fileName }
   
   if { [llength $fileName ] == 0 } {
      set filename [APSFileSelectDialog .openFile -path $currentDir ]
   } else {
      set filename $fileName
   }   
   
   if { [llength $filename] == 0  } {
      return
   }   
     
   set currentDir [string replace  [join [lreplace [ split $filename / ] end end {} ] / ] end end ""]
   setStatus $currentDir
   
   
   if [catch {APSSDDSCheck -fileName $filename } result ] {
      setStatus $result
      return
   }   
   
   if [catch {APSGetSDDSNames -class column -fileName $filename } varList ] {
      setStatus $varList
      return
   }
   set varList_new [string tolower $varList]
   
   clearEditEntryItems   -parent $eScroll
   set i_red [lsearch $varList_new red] 
   set i_blue [lsearch $varList_new blue]
   set i_green [lsearch $varList_new green]
   if { $i_red > -1  && $i_blue > -1 && $i_green > -1 } {
      set defRGB 1
   } else {
      set defRGB 0
   }   
   set i_dash [lsearch $varList_new dash] 
   if { $i_dash > -1 } {
      set defDash 1
   } else {
      set defDash 0
   }   
   set i_thickness [lsearch $varList_new thickness] 
   if { $i_thickness > -1 } {
      set defThickness 1
   } else {
      set defThickness 0
   }   
   if { !$defRGB && !$defDash && !$defThickness } {
      setStatus "Not an appropriate line type defintion file.\n"
      return
   } 
   if { $defRGB }  {
      if [ catch { APSGetSDDSColumn -fileName $filename -column [lindex $varList $i_red] } red ] {
         setStatus $red
	 return
      }	 
      if [ catch { APSGetSDDSColumn -fileName $filename -column [lindex $varList $i_green] } green ] {
         setStatus $green
	 return
      }
      if [ catch { APSGetSDDSColumn -fileName $filename -column [lindex $varList $i_blue] } blue] {
         setStatus $blue
	 return
      }  
      set i 0
      foreach r $red g $green  b $blue  {
         incr i 
         set RGBArray(red.$i) [expr $r%256]
	 set RGBArray(green.$i) [expr $g%256]
	 set RGBArray(blue.$i) [expr $b%256]
      }	
   }   
   if { $defDash } {
      if [ catch { APSGetSDDSColumn -fileName $filename -column [lindex $varList $i_dash] } dash ] {
         setStatus $dash
	 return
      }
      set i 0
      foreach d $dash {
         incr i
	 set dashArray($i) $d
      }
   }    
   if { $defThickness } {
      if [ catch { APSGetSDDSColumn -fileName $filename -column [lindex $varList $i_thickness] } thickness ] {
         setStatus $dash
	 return
      }	
      set i 0 
      foreach t $thickness {
         incr i
	 set thicknessArray($i) $t
      }
   }   
   while { $numLines < $i } {
       incr numLines 
       makeEditEntryFrame -parent $eScroll
   }
   display -linetype all    
   setStatus "\nopen $filename. \nDone"
}   

proc WriteSDDSFile {} {
   global filename 
   global defRGB defDash defThickness
   global numLines
   global RGBArray
   global dashArray
   global thicknessArray
   
   set red ""
   set green ""
   set blue ""
   set thickness ""
   set dash ""
   
   set fd [ sdds open $filename w ]
   if { $defRGB } {
      sdds defineColumn $fd "red" -type SDDS_LONG
      sdds defineColumn $fd "green" -type SDDS_LONG
      sdds defineColumn $fd "blue" -type SDDS_LONG
      
      for {set i 1 } {$i<=$numLines} { incr i} {
         lappend red $RGBArray(red.$i)
         lappend green $RGBArray(green.$i)
	 lappend blue $RGBArray(blue.$i)
      }	     	 
      
   }
   if { $defDash } {
      sdds defineColumn $fd "dash" -type SDDS_STRING
      for {set i 1 } {$i<=$numLines} { incr i} {
         if { [ llength  $dashArray($i) ] } {
	    set tmpstr $dashArray($i)
	 } else {
	    set tmpstr "0"
	 }      
         lappend dash [string trim $tmpstr ]
      }	 
     
   }
   if { $defThickness } {
      sdds defineColumn $fd "thickness" -type SDDS_LONG
      for {set i 1 } {$i<=$numLines} { incr i} {
         if { [ llength  $thicknessArray($i) ] } {
	    set tmpstr $thicknessArray($i)
	 } else {
	    set tmpstr 1
	 }   
         lappend thickness [string trim $tmpstr ] 
      }	
            
   }
   sdds writeLayout $fd
   sdds startPage $fd $numLines
   if { $defRGB }  {
      eval sdds setColumn $fd "red"   $red
      eval sdds setColumn $fd "green"  $green
      eval sdds setColumn $fd "blue"  $blue
   }      
   if { $defDash } {
      eval sdds setColumn $fd "dash" $dash
   }
   
   if { $defThickness }  {
     eval sdds setColumn $fd "thickness" $thickness
   }
   
   sdds writePage $fd 
   sdds close $fd
   setStatus "$filename saved"   
}

proc saveFile {} {
   global filename
    
   if { [llength $filename ] ==0 } {
      saveAs
      return
   }
   WriteSDDSFile 
}   
 
proc saveAs {} { 
   global filename
   global currentDir
   set tmpfilename [APSFileSelectDialog .saveFile -path $currentDir -checkValidity 0 ]
   if { ![llength $tmpfilename ] } {
      return
   }   
   set filename $tmpfilename
   set currentDir [string replace  [join [lreplace [ split $filename / ] end end {} ] / ] end end ""]
   WriteSDDSFile
}

event add <<EDIT>> <Key-Tab>
event add <<EDIT>> <Key-Return>
proc makeEditEntryFrame {  args } {
   global eScrollFrame
   global numLines
   APSStrictParseArguments { parent }
   global RGBArray  dashArray thicknessArray
   global defRGB defDash defThickness
   
   APSFrame .ef$numLines -parent $parent -packOption "-side top -fill x -expand 0" 
   set w $parent.ef$numLines.frame
   #$w configure -bd 0 -relief flat 
   if { ![info exist RGBArray(red.$numLines)]  } {
      set RGBArray(red.$numLines) 0
      set RGBArray(green.$numLines) 0
      set RGBArray(blue.$numLines) 0
   }
   APSButton .lntest -parent $w -text "Line[expr $numLines - 1]:" -width "" -packOption "-side left" -command "display -linetype all " \
             -contextHelp "to display line$numLines"
   APSLabeledEntry .r -parent $w -label "" -packOption "-side left" -width 3 -textVariable RGBArray(red.$numLines) -type integer \
                   -contextHelp "red value: 0-255"
   APSLabeledEntry .b -parent $w -label "" -packOption "-side left" -width 3 -textVariable RGBArray(green.$numLines) -type integer \
                   -contextHelp "blue value: 0-255"
   APSLabeledEntry .g -parent $w -label "" -packOption "-side left" -width 3 -textVariable RGBArray(blue.$numLines) -type integer \
                   -contextHelp "green value: 0-255"
   APSLabeledEntry .dash -parent $w -label "" -packOption "-side left " -width 8  -textVariable dashArray($numLines)  \
                   -contextHelp "dash format example: 0 (solid); or 4,1; or 4,1,8,2"
   APSLabeledEntry .thickness -parent $w -label "" -packOption "-side left"  -width 5  -textVariable thicknessArray($numLines) \
                   -contextHelp "thickness value range: 1-10" -type integer
		   
   bind $w.r.entry <<EDIT>> { 
      #ugly but works to get the linetype number  
      set n [ string range [lindex [split [ focus ] . ] 8] 2 end ]    
      display -linetype all
   }
		
   bind $w.b.entry <<EDIT>> {
      set n [ string range [lindex [split [ focus ] . ] 8] 2 end ]
      display -linetype all
   }
   bind $w.g.entry <<EDIT>> {
      set n [ string range [lindex [split [ focus ] . ] 8] 2 end ]
      display -linetype all
   }
		   
   bind $w.dash.entry <<EDIT>> {
      set n [ string range [lindex [split [ focus ] . ] 8] 2 end ]
      display -linetype all
   }
	
   bind $w.thickness.entry <<EDIT>> {
      set n [ string range [lindex [split [ focus ] . ] 8] 2 end ]
      display -linetype all
   }
	 


   if { !$defRGB } {
      APSDisableWidget $w.r
      APSDisableWidget $w.g
      APSDisableWidget $w.b
   }  
   if { !$defDash } {
      APSDisableWidget $w.dash
   }
   if {!$defThickness } {
      APSDisableWidget $w.thickness
   }
   tkwait visibility $w.g
   APSScrollAdjust $eScrollFrame -numVisible 16
}

proc addEditEntryItem { args } {
   global numLines
   set parent ""
   APSStrictParseArguments { parent }
   
   incr numLines
   makeEditEntryFrame -parent $parent
   setStatus "Adding new entry line$numLines" 
}

proc deleteEditEntryItem { args } {
   global numLines plot
   set parent ""
   APSStrictParseArguments { parent }
   
   if {$numLines > 0 }  {
      destroy $parent.ef$numLines
      setStatus "Deleting entry line$numLines"
      $plot delete "test$numLines" "label$numLines"
      incr numLines -1
   } else {
      setStatus "nothing to delete"
   }   
}   
   
proc clearEditEntryItems { args } {
   global numLines plot
   set parent ""
   APSStrictParseArguments { parent }
   
   while {$numLines > 0 }  {
      destroy $parent.ef$numLines
      set RGBArray(red.$numLines) ""
      set RGBArray(green.$numLines) ""
      set RGBArray(grenn.$numLines) ""
      set dashArray($numLines) ""
      set thicknessArray($numLines) ""
      $plot delete "test$numLines" "label$numLines"
      incr numLines -1
   } 
   update 
}   


proc makeEditFrame { widget args } {
   global defRGB
   global defDash
   global defThickness
   global eScrollFrame
   global eScroll
   global numLines
   set parent ""
   APSStrictParseArguments { parent packOption }
   APSFrame $widget -parent $parent -packOption $packOption
  
   set w $parent$widget.frame
   set blist [list "  R    G    B "   " dash" "thickness"]
   set vlist [list "defRGB"  "defDash"  "defThickness"]
   set clist [list "toggleRGB"  "toggleDash" "toggleThickness"]
   
   APSCheckButtonFrame .type -parent $w -packOption "-side top -expand 0" -label "Types" -buttonList $blist -commandList $clist \
                       -variableList $vlist -orientation horizontal 
   
   set eScroll [ APSScroll .defs -parent $w -name "Line Definitions"  -packOption "-side top  -fill x "]
   set eScrollFrame $w.defs   
   set numLines 1
   makeEditEntryFrame -parent $eScroll
   APSButton .add -parent $w -text "Add" -width "" -command "addEditEntryItem -parent $eScroll "
   APSButton .delete -parent $w -text "Delete" -width "" -command "deleteEditEntryItem -parent $eScroll"
   APSButton .plotall -parent $w -text "Test All" -width "" -command "display -linetype all  "
   APSButton .save -parent $w -text "Save" -width "" -command "saveFile"
   APSButton .saveAs -parent $w -text "Save As" -width "" -command "saveAs"
   
}

proc toggleRGB {} {
   global defRGB
   global eScroll
   global numLines
   if { !$defRGB } {
      for { set i 1 } { $i <= $numLines} { incr i} {
         APSDisableWidget $eScroll.ef$i.frame.r
	 APSDisableWidget $eScroll.ef$i.frame.g
	 APSDisableWidget $eScroll.ef$i.frame.b
      }
      setStatus "disable RGB editing"
   }  else {
      for { set i 1 } { $i <= $numLines } { incr i} {
         APSEnableWidget $eScroll.ef$i.frame.r
	 APSEnableWidget $eScroll.ef$i.frame.g
	 APSEnableWidget $eScroll.ef$i.frame.b
      }  	 
      setStatus "enable RGB editing"
   }   
    
}

proc toggleDash {} {
   global defDash
   global eScroll
   global numLines 
   
   if { !$defDash } {
      for { set i 1 } { $i <=$numLines } { incr i } {
         APSDisableWidget $eScroll.ef$i.frame.dash
      }
      setStatus "disable dash editing"
   } else {
      for { set i 1 } { $i <=$numLines } { incr i } {
         APSEnableWidget $eScroll.ef$i.frame.dash
      }   	 
      setStatus "enable dash editing"
   }   
}

proc toggleThickness {} {
   global defThickness
   global eScroll
   global numLines 
   
   if { !$defThickness } {
      for { set i 1 } { $i <=$numLines } { incr i } {
         APSDisableWidget $eScroll.ef$i.frame.thickness
      }
      setStatus "disable thickness editing"
   } else {
      for { set i 1 } { $i <=$numLines } { incr i } {
         APSEnableWidget $eScroll.ef$i.frame.thickness
      }   	 
      setStatus "enable thickness editing"
   }   
}

proc display { args } {
   global plot width height
   global eScroll
   global RGBArray dashArray thicknessArray
   global defRGB defDash defThickness
   global numLines
   set linetype ""
   set yOffset 0
   APSStrictParseArguments { linetype }
   
   for {set i 1 } { $i<=$numLines } { incr i } {
       	 $plot delete "test$i"
	 $plot delete "label$i"
   }
   
   if { [string compare $linetype "all" ] == 0 } {
      set linetype ""
      for {set i 1} { $i<=$numLines } { incr i } {
         lappend linetype $i
      }
   }
   
   set x0 [ expr $width/8 ]
   set x1 [ expr $width*5/8 ]
   set y0 [ expr $height/( [llength $linetype]  +1 )]
   set x2 [ expr $width*7/8]
   
   set i 1
   foreach item $linetype {
      if { $defRGB } {
         set r [ format %X $RGBArray(red.$item)]
         set g [ format %X $RGBArray(green.$item)]
         set b [ format %X $RGBArray(blue.$item)]
         if {[string length $r] == 1} { set r 0$r }
         if {[string length $g] == 1} { set g 0$g }
         if {[string length $b] == 1} { set b 0$b }        
         set color "\#$r$g$b"
      } else {
         set color "\#ffffff"
      }
   
      if { $defDash } {
         set dash [join [ split $dashArray($item) ,]]
         if { $dash == "0" } { set dash "255" }
      } else  {
         set dash "255"
      }   
      set thickness 1
      if { $defThickness } {  
      
      set thickness $thicknessArray($item)
      if { ![string length $thickness] } {set thickness 1}
      }  
      
      set y [ expr $y0*$i]
      $plot create line $x0 $y $x1 $y -fill $color -width $thickness  -dash $dash -tag "test$item" 
      $plot create text  $x2 $y -text "linetype[expr $item-1]" -fill $color -tag "label$item" 
      incr i
      
   }
}   

proc reverseBackground {} {
   global background 
   global plot
   $plot delete "background"
   if { [ string compare "\#ffffff" $background]  == 0} {
      set background "\#000000"
   } else  {
      set background "\#ffffff"
   }
   $plot config -background $background   
   update
}   

proc makeDisplayFrame { widget args } {
   global plot width height background
   set parent ""
   set packOption ""
   set background "\#000000"
   
   APSStrictParseArguments { parent packOption }
   frame ${parent}${widget}  -relief raised -bd 2
   eval pack ${parent}${widget} $packOption
   APSLabel .lbl -parent ${parent}${widget}  -text "Line Type Display" -packOption "-side top"
   canvas ${parent}$widget.canvas -bg $background -width 450 -height 500 -relief flat -bd 0 
   pack ${parent}$widget.canvas -fill both -expand true
   set plot ${parent}$widget.canvas
   set width [$plot cget -width]
   set height [$plot cget -height]
   
   APSButton .bg -parent ${parent}${widget}  -text "Toggle Background Color" -command "reverseBackground"
}   
   

set currentDir  [pwd]
if { [llength $argv ] } {
   set filename ${currentDir}/$argv
}   
set defRGB  1
set defDash 0
set defThickness 0

makeEditFrame .edit -parent .userFrame -packOption "-side left -fill y"
makeDisplayFrame .display -parent .userFrame -packOption "-side left -fill both -expand true"

if { [llength $argv ] } {
   if { [file exist $filename] } {
      openFile -fileName $filename
      
   } else {
      setStatus "editing new file $filename"
   }
}      
