########################################
# jconfig v 1.54
# Jaleo Configutarion Manager
# Copyright S.G.O. 2.000
# Created by Miguel Angel Doncel, 2.000
# Questions: mad@sgo.es
#######################################
#!/bin/sh
#Tag 0xFFFFFF00
# restarts using wish  \
exec wish "$0" 

# files list
# format:	index	name
#               -----   ----
set filelist {	{1		~/JALEO-ENV/.jaleorc               }
		{2		~/JALEO-ENV/etc/devices/Xfs.dev        }
		{3		~/JALEO-ENV/etc/devices/ScrToVideo.cfg }
             }
	
# variable list
# format: 	name 				index 	name				default		widget		values
#               ----                ----- 	----					------- 	------		------				  
set varlist {	{GENERAL			0	"General"			0		button			    }
		{NUMLEADZEROS 			1	"Lead Zeros"			4		slider		{1 5 1}	 								}
		{TIMESAVE 			1	"Time Save (secs)"		300		slider		{10 1000 1}	 							}
		{EXPIRATIONWARNING 		1	"Expiration Warning"		10 		slider		{1 15 1} 	 							}
		{MAXMEM 			1	"Max. Memory"			4 		slider		{1 32 1}  		 	 							}
	     	{PARALLEL 			1	"Parallel CPUs"			1 		slider		{1 16 1}				 							}
		{HARDWARE_RENDERING 		1	"Hardware Rendering"		TRUE 		checkbutton					 							}
		{MONITORS_DOUBLE_BUFFER		1	"Monitors Double Buffer"	FALSE 		checkbutton					 							}
	     	{MAGNET_SNAP 			1	"Magnet Snap (pixels)"		15 		slider		{1 25 1}				 					 	}
		{GALLERY_TMP_DIR 		1	"Gallery tmp dir."		/usr/tmp	entry		 										 	}
		{PAINT_TMP_DIR			1	"Paint tmp dir."		/usr/tmp	entry			    }
		{VIDEO_FORMAT 			0	"Video format"			0		button												 	}
		{STANDARD 			1	"Standard"			PAL 		menu		{"Custom" "PAL" "NTSC" "NTSC_D" "NTSC_ND" "FILM" "1035" "1080_24p" "1080_30i" "720p"}  			}
		{IMAGESIZEX 			1	"Image Size X"			720		slider		{1 2500 1}										 	}
		{IMAGESIZEY 			1	"Image Size Y"			576		slider		{1 2500 1}										 	}
		{FRAMESSEG 			1	"Frames per Second"		25		entry												 	}
		{NTSCFIELDS			1	"NTSC Fields"			FALSE		checkbutton											 	}
		{LOWRESRATIO 			1	"Low Res. Ratio"		2 		radiobutton	{2 4 8 16 32}							 	}
		{SCREENRATIO 			1	"Screen Ratio"			1.33		radiobutton	{1.33 1.77}												 	}
		{PAL_PLUS 			1	"Pal Plus"			FALSE		checkbutton											 	}
		{OLD_SIZE_RULES 		1	"Old Size Rules"		FALSE		checkbutton											 	}
		{EXTRA_VITC_LINES 		1	"Extra VITC Lines"		0 		slider		{0 20 2}					 	}
		{RENDER_AND_DEVICE		0	"Device/Render"			0		button		    }
		{TABLET_MAXPRESS 		1	"Tablet Max. Press."		3		slider		{1 100 1}												 	}		
		{DEVICETYPE		 	2	"Disk Device Type"			XFS		entry												 	}
 		{MESSAGES		 	2	"Disk Messages"			TRUE		checkbutton											 	}
		{MAX_FILES_OPENED		2	"Max Open Files"		10		slider		{5 50 1}												 	}
		{PATH		 		2	"Disk Device Path"		/MATERIAL	entry												 	}
		{RENDERPARTIAL 			1	"Partial Render Dev."		Xfs.dev 	entry													}
		{CACHEDEVICE 			1	"Cache Device"			Xfs.dev 	entry						 							}
		{DEVICECLASS		 	3	"Device Class"			LIVEVIDEO	entry												 	}
		{RENDER_TO_VIDEO 		1	"Render to Video"		TRUE 		checkbutton						 					 	}
		{RENDER_UNITS 			1	"Render Units"			1 		slider		{1 12 1}								 	}
		{PIPE_UNITS 			1	"Pipe Units"			5 		slider		{1 12 1}								 	}
		{RING_BUFF_SIZE			3	"Ring Buffer Size"		16		slider		{18  64 1}}
		{BLOCK_SIZE			1	"Block Size"			16384		radiobutton	{4096 16384}}
		{ALIGN_SIZE			1	"Align Size"			16384		radiobutton	{4096 16384}}
		{HD_OPTIONS 			0	"HD Options"			0		button												 	}
		{COLOR_SPACE_709		1	"HD Color Space (709)"		FALSE		checkbutton }
		{NODE_COUNT			1	"Node Count"			2		slider		{1 8 1}}
		{VIDEO_BOARD			1	"Default Video Board"		XTHD		radiobutton	{"XTHD" "DIVO"}}
		{BACKLOAD			1	""				1		none		{1}}
           }


