proc rmi_SetMotion { what { w "" } } {
global rmi
 
  if { $what == "0" } {
    set fc gray
    set on disabled
    foreach item { intake exhaust } {
      if [winfo exists .rmiedit$item] {
        destroy .rmiedit$item
      }
      if [ winfo exists .rmieditgeometry$item ] {
        destroy .rmieditgeometry$item
      }
    }    
  } else {
    set fc black
    set on normal
  }

  set rmi(intake_motion) 0
  set rmi(exhaust_motion) 0

  if { $what == "1" || $what == "3" } {
    set rmi(intake_motion) 1
  }
  if { $what == "2" || $what == "3" } {
    set rmi(exhaust_motion) 1
  }

  if { $w != "GrayOut" } {

    foreach item $rmi(MotionBitmap) {
      if { $w == $item } {
        $w configure -relief raised -highlightbackground blue -highlightthickness 2
      } else {
        $item configure -relief sunken -highlightthickness 0
      }
    }
  
    foreach item $rmi(ValveAngleBitmap) {
      $item configure -fg $fc
      if { [ winfo class $item ] == "Button" } {
        $item configure -state $on
      }
    }
  }
  
  foreach item $rmi(GrayOutEngineGeometryButtons) {
    if ![winfo exists $item] { continue }
    $item configure -fg $fc
    if { ([ winfo class $item ] == "Button") || \
         ([ winfo class $item ] == "Menubutton") || \
         ([ winfo class $item ] == "Entry") || \
         ([ winfo class $item ] == "Radiobutton") } {
      $item configure -state $on
    }
  }

  foreach item $rmi(GrayOutEngineMeshingButtons) {
    if ![winfo exists $item] { continue }
    $item configure -fg $fc
    if { ([ winfo class $item ] == "Button") || \
         ([ winfo class $item ] == "Menubutton") || \
         ([ winfo class $item ] == "Entry") || \
         ([ winfo class $item ] == "Radiobutton") } {
      $item configure -state $on
    }
  }
  
  foreach type {Intake Exhaust} {
    foreach item $rmi(MaskForm${type}LayersNumber) {
      if ![winfo exists $item] { continue }
      $item configure -fg $fc -state $on
    }
    if !$rmi(chadice) {
      if [winfo exists $rmi(${type}AllValveButton)] {
        $rmi(${type}AllValveButton) configure -fg $fc -state $on
      }
    }
  }  

  foreach item {MaskFormIntakeGeometryNumber MaskFormExhaustGeometryNumber \
  		MaskFormIntakeGeometry MaskFormExhaustGeometry} {
    if [info exists rmi($item)] {
      foreach i $rmi($item) {
        if [winfo exists $i] {
          $i configure -fg $fc -state $on
        }
      }
    }
  }
    
  if { $what == "1" || $what == "2" } {
    if { $what == "1" } {
      set fc_1 black
      set fc_2 gray
      set on_1 normal
      set on_2 disabled
    } elseif { $what == "2" } {
      set fc_1 gray
      set fc_2 black 
      set on_1 disabled
      set on_2 normal
    }
    
    foreach type {Intake Exhaust} {    
      if {$type == "Intake"} { set fc $fc_1; set on $on_1 }
      if {$type == "Exhaust"} { set fc $fc_2; set on $on_2 }
      foreach item $rmi(GrayOutEngineGeometry${type}Buttons) {
        if ![winfo exists $item] { continue }
        $item configure -fg $fc
        if {([winfo class $item] == "Button") || \
            ([winfo class $item] == "Menubutton") || \
            ([winfo class $item] == "Entry") || \
            ([winfo class $item] == "Radiobutton")} {
          $item configure -state $on
        }
      }
      foreach item $rmi(GrayOutEngineMeshing${type}Buttons) {
       if ![winfo exists $item] { continue }
        $item configure -fg $fc
        if {([ winfo class $item] == "Button") || \
            ([ winfo class $item] == "Menubutton") || \
            ([ winfo class $item] == "Entry") || \
            ([ winfo class $item] == "Radiobutton") } {
          $item configure -state $on
        }
      }
      foreach item $rmi(MaskForm${type}LayersNumber) {
        if ![winfo exists $item] { continue }
        $item configure -fg $fc -state $on
      }
      if !$rmi(chadice) {
        if [winfo exists $rmi(${type}AllValveButton)] {
          $rmi(${type}AllValveButton) configure -fg $fc -state $on
        }
      }
    }
    
    if [info exists rmi(MaskFormIntakeGeometryNumber)] {
      foreach item $rmi(MaskFormIntakeGeometryNumber) {
        if [winfo exists $item] {
          $item configure -fg $fc_1 -state $on_1
        }
      }
      if [winfo exists $rmi(MaskFormIntakeGeometry)] {
        $rmi(MaskFormIntakeGeometry) configure -fg $fc_1 -state $on_1
      }
    }
    if [info exists rmi(MaskFormExhaustGeometryNumber)] {
      foreach item $rmi(MaskFormExhaustGeometryNumber) {
        if ![winfo exists $item] { continue }
        $item configure -fg $fc_2 -state $on_2
      }
      if [winfo exists $rmi(MaskFormExhaustGeometry)] {
        $rmi(MaskFormExhaustGeometry) configure -fg $fc_2 -state $on_2
      }
    }    
  }
  
  rmi_SetMenuCurrentValve Intake intake
  rmi_SetMenuCurrentValve Exhaust exhaust
  rmi_SetStaticButtons
}

proc rmi_SetStaticButtons {} {
global rmi
  
  if !$rmi(chadice) { return }    
  if {!$rmi(intake_motion) && !$rmi(exhaust_motion) } {
    set on disabled
    set col gray
  } else {
    set on normal
    set col black
  }
  if [winfo exists $rmi(StaticGeoButton)] {
    $rmi(StaticGeoButton) configure -state $on -fg $col
    $rmi(StaticMeshButton) configure -state $on -fg $col
    $rmi(StaticMergeButton) configure -state $on -fg $col
    $rmi(MergeMeshButton) configure -state $on -fg $col
  }
}

proc rmi_IsTetinSelected {} {
global rmi batch_mode

  if {$rmi(chadice) || $batch_mode} { return }

  if {!$rmi(TetinSelected) || $rmi(tetin_fn) == ""} {
    set color gray
    set state disabled
  } else {
    set color black 
    set state normal
  }
  
  foreach item $rmi(GrayOutEngineGeometryButtons) {
    $item configure -fg $color
    if {([winfo class $item] == "Button") || \
        ([winfo class $item] == "Menubutton") || \
        ([winfo class $item] == "Entry")||
        ([winfo class $item] == "Radiobutton")} {
      $item configure -state $state
    }
  }

  rmi_SetMenuCurrentValve Intake intake
  rmi_SetMenuCurrentValve Exhaust exhaust

  $rmi(ValveMotionButton) configure -state $state -fg $color
  $rmi(IntakeAllValveButton) configure -state $state -fg $color
  $rmi(ExhaustAllValveButton) configure -state $state -fg $color
}

proc rmi_CalculateMotion {} {
global rmi tmp

    if {!$rmi(intake_motion) && !$rmi(exhaust_motion)} {
      set rmi(degrees_simulated_start) 540
      set rmi(degrees_simulated_stop) 780
      set rmi(starting_angle_dca) $rmi(degrees_simulated_start)
      set rmi(ending_angle_dca) $rmi(degrees_simulated_stop)
      return
    }    
    
    set both 0
    if $rmi(intake_motion) {
      set type intake; set use 1
    }
    if $rmi(exhaust_motion) {
      set type exhaust; set use 2
    }
    if {$rmi(intake_motion) && $rmi(exhaust_motion)} {
      set type intake; set use 1; set both 1
    }
    if $rmi(all_${type}_valves) {
      if {$rmi(${type}_lift_fn) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile file before.\n" red
        return
      }   
    } else {
      if {$rmi(${type}_lift_fn,$rmi(current_${type}_valve)) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile file $rmi(current_${type}_valve) before.\n" red
        return     
      }        
    }
    set list ""
    if $rmi(all_${type}_valves) {
      set list [ ic_rmi_comp_max_lift $use \
          $rmi(${type}_lift_fn) \
  	  $rmi(${type}_lift_factor) \
          $rmi(${type}_max_lift) \
          $rmi(${type}_min_lift) \
          $rmi(${type}_valve_nlayers) ]
      if ![ lindex $list 0 ] {
        rmi_ShowMessage "Calculate: Unable to calculate simulation start/stop.\n" red
        return
      }
      rmi_CalculateStartStop "$list" $use $both 0
    } else {
      for { set x 1 } { $x <= $rmi(${type}_number_valve) } { incr x } {
        set list [ ic_rmi_comp_max_lift $use \
          $rmi(${type}_lift_fn,$x) \
  	  $rmi(${type}_lift_factor) \
          $rmi(${type}_max_lift,$x) \
          $rmi(${type}_min_lift) \
          $rmi(${type}_valve_nlayers) ]
        if ![ lindex $list 0 ] {
          rmi_ShowMessage "Calculate: Unable to calculate simulation start/stop for $type valve $x.\n" red
          if [info exists tmp(degrees_simulated_start)] {
           unset tmp(degrees_simulated_start)
           unset tmp(degrees_simulated_stop)
          }
          return
        }
        rmi_CalculateStartStop "$list" $use $both 1
      }
      if [info exists tmp(degrees_simulated_start)] {
        unset tmp(degrees_simulated_start)
        unset tmp(degrees_simulated_stop)
      }
    }
    set rmi(starting_angle_dca) $rmi(degrees_simulated_start)
    set rmi(ending_angle_dca) $rmi(degrees_simulated_stop)
}

proc rmi_CalculateStartStop {list use both single} {
global rmi tmp

    if {$use == "1" && $both == "0"} {
      set start [expr round([lindex $list 3]) - 5]
      set len [expr [string length $start] - 1]
      set last [string index $start $len]
      if {$last >=6 && $last <=9} {
        set start "[string range $start 0 [expr $len - 1]]5"
      } elseif {$last >=1 && $last <=4} {
       set start "[string range $start 0 [expr $len - 1]]0"
      }
      set rmi(degrees_simulated_start) $start
      set rmi(degrees_simulated_stop) 780
    } elseif {$use == "2" && $both == "0"} {
      set stop [expr round([lindex $list 4])]
      set len [expr [string length $stop] - 1]
      set last [string index $stop $len]
      if {$last >=6 && $last <=9} {
        set stop "[string range $stop 0 [expr $len - 1]]5"
      } elseif {$last >=1 && $last <=4} {
        set stop "[string range $stop 0 [expr $len - 1]]0"
      }
      set rmi(degrees_simulated_start) 0
      set rmi(degrees_simulated_stop) $stop
    } elseif {$both == "1"} {
      set start [expr round([lindex $list 3]) - 10]
      set len [expr [string length $start] - 1]
      set last [string index $start $len]
      if {$last >=6 && $last <=9} {
        set start "[string range $start 0 [expr $len - 1]]5"
      } elseif {$last >=1 && $last <=4} {
        set start "[string range $start 0 [expr $len - 1]]0"
      }
      set rmi(degrees_simulated_start) $start
      set rmi(degrees_simulated_stop) [expr $start + 720]
    }
    
    if $single {
      if ![info exists tmp(degrees_simulated_start)] {
        set tmp(degrees_simulated_start) $rmi(degrees_simulated_start)
        set tmp(degrees_simulated_stop) $rmi(degrees_simulated_stop)
      } else {
        if {$use == "1" && $both == "0"} {
          if {$rmi(degrees_simulated_start) < $tmp(degrees_simulated_start)} {
            set tmp(degrees_simulated_start) $rmi(degrees_simulated_start)
          }
        } elseif {$use == "2" && $both == "0"} {
          if {$rmi(degrees_simulated_stop) > $tmp(degrees_simulated_stop)} {
            set tmp(degrees_simulated_stop) $rmi(degrees_simulated_stop)
          }
        } elseif {$both == "1"} {
          if {$rmi(degrees_simulated_start) < $tmp(degrees_simulated_start)} {
            set tmp(degrees_simulated_start) $rmi(degrees_simulated_start)
          }
          if {$rmi(degrees_simulated_stop) > $tmp(degrees_simulated_stop)} {
            set tmp(degrees_simulated_stop) $rmi(degrees_simulated_stop)
          }        
        }
      }
      set rmi(degrees_simulated_start) $tmp(degrees_simulated_start)
      set rmi(degrees_simulated_stop) $tmp(degrees_simulated_stop)
    }
}

proc rmi_CalculateMaxLift {type} {
global rmi

    if {$rmi(intake_motion) && $type == "intake"} {
      set use 1
    } elseif {$rmi(exhaust_motion) && $type == "exhaust"} {
      set use 2
    } else {
      return
    }

    if $rmi(all_${type}_valves) {
      if {$rmi(${type}_lift_fn) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile file before.\n" red
        return     
      }
    } else {
      if {$rmi(${type}_lift_fn,$rmi(current_${type}_valve)) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile $rmi(current_${type}_valve) file before.\n" red
        return     
      }    
    }
    set list ""
    set list [ ic_rmi_comp_max_lift $use \
          $rmi(${type}_lift_fn) \
  	  $rmi(${type}_lift_factor) \
          $rmi(${type}_max_lift) \
          $rmi(${type}_min_lift) \
          $rmi(${type}_valve_nlayers) ]
    if ![ lindex $list 0 ] {
      rmi_ShowMessage "Calculate: Unable to calculate $type max lift location (DCA).\n" red
      return
    }
    set rmi(${type}_max_lift) [ lindex $list 5 ]
    if {$rmi(all_${type}_valves)} {
      for { set i 1 } { $i <= $rmi(${type}_number_valve) } { incr i } {
        set rmi(${type}_max_lift,$i) $rmi(${type}_max_lift)
      }
    } else {
      set rmi(${type}_max_lift,$rmi(current_${type}_valve)) $rmi(${type}_max_lift)
    }
}