# Custom formats
set custom_modes [list]
set custom_settings [list]

# other global vars
set comment 0
set changed 1
set othervarlist [list ]
set curformat "PAL"


#--------------------------------------------------------
# wipe comments
# substract the comments from the line
#--------------------------------------------------------
proc fcopy {from to} {
    set source [open $from r]
    set dest [open $to w+]
    while {[gets $source line] >= 0} {
	puts $dest $line
    }
    close $source
    close $dest
}


#--------------------------------------------------------
# wipe comments
# substract the comments from the line
#--------------------------------------------------------
proc wipe_comments {line} {
    global comment
    while 1 {
	# comment end
	if  {$comment == 1 } {
	    if {[regsub {.*\*/} $line "" line] == 1 } {
		set comment 0
	    } else {return ""}
	}
	# inline comment
	if {[regsub {/\*.*\*/} $line "" line] == 1 } {
	    set comment 0
	} else {
	# comment start
	    if {[regsub {/\*.*} $line "" line] == 1 } {
		set comment 1  
		return $line
	    } else {
		set square ""
		scan $line "%s" square
		if {$square == "#"} { 
		    return ""
		} else { return $line }
	    }
	}
    }
}


#--------------------------------------------------------
# get var name
# get the variable name from the parameter name
#--------------------------------------------------------

proc get_var_name {name} {
  set low [string tolower $name]
  regsub -all {[_/\.]} $low "" low
  return $low
}


#--------------------------------------------------------
# parse line
# analize one config line
#--------------------------------------------------------
proc parse_line {line current_filename } {
  global varlist
  global othervarlist
  set found 0
  set cont [scan $line "%s %s" var val]
  if {$cont == 2} {
    foreach i $varlist {
      if {[lindex $i 0] == $var} {
        set found 1
        set varname [get_var_name $var]
        global $varname
        switch [lindex $i 4] {
          checkbutton {
                        if { $val == "TRUE" } {
                          set $varname 1
                        } else {
                          set $varname 0
                        }
                      }
          default     {
                        set $varname $val
                      }
        }
      }
    } 
    if { $found == 0} {
      set othervarlist [concat $othervarlist [list [format "%s %s %s" $current_filename $var $val]]]
    }
  }
}

#--------------------------------------------------------
# load config
# read the configuration files
#--------------------------------------------------------
proc load_config {} {
  global filelist
  foreach i $filelist {
    if {[file exists [lindex $i 1]]} {
	set f [open [lindex $i 1] r]
	while { [gets $f line]>=0} {
	  set line [wipe_comments $line]
	  parse_line $line [lindex $i 1]
	}
	close $f
    }
  }
} 

#--------------------------------------------------------
# load custom modes
# read settings for customized video formats
#--------------------------------------------------------
proc load_custom_modes {} {
    global custom_settings
    global custom_modes
    set name ""
    set value ""
    foreach f [glob -nocomplain ~/JALEO-ENV/config/.jaleorc.*] {
	 set ffile [open $f r]
	 regsub {.*.jaleorc.} $f "" mode
	 set settings {}
	 while {[gets $ffile line]>=0} {
	    set line [wipe_comments $line]
	    if {[scan $line "%s %s" name value] > 1} {
		lappend settings [concat $name $value]
	    }
	 }	
	 lappend custom_settings $settings
	 lappend custom_modes $mode	
    }    
}