proc rmi_CalculateMinLift {type} {
global rmi

    if {$rmi(intake_motion) && $type == "intake"} {
      set use 1
    } elseif {$rmi(exhaust_motion) && $type == "exhaust"} {
      set use 2
    } else {
      return
    }
    if {$rmi(all_${type}_valves)} {
      if {$rmi(${type}_lift_fn) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile file before.\n" red
        return     
      }
    } else {
      if {$rmi(${type}_lift_fn,$rmi(current_${type}_valve)) == ""} {
        rmi_ShowMessage "Calculate: Please load $type valve lift profile $rmi(current_${type}_valve) file before.\n" red
        return     
      }    
    }
    set list ""
    set list [ ic_rmi_comp_max_lift $use \
          $rmi(${type}_lift_fn) \
  	  $rmi(${type}_lift_factor) \
          $rmi(${type}_max_lift) \
          $rmi(${type}_min_lift) \
          $rmi(${type}_valve_nlayers) ]
    if ![ lindex $list 0 ] {
      rmi_ShowMessage "Calculate: Unable to calculate $type min valve lift (mm).\n" red
      return
    }
    set value [ lindex $list 2 ]
    set rmi(${type}_min_lift) [expr $value * 0.01]
    if {$rmi(all_${type}_valves)} {
      for { set i 1 } { $i <= $rmi(${type}_number_valve) } { incr i } {
        set rmi(${type}_min_lift,$i) $rmi(${type}_min_lift)
      }
    } else {
      set rmi(${type}_min_lift,$rmi(current_${type}_valve)) $rmi(${type}_min_lift)
    }
}

proc rmi_SetAskForValveAngle { what w } {
global rmi
   
  set rmi(ask_valve_angle) $what
 
  foreach item $rmi(ValveAngleBitmap) {
    if { [ winfo class $item ] == "Button" } {
      if { $w == $item } {
        $w configure -relief raised -highlightbackground blue -highlightthickness 2
      } else {
        $item configure -relief sunken -highlightthickness 0
      }
    }
  }
}

proc rmi_SetIntakeArray { what w } {
global rmi

  set cur $rmi(current_intake_valve)
  set rmi($what,$cur) [ $w get ]
  if {$what == "intake_max_lift"} {
    rmi_SetMaxLift intake
  }
}

proc rmi_SetExhaustArray { what w } {
global rmi

  set cur $rmi(current_exhaust_valve)
  set rmi($what,$cur) [ $w get ]
  if {$what == "exhaust_max_lift"} {
    rmi_SetMaxLift exhaust
  }
}

proc rmi_ResetLayers {what which} {
global rmi col

  if [ info exists rmi(CursorFromOn) ] {
    set rmi(WhichSettingFrom) $rmi(current_${what}_valve)
    set rmi(WhichSetting) ${which}
    unset rmi(CursorFromOn)
    if ![ string match Windows* [ winfo server . ] ] {
      $rmi(FrameCopyWindow) configure -cursor $rmi(CursorToBitmap)
    }
    set rmi(CursorToOn) 1
    rmi_ShowMessage "\nFROM: Source is $rmi(WhichSetting) $rmi(WhichSettingFrom).\n"
    rmi_ShowMessage "TO: Move the mouse to ONE of the four categories\
   		    (Intake, Exhaust, Combustion dome, or Piston) and click on it.\n"
    return
  }  
  if [ info exists rmi(CursorToOn) ] {
    set rmi(WhichSettingTo) $rmi(current_${what}_valve)
    set rmi(WhichSettingAim) ${which}
    unset rmi(CursorToOn)
    rmi_ShowMessage "\nTO: Destination is $rmi(WhichSettingAim) $rmi(WhichSettingTo).\n"
    rmi_ShowMessage "OK?: Use the middle mouse button to accept copy, right mouse button\
    		     to cancel.\n"
    if ![ string match Windows* [ winfo server . ] ] {
      $rmi(FrameCopyWindow) configure -cursor $rmi(CursorOKBitmap)
    }
    set rmi(CursorOKOn) 1
    return
  }  
    
  set cur $rmi(current_${what}_valve)

### n_layer_below_valve_ 
  
  foreach item {n_smooth_hexa_ use_geometr_set_ diagnostic_ tetra_ref_size_ \
      tetra_violate_geom_ n_cells_in_gap_ n_layers_at_bnd_ n_prism_layers_ \
      n_prism_smoothing_steps_ prism_ratio_ rel_prism_height_ max_prism_angle_ \
      prism_smooth_ratio_ tetra_smooth_ratio_ prismtetra_smooth_ratio_ \
      n_prism_smooth_steps_ n_tetra_smooth_steps_ n_prismtetra_smooth_steps_ duplicate_ \
      single_ single_2_ multiple_ single_multiple_ uncovered_ missing_internal_ \
      triangle_box_ nmanvert_ vol_orient_ surf_orient_ disconnected_vert_ metric_ \
      max_height_below_valve_ n_layer_tip_valve_ n_cells_circumfrential_ clean_tetra_mesh_ \
      n_layers_next_tip_ n_layers_valve_seat_ n_layers_valve_closure_ n_layers_at_lift_ \
      value_layers_at_lift_ exclude_port_valve_closure_ edge1_ edge2_ edge3_ edge4_ \
      edge5_ edge10_ edge11_ edge13_ edge14_ edge15_ vbdyh_ vbdynum_} {
    set rmi($item${what}) $rmi($item${what},$cur)
  }

  foreach item { TetraViolateGeom NLayerBelow MaxHeightLayerBelow \
                 NLayerTip NCellsCircum VBDY} {
    set rmi(${which}$item) $rmi(${which}$item,$cur)    
    if { [ info exists rmi(${which}${item}Button) ] && \
         [ winfo exists $rmi(${which}${item}Button) ] } {
      rmi_OnOffEdit ${which}$item $rmi(${which}${item}Button)
    }
  }
  foreach item $rmi(${which}LayerButtons) {
    $item configure -highlightbackground $col($cur) -highlightthickness 1
  }
  foreach item {Edit EditTetra EditPrism SetDiagnostic EditGeometry} {
    set win Frame${which}$item
    if { [ info exists rmi($win) ] && [ winfo exists $rmi($win) ] } {
      set w $rmi(MaskForm${which}$item)
      $w configure -highlightbackground $col($cur) -highlightthickness 1
    }
  }
  rmi_SetMenuCurrentValve $which $what
  update 
}