#--------------------------------------------------------
# Save single config
# write a configuration file
#--------------------------------------------------------
proc save_single_config {index filename} {
  global varlist
  global othervarlist
  set f [open $filename w]
  puts $f "/* JALEO                                                  */"
  puts $f "/* ****************************************************** */"
  puts $f "/* File created by Jaleo Configuration Manager            */"
  puts $f "/* We strongly recommend not to change this file manually */"
  puts $f "/* use jconfig instead.                                   */"
  puts $f "/* ****************************************************** */" 
  foreach i $varlist {
    if {[lindex $i 1]==$index} { 
      set var [lindex $i 0]
      set varname [get_var_name $var]
      global $varname
   
      set val [expr $[get_var_name $var]]
      switch [lindex $i 4] {
        checkbutton {
                      if {[expr $[get_var_name $var]] == 1} {
                        puts $f [format "%-30s %s" $var TRUE]
                      } else {
                        puts $f [format "%-30s %s" $var FALSE]
                      } 
                    }
       default      {
                       puts $f [format "%-30s %s" $var $val]
                    } 
      }
    }
  }
  foreach i $othervarlist {
    if {$filename == [lindex $i 0]} {
      puts $f [format "%-30s %s" [lindex $i 1] [lindex $i 2]]   
    }
  }
  close $f
} 

#--------------------------------------------------------
# Save config
# write configuration files
#--------------------------------------------------------
proc save_config {} {
  global filelist
  foreach i $filelist {
    save_single_config [lindex $i 0] [lindex $i 1]
  }
}


#--------------------------------------------------------
# Save and exit
# any question?
#--------------------------------------------------------
proc save_and_exit {} {
  global standard
  global curformat
  save_config
# swap corrections
  if { [file exists ~/JALEO-ENV/config/.jCorrectionsSetup] } {
      fcopy ~/JALEO-ENV/config/.jCorrectionsSetup ~/JALEO-ENV/config/.jCorrectionsSetup.$curformat
  }
  if { [file exists "~/JALEO-ENV/config/"] } {
      if { [glob -nocomplain ~/JALEO-ENV/config/.jCorrectionsSetup.$standard] != "" } {
	    fcopy ~/JALEO-ENV/config/.jCorrectionsSetup.$standard ~/JALEO-ENV/config/.jCorrectionsSetup
	  }
  }	  
  exit
} 

#--------------------------------------------------------
# Cancel and exit
# any question?
#--------------------------------------------------------
proc cancel_and_exit {} {
  global changed
  if {$changed != 0 } {
 # set res [tk_messageBox -icon question -message "Do you really want to quit without saving the config?" -type yesno -parent .]
  set res [exec xconfirm -icon question -b "yes" -B "no" -t "Do you really want to quit without saving the settings?" -header "Jaleo Setup" -font -adobe-helvetica-bold-r-normal--14-*]
    if {$res == "yes"} {
      exit
    }
  } else {
    exit
  }
} 

#--------------------------------------------------------
# default config
# assign the factory default.
#--------------------------------------------------------

proc default_config {} {

  global varlist
  foreach i $varlist {
    set var [lindex $i 0]
    set varname [get_var_name $var]
    global $varname
    switch [lindex $i 4] {
      checkbutton {
                    if {[lindex $i 3] == "TRUE"} {
                      set $varname 1
                    } else {
                      set $varname 0
                    }                  
                  }		  
      default     {
                    set $varname [lindex $i 3]
                  }
    }
  }
}

#--------------------------------------------------------
# create label
# args: frame, title, var
# create a label type param.
#--------------------------------------------------------

proc create_label {orig tit var} {
  frame $orig.f$var
  label $orig.f$var.label -text "$tit" -anchor nw  -font "-adobe-helvetica-bold-r-normal--14-*"
  pack $orig.f$var.label -anchor nw -side left
}

#--------------------------------------------------------
# create_check
# args: frame, title var
# create a checkbutton type param
#--------------------------------------------------------