proc rmi_SetBackup {what reset which {reset2 ""}} {
global rmi rmiBackup
 
  if {$what == "intake"} {
    set what2 Intake
  } elseif {$what == "exhaust"} {
    set what2 Exhaust
  }
  
  set backup ""; set backup2 ""
### n_layer_below_valve_
  if {$which == "geo"} {
    set backup {max_height_below_valve_ n_layer_tip_valve_ n_cells_circumfrential_ \
      tetra_ref_size_ use_geometr_set_ n_cells_in_gap_ \
      n_layers_next_tip_ n_layers_valve_seat_}
  } elseif {$which == "main"} {
    set backup {n_smooth_hexa_ n_layers_at_bnd_}
  } elseif {$which == "tetra"} {
    set backup {diagnostic_ tetra_violate_geom_ tetra_smooth_ratio_ n_tetra_smooth_steps_ \
      clean_tetra_mesh_}
    set backup2 { TetraViolateGeom }
  } elseif {$which == "prism"} {
    set backup {n_prism_layers_ rel_prism_height_ prism_ratio_ max_prism_angle_ \
      n_prism_smoothing_steps_ prism_smooth_ratio_ n_prism_smooth_steps_ \
      prismtetra_smooth_ratio_ n_prismtetra_smooth_steps_}  
  } elseif {$which == "diagnostic"} {
    set backup {duplicate_ single_  single_2_  multiple_ single_multiple_ \
      uncovered_  missing_internal_ triangle_box_ nmanvert_ vol_orient_ \
      surf_orient_ disconnected_vert_ metric_}  
  }
  if {$reset == "0"} {
    for { set i 1 } { $i <= $rmi(${what}_number_valve) } { incr i } {
      foreach item $backup {      
        set rmiBackup($item${what},$i) $rmi($item${what},$i)
      }
      foreach item $backup2 {
        set rmiBackup(${what2}$item,$i) $rmi(${what2}$item,$i)
      }
    } 
  } elseif {$reset == "1"} {
    set cur $rmi(current_${what}_valve)
    for { set i 1 } { $i <= $rmi(${what}_number_valve) } { incr i } {
      foreach item $backup {
        if {$reset2 == ""} {
          set rmi($item${what},$i) $rmiBackup($item${what},$i)
          unset rmiBackup($item${what},$i)
        } elseif {$reset2 == "reset" && $cur == $i} { 
          set rmi($item${what},$i) $rmiBackup($item${what},$i)
        } 
        if {$cur == $i} {
          set rmi($item${what}) $rmi($item${what},$cur)
        }
      }
      foreach item $backup2 {
        if {$reset2 == ""} {
          set rmi(${what2}$item,$i) $rmiBackup(${what2}$item,$i)
          unset rmiBackup(${what2}$item,$i)
        } elseif {$reset2 == "reset" && $cur == $i} {
          set rmi(${what2}$item,$i) $rmiBackup(${what2}$item,$i)
        }
        if {$cur == $i} {
          set rmi(${what2}$item) $rmi(${what2}$item,$cur) 
          if {$reset2 == "reset"} {
            rmi_OnOffEdit ${what2}$item $rmi(${what2}${item}Button) 
          }        
        }
      }
    } 
  }
}

proc rmi_CheckSettings {} {
global rmi tmp

  set err 0
  rmi_ShowMessage "Checking input information ...\n"
  if !$rmi(ConfigurationSelected) {
    rmi_ShowMessage "No project selected - select project first.\n"
    bell
    return
  }
  set err [rmi_CheckSingleInput]
  if $err {
    rmi_ShowMessage "Found input error(s) ... check red colored fields first.\n"
    bell
    return
  }
  foreach which {intake exhaust} {
    if {$which == "intake"} { set what Intake }
    if {$which == "exhaust"} { set what Exhaust }
    if !$rmi(all_${which}_valves) {
      for {set i 1} {$i <= $rmi(${which}_number_valve)} {incr i} {
        if {($rmi(${which}_lift_fn,$i) == "") && $rmi(${which}_motion)} {
          rmi_ShowMessage "Missing $which valve lift profile $i.\n" red
          $rmi(${what}LiftFnButton) configure -bg red
          set err 1
        } elseif {$rmi(${which}_motion) == "1"} {
          set path $rmi(${which}_lift_fn,$i)
          if ![file exists $path] {
            rmi_ShowMessage "ERROR: $what $i file not found at path <$path>.\n" red
            $rmi(${what}LiftFnButton) configure -bg red
            set err 1
          } else {
            $rmi(${what}LiftFnButton) configure -bg white
          }
        } else {
          $rmi(${what}LiftFnButton) configure -bg white
        }
      }
    } else {
      if {($rmi(${which}_lift_fn) == "") && $rmi(${which}_motion)} {
        rmi_ShowMessage "Missing $which valve lift profile.\n" red
        $rmi(${what}LiftFnButton) configure -bg red
        set err 1
      } elseif {$rmi(${which}_motion) == "1"} {
        set path $rmi(${which}_lift_fn)
        if ![file exists $path] {
          rmi_ShowMessage "ERROR: $what file not found at path <$path>.\n" red
          $rmi(${what}LiftFnButton) configure -bg red
          set err 1
        } else {
          $rmi(${what}LiftFnButton) configure -bg white
        }
      } else {
        $rmi(${what}LiftFnButton) configure -bg white
      }
    }
  }
  if {$rmi(TetinSelected) && $rmi(ConfigurationSelected)} {
    set path $rmi(configuration)/mesh/$rmi(tetin_fn)
    if ![file exists $path] {
      rmi_ShowMessage "ERROR: Tetin file not found at path <$path>.\n" red
      $rmi(TetinFnButton) configure -bg red
      set err 1
    } else {
      $rmi(TetinFnButton) configure -bg white
    }
  }
  if !$rmi(chadice) {
    foreach item {Intake Exhaust} {
      if [info exists tmp($item,warning)] { unset tmp($item,warning) }
    }
    rmi_SetMenuCurrentValve Intake intake
    rmi_SetMenuCurrentValve Exhaust exhaust
    foreach item {Intake Exhaust} {
      if [info exists tmp($item,warning)] { set err 1; unset tmp($item,warning) }
    }
  }
  if $err { bell; return }  
  rmi_ShowMessage "No input errors found.\n"
}

proc rmi_CheckSingleInput {} {
global rmi

  set err 0
  foreach item [ array names rmi CheckOut,* ] {
    set val [ lindex [ split $item , ] 1 ]
    set img [ lindex $rmi(CheckOut,$val) 0 ]
    $img configure -bg white
    set chk [ lindex $rmi(CheckOut,$val) 1 ]
    if { ($val == "intake_valve_nlayers") || ($val == "exhaust_valve_nlayers") } {
      if { ($val == "intake_valve_nlayers") && ($rmi(intake_motion) == "1") } {
        if {($rmi($val) == "") || ![ eval expr $rmi($val) $chk ]} {
          $img configure -bg red
          set err 1
        }
      }
      if { ($val == "exhaust_valve_nlayers") && ($rmi(exhaust_motion) == "1") } {
        if {($rmi($val) == "") || ![ eval expr $rmi($val) $chk ]} {
          $img configure -bg red
          set err 1
        }
      }
      continue
    }
    if { $rmi($val) == "" } {
      set err 1
      set col red
    } else {
      if [ eval expr $rmi($val) $chk ] {
        set col white
      } else {
        set err 1
        set col red
      }
    }
    $img configure -bg $col
  }
  return $err
}

proc rmi_ShowMessage {mess {color ""} {font ""}} {
global rmi rmi_tagnumber batch_mode
  
  if $batch_mode {
    puts -nonewline "$mess"
    return
  }
  if ![info exists rmi(MaskMessage)] {
    mess "$mess" $color $font
    return
  }
  set now [ $rmi(MaskMessage) index "end -1c" ]
  $rmi(MaskMessage) insert end $mess
  if { $color != "" } {
    if ![ info exists rmi_tagnumber ] { 
      set rmi_tagnumber 0
    }
    set tag t[ incr rmi_tagnumber ]
    $rmi(MaskMessage) tag configure $tag -foreground $color
    $rmi(MaskMessage) tag add $tag $now "end - 1c"
  }
  $rmi(MaskMessage) yview end
  update
}

proc rmi_ShowQuestion { what mess } {
global okQuestion

  set win [ toplevel .quest ]
  wm title $win $what
  bind $win <Visibility> "raise $win"
  putcenter $win
  set okQuestion 1

  label $win.l -text $mess -bg white
  frame $win.f -bd 3
  set opts "-relief raised -bd 3 -bg gray -activebackground gray -width 10"
  eval button $win.f.ok -text "Yes" -command \"set okQuestion 1\" $opts
  eval button $win.f.ca -text "No" -command \"set okQuestion 0\" $opts
  pack append $win.f \
       $win.f.ok { left fill expand } \
       $win.f.ca { left fill expand }

  pack $win.l -side top
  pack $win.f -side bottom

  wm resizable $win 0 0   
  grab set $win
  tkwait variable okQuestion
  grab release $win
  destroy $win

  return $okQuestion
}

proc rmi_Quit {} {
global rmi rmiBackup
  
  ic_rmi_del_params
  rmi_CopyCancel
  foreach item [ array names rmi *Frame* ] {
    if [ winfo exists $rmi($item) ] {
      destroy $rmi($item)
    }
  }
  
  if [info exists rmiBackup] { unset rmiBackup }
  
  foreach item [array names rmi CopyParameters,*] {
    unset rmi($item)
  }  
  if [ winfo exists .file_selection ] { destroy .file_selection }
  if [ winfo exists .rmicomputegeo ] {  destroy .rmicomputegeo }
  if [ winfo exists .rmicomputemesh ] { destroy .rmicomputemesh }
  if [ winfo exists .rmicomputegeochadice ] {  destroy .rmicomputegeochadice }
  if [ winfo exists .rmicomputemeshchadice ] { destroy .rmicomputemeshchadice }
  if [ winfo exists .rmioutputmesh ] { destroy .rmioutputmesh }
  if [ winfo exists .rmimeshpreview ] { destroy .rmimeshpreview }
  if [ winfo exists .rmigeometrypreview ] { destroy .rmigeometrypreview }
  if [ winfo exists .rmisteadystatemesh ] { destroy .rmisteadystatemesh }
  if [ winfo exists .rmiselectobjectfile ] { destroy .rmiselectobjectfile }
  if [ winfo exists .rmicomputestations ] { destroy .rmicomputestations }
  if [ winfo exists .rmivalvemeshimage ] { destroy .rmivalvemeshimage }
  if [ winfo exists .rmivalvemeshedge ] { destroy .rmivalvemeshedge }
  if [ winfo exists $rmi(messWindow) ] { destroy $rmi(messWindow) }
  if { $rmi(mainWindow) != "" } {
    destroy $rmi(mainWindow)
    set rmi(mainWindow) ""
  }
  if { $rmi(waitWindow) != "" } {
    destroy $rmi(waitWindow)
    set rmi(waitWindow) ""
    wm deiconify .v
    update
  }
}