proc create_check {orig tit var} {
  frame $orig.f$var 
  label $orig.f$var.label -text "$tit" -anchor w -width 20
  checkbutton $orig.f$var.$var -text "" -variable $var -relief flat -anchor nw 
  pack $orig.f$var.label -side left 
  pack $orig.f$var.$var -side left -expand 1 -fill both
}

#--------------------------------------------------------
# create_radio
# args: frame, title, buttons
# create a radiokbutton type param
#--------------------------------------------------------

proc create_radio {orig tit var options} {
  frame $orig.f$var
  label $orig.f$var.label -text "$tit" -anchor nw -width 20
  frame $orig.f$var.$var 
  foreach i $options {
    radiobutton $orig.f$var.$var.[get_var_name $i] -text $i -variable $var -relief flat -value $i -anchor w 
    pack $orig.f$var.$var.[get_var_name $i] -side left -anchor nw -expand 1 -fill both
  } 
  pack $orig.f$var.label -side left 
  pack $orig.f$var.$var -side left -expand 1 -fill both
}

#--------------------------------------------------------
# create_menu
# args: frame, title, buttons
# create a menu type param
#--------------------------------------------------------

proc create_menu {orig tit var options} {
  global $var
  global custom_modes
  frame $orig.f$var
  label $orig.f$var.label -text "$tit" -anchor nw -width 20
  set seg [expr $[get_var_name $var]]
  set menulauncher "tk_optionMenu \$orig.f\$var.\$var \$var"

  if { $tit == "Standard" } {
    set options [concat $options $custom_modes]
  }
  foreach i $options {
    set menulauncher [format "%s %s" $menulauncher $i]
  }
  global m$var
  set m$var [eval $menulauncher]
  $orig.f$var.$var configure -pady 0
  set $var $seg
  pack $orig.f$var.label -side left
  pack $orig.f$var.$var -side left -expand 1 -fill both  

  if { $tit == "Standard" } { 
    standard_menu_patch $options }
}

#--------------------------------------------------------
# create entry
# args: frame, title, var
# create an entry type param
#--------------------------------------------------------

proc create_entry {orig tit var} {
  frame $orig.f$var 
  label $orig.f$var.label -text "$tit" -anchor nw -width 20  
  entry $orig.f$var.$var -textvariable $var
  global $var 
  set seg [expr $[get_var_name $var]]
  set $var $seg
  pack $orig.f$var.label -side left
  pack $orig.f$var.$var -side left -expand 1 -fill both
 }
 
#--------------------------------------------------------
# create slider
# args: frame, title, var
# create an slider type param
#--------------------------------------------------------

proc create_slider {orig tit var params} {
  frame $orig.f$var
  label $orig.f$var.label -text "$tit" -anchor nw -width 20
  frame $orig.f$var.fslider  
  label $orig.f$var.fslider.value -width 3 -justify right -textvariable $var
  scale $orig.f$var.fslider.slider -orient horizontal -from [lindex $params 0] -to [lindex $params 1] -resolution [lindex $params 2] -showvalue 0 -length 180 -variable $var
  set cmdstring [format "%s.f%s.fslider.slider configure -command {%s.f%s.fslider.value configure -text}" $orig $var $orig $var]
  eval $cmdstring
  global $var 
  set $var [expr $[get_var_name $var]]
  pack $orig.f$var.label -side left
  pack $orig.f$var.fslider -side left -expand 1 -fill both
  pack $orig.f$var.fslider.value $orig.f$var.fslider.slider -side left -fill x
 }
 
#--------------------------------------------------------
# create button
# args: frame, title, var
# add a button to menu and create a label
#--------------------------------------------------------

proc create_button {orig tit var} {
    global page
    set cmd [format "pack forget .ui.$%s; pack .ui.%s; set page %s" page $var $var]
    button .ui.menu.$var -text "$tit" -relief groove -command $cmd
    pack .ui.menu.$var -side left
    set page $var
    frame .ui.$page
    pack forget $orig
    pack .ui.$page -side top
    create_label .ui.$page "$tit" $var
 } 
 
#--------------------------------------------------------
# standard_menu_patch
# args: 
# Patch to handle standard settings. initial dirty solution
#--------------------------------------------------------

proc standard_menu_patch {menuentries} {
  global mstandard
  global varlist
  global custom_modes
  set cont 0
# standard menu
  foreach i $menuentries {
    set cmdline [format "%s entryconfigure %d -command {standard_menu_changed %s}" $mstandard $cont $i]
    set cont [expr $cont + 1]
    eval $cmdline
  }      
}

#--------------------------------------------------------
# standard_menu_changed
# args: 
# manually change settings if standard is changed
#--------------------------------------------------------

proc standard_menu_changed {index} {
  global standard
  global imagesizex
  global imagesizey
  global framesseg
  global ntscfields
  global mstandard    
  global pipeunits
  global screenratio
  global colorspace709
  global custom_modes
  global custom_settings

  set standard $index
  switch $index {
    "PAL" {
            set imagesizex 720
            set imagesizey 576
            set framesseg 25
	    set screenratio 1.33
            set ntscfields 0
	    set colorspace709 0
          }
    "NTSC" {
            set imagesizex 720
            set imagesizey 486
            set framesseg 29.97
	    set screenratio 1.33
            set ntscfields 1
	    set colorspace709 0
           }
    "NTSC_D" {
            set imagesizex 720
            set imagesizey 486
            set framesseg 29.97
	    set screenratio 1.33
            set ntscfields 1
	    set colorspace709 0
           }
    "NTSC_ND" {
            set imagesizex 720
            set imagesizey 486
            set framesseg 29.97
	    set screenratio 1.33
            set ntscfields 1
	    set colorspace709 0
            }
    "FILM" {
            set imagesizex 2048
            set imagesizey 1536
	    set framesseg 24
	    set screenratio 1.33
            set ntscfields 0
	    set colorspace709 0
           }
    "1035" {
	    set imagesizex 1920
            set imagesizey 1035
	    set framesseg 30           
	    set screenratio 1.77
	    set pipeunits 4
	    set colorspace709 1
	   }
    "1080_24p" {
	    set imagesizex 1920
            set imagesizey 1080
	    set framesseg 24
            set ntscfields 0 
	    set screenratio 1.77
	    set pipeunits 1
	    set colorspace709 1
	    }
    "1080_30i" {
	    set imagesizex 1920
            set imagesizey 1080
	    set framesseg 30 
	    set screenratio 1.77
	    set pipeunits 4
	    set colorspace709 1
	    }
    "720p"  {	    
	    set imagesizex 1280
            set imagesizey 720
	    set framesseg 30
	    set screenratio 1.77
	    set pipeunits 1
	    set colorspace709 1
	    }
    "Custom" {
	   # dialog to enter new name
	   pack forget .ui .buttons
	   pack .custom 
	   pack .custom.prompt .custom.name -side top
	   pack .custom.ok .custom.cancel -side left -expand 1 -fill both	   
	    }   
    default {
	    set indexstd [lsearch -exact $custom_modes $standard]
	    foreach setting [lindex $custom_settings $indexstd] {
		set [get_var_name [lindex $setting 0]] [lindex $setting 1]
	    }	
	    }	     	    
  }
}

#--------------------------------------------------------
# Custom Name Entry proc
#
#--------------------------------------------------------