proc rmi_OnOffEdit { what w {w2 ""} {w3 ""}} {
global rmi

  switch $what {
    use_geometr_set_intake - diagnostic_intake - tetra_violate_geom_intake -
    clean_tetra_mesh_intake - exclude_port_valve_closure_intake {
      set cur $rmi(current_intake_valve)
      set rmi($what,$cur) $rmi($what)
    }    
    use_geometr_set_exhaust - diagnostic_exhaust - tetra_violate_geom_exhaust -
    clean_tetra_mesh_exhaust - exclude_port_valve_closure_exhaust {
      set cur $rmi(current_exhaust_valve)
      set rmi($what,$cur) $rmi($what)
    }
    IntakeTetraViolateGeom {
      set cur $rmi(current_intake_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        ${w}e configure -state disabled -fg gray
      } else {
        ${w}e configure -state normal -fg black
      }
    }
    ExhaustTetraViolateGeom {
      set cur $rmi(current_exhaust_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        ${w}e configure -state disabled -fg gray
      } else {
        ${w}e configure -state normal -fg black
      }
    }
    CombTetraViolateGeom - PistonTetraViolateGeom {
      if !$rmi($what) {
        ${w}e configure -state disabled -fg gray
      } else {
        ${w}e configure -state normal -fg black
      }
    }
    duplicate_intake - single_intake - single_2_intake -
    multiple_intake - single_multiple_intake - uncovered_intake -
    missing_internal_intake - triangle_box_intake -
    nmanvert_intake - vol_orient_intake - surf_orient_intake -
    disconnected_vert_intake - metric_intake {
      set cur $rmi(current_intake_valve)
      set rmi($what,$cur) $rmi($what)
    }
    duplicate_exhaust - single_exhaust - single_2_exhaust -
    multiple_exhaust - single_multiple_exhaust - uncovered_exhaust -
    missing_internal_exhaust - triangle_box_exhaust -
    nmanvert_exhaust - vol_orient_exhaust - surf_orient_exhaust -
    disconnected_vert_exhaust - metric_exhaust {
      set cur $rmi(current_exhaust_valve)
      set rmi($what,$cur) $rmi($what)
    }
    IntakeNLayerBelow - IntakeMaxHeightLayerBelow -
    IntakeNLayerTip - IntakeNCellsCircum {
      set cur $rmi(current_intake_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        ${w}e configure -state disabled -fg gray
      } else {
        ${w}e configure -state normal -fg black
      }
      if {$what == "IntakeNLayerBelow"} {
        for { set i 1 } { $i <= $rmi(intake_number_valve) } { incr i } {
          set rmi($what,$i) $rmi($what)
          set rmi(n_layer_below_valve_intake,$i) $rmi(n_layer_below_valve_intake)
          if !$rmi($what) {
            ${w}e configure -state disabled -fg gray
          } else {
            ${w}e configure -state normal -fg black
          }
        }
      }
    }
    ExhaustNLayerBelow - ExhaustMaxHeightLayerBelow -
    ExhaustNLayerTip - ExhaustNCellsCircum {
      set cur $rmi(current_exhaust_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        ${w}e configure -state disabled -fg gray
      } else {
        ${w}e configure -state normal -fg black
      }
      if {$what == "ExhaustNLayerBelow"} {
        for { set i 1 } { $i <= $rmi(exhaust_number_valve) } { incr i } {
          set rmi($what,$i) $rmi($what)
          set rmi(n_layer_below_valve_exhaust,$i) $rmi(n_layer_below_valve_exhaust)
          if !$rmi($what) {
            ${w}e configure -state disabled -fg gray
          } else {
            ${w}e configure -state normal -fg black
          }
        }
      }
    }
    IntakeVBDY {
      set cur $rmi(current_intake_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        $w configure -state normal -fg black
        ${w}e configure -state normal -fg black
        $w2 configure -state disabled -fg gray
        ${w2}e configure -state disabled -fg gray
        $w3 configure -state disabled -fg gray
        ${w3}e configure -state disabled -fg gray
      } else {
        $w configure -state disabled -fg gray
        ${w}e configure -state disabled -fg gray
        $w2 configure -state normal -fg black
        ${w2}e configure -state normal -fg black
        $w3 configure -state normal -fg black
        ${w3}e configure -state normal -fg black
      }
    }
    ExhaustVBDY {
      set cur $rmi(current_exhaust_valve)
      set rmi($what,$cur) $rmi($what)
      if !$rmi($what) {
        $w configure -state normal -fg black
        ${w}e configure -state normal -fg black
        $w2 configure -state disabled -fg gray
        ${w2}e configure -state disabled -fg gray
        $w3 configure -state disabled -fg gray
        ${w3}e configure -state disabled -fg gray
      } else {
        $w configure -state disabled -fg gray
        ${w}e configure -state disabled -fg gray
        $w2 configure -state normal -fg black
        ${w2}e configure -state normal -fg black
        $w3 configure -state normal -fg black
        ${w3}e configure -state normal -fg black
      }
    }
  }
}

proc rmi_GetPid { pid } {
global rmi

  set list [ split [ exec ps ] \n ]
  for { set i 1 } { $i < [ expr [ llength $list ] ] } { incr i } {
    set p [ lindex [ lindex $list $i ] 0 ]
    if { $p == $pid } {
      return 1
    }
  }
  return 0
}

proc rmi_CalculateTetraRefSize { what } {
global rmi
  
  set err_calc 0
  if { $what == "comb" || $what == "piston" } {
    if { $rmi(number_layers_cyl_BDC) == "0" } {
      rmi_ShowMessage "Calculate: Wrong value for mesh layers at BDC.\n" red
      return
    }
    set calc_it $rmi(stroke_length)
    if ![ string match *.* $rmi(stroke_length) ] { 
      append calc_it ".0"
    }
    set rmi(tetra_ref_size_${what}) [ expr 0.5 * [ expr $calc_it \
    				/ $rmi(number_layers_cyl_BDC) ] ]
    return
  } else {
    if { $rmi(${what}_lift_fn) == "" } {
      set err_calc 1
      set err_mess $what
    }
  }
  if $err_calc {
    rmi_ShowMessage "Calculate: Please load $err_mess valve lift profile file before.\n" red
    return
  }

  if { $what == "intake" } {
    set cur $rmi(current_intake_valve)
    set on 1
  }
  if { $what == "exhaust" } {
    set cur $rmi(current_exhaust_valve)
    set on 2
  }
  set list [ ic_rmi_comp_max_lift $on \
  		$rmi(${what}_lift_fn) \
  		$rmi(${what}_lift_factor) \
                $rmi(${what}_max_lift) \
                $rmi(${what}_min_lift) \
                $rmi(${what}_valve_nlayers) ]
  if [ lindex $list 0 ] {
    set rmi(tetra_ref_size_${what}) [ lindex $list 1 ]
    set rmi(tetra_ref_size_${what},$cur) $rmi(tetra_ref_size_${what})
  } else {
    rmi_ShowMessage "Unable to calculate Tetra Reference Size.\n" red
  }
}

proc rmi_CopyOnOff { w } {
global rmi 
  
  if { $rmi(WhichSetting) == "Intake" ||  $rmi(WhichSetting) == "Exhaust" } {
    foreach item $rmi(WhichSettingButtons) {
      $item configure -state disabled
    }
    set rmi(WhichSettingTo) 1
    $w configure -text "$rmi(WhichSettingAim) $rmi(WhichSettingTo)" -state normal
  }
}

proc rmi_CopySetting {} {
global rmi 
  
  if ![ info exists rmi(WhichSetting) ] {
    rmi_ShowMessage "\nUnable to copy. No source selected.\n"
    rmi_CopyCancel
    return 
  }   
  if ![ info exists rmi(WhichSettingAim) ] {
    rmi_ShowMessage "\nUnable to copy. No destination selected.\n"
    rmi_CopyCancel
    return
  }

  if { ($rmi(WhichSetting) == $rmi(WhichSettingAim)) && \
       ($rmi(WhichSettingFrom) == $rmi(WhichSettingTo)) } {
    rmi_ShowMessage "\nUnable to copy. Source and destination are the same.\n"
    rmi_CopyCancel
    return
  }


  if { $rmi(WhichSetting) == "Intake" } {
    set from intake
  } elseif { $rmi(WhichSetting) == "Exhaust" } {
    set from exhaust
  } elseif { $rmi(WhichSetting) == "Combustion dome" } {
    set from comb
  } elseif { $rmi(WhichSetting) == "Piston" } {
    set from piston
  }
  if { $rmi(WhichSettingAim) == "Intake" } {
    set to intake
  } elseif { $rmi(WhichSettingAim) == "Exhaust" } {
    set to exhaust
  } elseif { $rmi(WhichSettingAim) == "Combustion dome" } {
    set to comb
  } elseif { $rmi(WhichSettingAim) == "Piston" } {
    set to piston
  }

  rmi_ShowMessage "Copy $rmi(WhichSetting) $rmi(WhichSettingFrom)\
		   to $rmi(WhichSettingAim) $rmi(WhichSettingTo) ... "
  
  if {$rmi(WhichSetting) == "Intake" || $rmi(WhichSetting) == "Exhaust"} {
    foreach item $rmi(CopyParameters,$from) {
      if {$rmi(WhichSettingAim) == "Combustion dome" || $rmi(WhichSettingAim) == "Piston"} {
	if [ info exists rmi(${item}$to) ] {
	  set rmi(${item}$to) $rmi(${item}${from},$rmi(WhichSettingFrom))
	}
      } elseif {$rmi(WhichSettingAim) == "Intake" || $rmi(WhichSettingAim) == "Exhaust"} {
        if [ info exists rmi(${item}${to},$rmi(WhichSettingTo)) ] {
          set rmi(${item}${to},$rmi(WhichSettingTo)) $rmi(${item}${from},$rmi(WhichSettingFrom))
          set rmi(${item}${to}) $rmi(${item}${from},$rmi(WhichSettingFrom))
        }
      }
    }
    if { $to == "intake" } { set to Intake }
    if { $to == "exhaust" } { set to Exhaust }
    if { $to == "comb" } { set to Comb }
    if { $to == "piston" } { set to Piston }
    if { $from == "intake" } { set from Intake }
    if { $from == "exhaust" } { set from Exhaust }
    if { $from == "comb" } { set from Comb }
    if { $from == "piston" } { set from Piston }
    foreach item $rmi(CopyParameters,$from) {
      if { $rmi(WhichSettingAim) == "Combustion dome" || $rmi(WhichSettingAim) == "Piston"} {
        if [ info exists rmi($to$item) ] {
          set rmi($to$item) $rmi(${from}$item,$rmi(WhichSettingFrom))         
        }
      } elseif {$rmi(WhichSettingAim) == "Intake" || $rmi(WhichSettingAim) == "Exhaust"} {
        if [ info exists rmi($to${item},$rmi(WhichSettingTo)) ] {
          set rmi($to${item},$rmi(WhichSettingTo)) $rmi(${from}${item},$rmi(WhichSettingFrom))
          set rmi($to${item}) $rmi(${from}${item},$rmi(WhichSettingFrom))
        }
      }
    }
  }

  if {$rmi(WhichSetting) == "Combustion dome" || $rmi(WhichSetting) == "Piston"} {
    foreach item $rmi(CopyParameters,$from) {
      if {$rmi(WhichSettingAim) == "Combustion dome" || $rmi(WhichSettingAim) == "Piston"} {
	if [ info exists rmi(${item}$to) ] {
	  set rmi(${item}$to) $rmi(${item}${from})
	}
      } elseif {$rmi(WhichSettingAim) == "Intake" || $rmi(WhichSettingAim) == "Exhaust"} {
        if [ info exists rmi(${item}${to},$rmi(WhichSettingTo)) ] {
          set rmi(${item}${to},$rmi(WhichSettingTo)) $rmi(${item}${from})
          set rmi(${item}${to}) $rmi(${item}${from})
        }
      }
    }
    if { $to == "intake" } { set to Intake }
    if { $to == "exhaust" } { set to Exhaust }
    if { $to == "comb" } { set to Comb }
    if { $to == "piston" } { set to Piston }
    if { $from == "intake" } { set from Intake }
    if { $from == "exhaust" } { set from Exhaust }
    if { $from == "comb" } { set from Comb }
    if { $from == "piston" } { set from Piston }
    foreach item $rmi(CopyParameters,$from) {
      if { $rmi(WhichSettingAim) == "Combustion dome" || $rmi(WhichSettingAim) == "Piston"} {
        if [ info exists rmi($to$item) ] {
          set rmi($to$item) $rmi(${from}$item)         
        }
      } elseif {$rmi(WhichSettingAim) == "Intake" || $rmi(WhichSettingAim) == "Exhaust"} {
        if [ info exists rmi($to${item},$rmi(WhichSettingTo)) ] {
          set rmi($to${item},$rmi(WhichSettingTo)) $rmi(${from}${item})
          set rmi($to${item}) $rmi(${from}${item})
        }
      }
    }
  }

  rmi_ShowMessage "done.\n" 
  rmi_CopyCancel 
}

proc rmi_CopyStart {{geo ""}} {
global rmi 

  foreach item [ array names rmi WhichSetting* ] {
    unset rmi($item)
  }

  if {$geo == "geo"} {
    set rmi(FrameCopyWindow) $rmi(FrameEditGeometry)
    foreach item { intake exhaust comb piston } {
      if [ winfo exists .rmieditgeometry$item ] {
        destroy .rmieditgeometry$item
      }
    }
  } else {
    set rmi(FrameCopyWindow) $rmi(mainWindow)
    foreach item { intake exhaust comb piston } {
      if [ winfo exists .rmiedit$item ] {
        destroy .rmiedit$item
      }
    }
  }
  if ![ string match Windows* [ winfo server . ] ] {
    $rmi(FrameCopyWindow) configure -cursor $rmi(CursorFromBitmap)
  }
  bind $rmi(FrameCopyWindow) <ButtonRelease-2> { rmi_CopySetting }
  bind $rmi(FrameCopyWindow) <ButtonRelease-3> { rmi_CopyCancel cancel }
  set rmi(CursorFromOn) 1
  rmi_ShowMessage "FROM: Move the mouse to ONE of the four categories\
   		   (Intake, Exhaust, Combustion dome, or Piston) and click\
   		   on it.\n"
}

proc rmi_CopyActive { what } {
global rmi
  
  if [ info exists rmi(CursorFromOn) ] {
    set rmi(WhichSettingFrom) ""
    if { $what == "intake" } {
      set rmi(WhichSettingFrom) $rmi(current_intake_valve)
      set which Intake
    } elseif { $what == "exhaust" } {
      set rmi(WhichSettingFrom) $rmi(current_exhaust_valve)
      set which Exhaust
    } elseif { $what == "comb" } {
      set which "Combustion dome"
    } elseif { $what == "piston" } {
      set which Piston
    }
    set rmi(WhichSetting) $which
    unset rmi(CursorFromOn)
    if ![ string match Windows* [ winfo server . ] ] {
      $rmi(FrameCopyWindow) configure -cursor $rmi(CursorToBitmap)
    }
    set rmi(CursorToOn) 1
    rmi_ShowMessage "\nFROM: Source is $rmi(WhichSetting) $rmi(WhichSettingFrom).\n"
    rmi_ShowMessage "\nTO: Move the mouse to ONE of the four categories\
   		    (Intake, Exhaust, Combustion dome, or Piston) and click on it.\n"
    return 1
  }
  if [ info exists rmi(CursorToOn) ] {
    set rmi(WhichSettingTo) ""
    if { $what == "intake" } {
      set rmi(WhichSettingTo) $rmi(current_intake_valve)
      set which Intake
    } elseif { $what == "exhaust" } {
      set rmi(WhichSettingTo) $rmi(current_exhaust_valve)
      set which Exhaust
    } elseif { $what == "comb" } {
      set which "Combustion dome"
    } elseif { $what == "piston" } {
      set which Piston
    }
    set rmi(WhichSettingAim) $which
    unset rmi(CursorToOn)
    rmi_ShowMessage "\nTO: Destination is $rmi(WhichSettingAim) $rmi(WhichSettingTo).\n"
    rmi_ShowMessage "\nOK?: Use the middle mouse button to accept copy, right mouse button\
    		     to cancel.\n"
    if ![ string match Windows* [ winfo server . ] ] {
      $rmi(FrameCopyWindow) configure -cursor $rmi(CursorOKBitmap)
    }
    set rmi(CursorOKOn) 1
    return 1
  }
  return 0
}