proc custom_name {option} {
  global customname
  global custom_modes
  global custom_settings
  global imagesizex
  global imagesizey
  global framesseg
  global screenratio
  global pipeunits
  global colorspace709
  global ntscfields
  global standard
  global mstandard
  pack forget .custom
  pack .ui .buttons -side top -expand 1 -fill both
  if { $option == "ok" } {
    set customname [lindex $customname 0]
    set standard $customname
    if { $customname != "" } {
	# add format to custom list
	set cmd [format "%s add command -label %s -command {standard_menu_changed %s}" $mstandard $customname $customname]	
	eval $cmd
 	set newindex ""
	set newindex [lappend newindex [format "%s %s" IMAGESIZEX $imagesizex]]
	set newindex [lappend newindex [format "%s %s" IMAGESIZEY $imagesizey]]
	set newindex [lappend newindex [format "%s %s" FRAMESSEG $framesseg]]
	set newindex [lappend newindex [format "%s %s" SCREENRATIO $screenratio]]
	set newindex [lappend newindex [format "%s %s" PIPE_UNITS $pipeunits]]
	set newindex [lappend newindex [format "%s %s" COLOR_SPACE_709 $colorspace709]]
	set newindex [lappend newindex [format "%s %s" NTSCFIELDS $ntscfields]]
	set custom_modes [lappend custom_modes $customname]
	set custom_settings [lappend custom_settings $newindex]	    
	# save format file
	set cfile [open "~/JALEO-ENV/config/.jaleorc.$customname" w]    
	puts $cfile [format "# %s" $customname]
	puts $cfile [format "%s %s" IMAGESIZEX $imagesizex]
	puts $cfile [format "%s %s" IMAGESIZEY $imagesizey]
	puts $cfile [format "%s %s" FRAMESSEG $framesseg]
	puts $cfile [format "%s %s" SCREENRATIO $screenratio]    
	puts $cfile [format "%s %s" PIPE_UNITS $pipeunits]
	puts $cfile [format "%s %s" COLOR_SPACE_709 $colorspace709]
	puts $cfile [format "%s %s" NTSCFIELDS $ntscfields]    
	close $cfile
	}
  } 
}


#--------------------------------------------------------
# Main Program
#
#--------------------------------------------------------

  wm title . "Jaleo Configuration Manager"
  wm iconname . "jconfig"
  wm geometry . +550+150
  wm protocol . WM_DELETE_WINDOW cancel_and_exit
  wm resizable . 0 0
  
  option add "*font" "-adobe-helvetica-bold-r-normal--12-*"

# general fg & bg
  option add "*background" "#384959"
  option add "*foreground" "White"

#activated items fg & bg . No activation
  option add "*activeBackground" "#384959"
  option add "*activeForeground" "White"

# Highlighted items fg & bg. No highlight
  option add "*highlightBackground" "#384959"
  option add "*highlightColor" "White"

# selected text bg.
  option add "*selectBackground" "LightSteelBlue3"

# checkers & radio.
  option add "*selectColor" "#FFBE00"

# input boxes bg #696969
  option add "*Entry.background" "#696969"
  default_config
  load_config
  load_custom_modes

  frame .ui
  frame .buttons 
  pack .ui .buttons -side top -expand 1 -fill both
  
# custom window
  frame .custom  
  entry .custom.name -textvariable customname
  label .custom.prompt -text "Enter format name" -anchor w
  button .custom.ok -text OK -command "custom_name ok"
  button .custom.cancel -text Cancel -command "custom_name cancel"
  
# add ui button menu
  frame .ui.menu
  pack .ui.menu -side top -expand 1 -fill both
  
# add option components
  set page ""
  foreach i $varlist {
    set var [lindex $i 0]
    set title [lindex $i 2]
    switch [lindex $i 4] {
      label       {create_label .ui.$page $title [get_var_name $var]}
      checkbutton {create_check .ui.$page $title [get_var_name $var]}
      radiobutton {create_radio .ui.$page $title [get_var_name $var] [lindex $i 5]}
      menu        {create_menu  .ui.$page $title [get_var_name $var] [lindex $i 5]}
      entry       {create_entry .ui.$page $title [get_var_name $var]}
      slider	  {create_slider .ui.$page $title [get_var_name $var] [lindex $i 5]}
      button	  {create_button .ui.$page $title [get_var_name $var]}
      default     {create_label .ui "undefined type"  $var}
    }
    if {[lindex $i 4] != "none"} {
	pack .ui.$page.[get_var_name f$var] -side top -anchor ne -expand 1 -fill both -pady 0 -padx 2
	}
  }  
  button .buttons.save -text "Save" -command "save_and_exit" 
  button .buttons.default -text "Factory Defaults" -command "default_config" 
  button .buttons.cancel -text Cancel -command "cancel_and_exit" 
  pack .buttons.save .buttons.default .buttons.cancel -side left -expand 1 -fill both

  # standard_menu_patch

# store initial video format
  set curformat $standard

# initial settings page
  set start [.ui.menu.[get_var_name [lindex [lindex $varlist 0] 0]] cget -command]
  eval $start