proc rmi_CopyCancel { { what "" } } {
global rmi

  if {$what == "cancel"} {
    rmi_ShowMessage "Copy abort.\n"
  }
  
  if [info exists rmi(FrameCopyWindow)] {
    if [winfo exists $rmi(FrameCopyWindow)] {
      if ![ string match Windows* [ winfo server . ] ] {
        $rmi(FrameCopyWindow) configure -cursor $rmi(CursorBitmap)
      }
      bind $rmi(FrameCopyWindow) <ButtonRelease-2> {}
      bind $rmi(FrameCopyWindow) <ButtonRelease-3> {}
      unset rmi(FrameCopyWindow)
    }
  }
  
  if [info exists rmi(CursorFromOn)] {
    unset rmi(CursorFromOn)
  }
  if [info exists rmi(CursorToOn)] {
    unset rmi(CursorToOn)
  }
  if [info exists rmi(CursorOKOn)] {
    unset rmi(CursorOKOn)
  }
  foreach item [array names rmi WhichSetting*] {
    unset rmi($item)
  }
}

proc rmi_SortBy {} {
  global is_win
  if !$is_win {
    set sort_by "-dictionary"
  } else {
    set sort_by "-ascii"
  }
  return $sort_by
}

proc rmi_SetMenuCurrentValve {what which} {
global rmi tmp
  
  if $rmi(chadice) { return }

  if $rmi(all_${which}_valves) {
    $rmi(${what}CurrentValveMenuButton) configure -state disabled -fg gray
    $rmi(${what}LiftFnButton) configure -highlightthickness 1 -highlightbackground white
    $rmi(${what}MaxLiftButton) configure -highlightthickness 1 -highlightbackground white
    for {set i 1} {$i <= $rmi(${which}_number_valve)} {incr i} {    
      set file$i $rmi(${which}_lift_fn,$i)
    }
    set different 0
    if {$rmi(${which}_number_valve) == "2" || $rmi(${which}_number_valve) == "3"} {
      if {$file1 != $file2} {
        set different 1
      }
      if {$rmi(${which}_number_valve) == "3" } {
        if {$file1 != $file3} {
          set different 2
        }
        if {$file2 != $file3} {
          set different 3
        }
      }
    }
    if $different {
      if ![info exists tmp($what,warning)] {
        if $rmi(${which}_motion) {
          rmi_ShowMessage "WARNING: \"Current ${which} valve\" is set to \"All valves\" but\
            there are different or missing \"${what} valve lift profile file\" values. \
            They should be all the same.\n" red
          set tmp($what,warning) 1
        }
      }
    }
    return
  } else {
     set num 0
     if {$rmi(intake_motion) == "1"} { set num 1 }
     if {$rmi(exhaust_motion) == "1"} { set num 2 }
     if {$rmi(intake_motion) == "1" && $rmi(exhaust_motion) == "1"} { set num 3 }
     if {$num != "0" && (($which == "intake" && $num == "1") || \
     	($which == "exhaust" && $num == "2") || $num == "3")} {
      set button $rmi(${what}CurrentValveMenuButton)
      $button configure -state active -text $rmi(current_${which}_valve) -fg black
      rmi_SetCurrentLiftValve $what $which
      if [info exists tmp($what,warning)] { unset tmp($what,warning) }
    }
  }
  
  if {$rmi(${which}_number_valve) == "2" || $rmi(${which}_number_valve) == "3"} {
    $rmi(${what}CurrentValveButton) entryconfigure 1 -state active
    if {$rmi(${which}_number_valve) == "3" } {
      $rmi(${what}CurrentValveButton) entryconfigure 2 -state active
    } elseif {$which == "intake"} {
      $rmi(${what}CurrentValveButton) entryconfigure 2 -state disabled
    }
  } else {
    $rmi(${what}CurrentValveButton) entryconfigure 1 -state disabled
    if {$which == "intake"} {
      $rmi(${what}CurrentValveButton) entryconfigure 2 -state disabled
    }
  }
}

proc rmi_SetCurrentLiftValve {what which} {
global rmi col
  
  if $rmi(chadice) { return }
  
  set cur $rmi(current_${which}_valve)
  set rmi(${which}_lift_fn) $rmi(${which}_lift_fn,$cur)
  set rmi(${which}_max_lift) $rmi(${which}_max_lift,$cur)
  $rmi(${what}LiftFnButton) configure -highlightbackground $col($cur) -highlightthickness 1
  $rmi(${what}MaxLiftButton) configure -highlightbackground $col($cur) -highlightthickness 1
}

proc rmi_SetMaxLift {which} {
global rmi
  
  if $rmi(chadice) { return }
  if !$rmi(all_${which}_valves) { return }
  
  set what $rmi(${which}_max_lift,$rmi(current_${which}_valve))
  set rmi(${which}_max_lift) $what
  for { set i 1 } { $i <= $rmi(${which}_number_valve) } { incr i } {
    set rmi(${which}_max_lift,$i) $what
  }
}

proc rmi_print_image {args} {
    global hardcopy job_name job_title tdv_default 
    
    set hardcopy(top_current) .v
    set hardcopy(sub_current) $tdv_default
    set hardcopy(startcmd_current) ""
    set hardcopy(endcmd_current) ""
    set job_name unknown
    set job_title unknown
    
    foreach {n v} $args { set hardcopy($n) $v }
    hardcopy_create
}

proc rmi_CalculateTimestep {type} {
    global rmi
    
    switch $type {
      time_step {
        set rmi(time_step) [expr $rmi(time_step_dca) / ($rmi(engine_RPM) * 6.0)]
      }
      engine_RPM {
        set rmi(engine_RPM) [expr $rmi(time_step_dca) / ($rmi(time_step) * 6.0)]
      }
    }
    rmi_XviewEnd
}
