#source "C:/Archivos de programa/TclPro1.2/win32-ix86/bin/prodebug.tcl"
#debugger_init

#!/bin/sh
#DataWindows  -*- TCL -*- Created: ramsan May-1999, Modified: ramsan May-1999


#----------------------DataWindows ALONE---------------------------
# the next line restarts using wish \
	exec wish8.0 "$0" "$@"

catch {
    LoadDebugger
}

set DataWindowsRunningAlone 0
catch {
    if {$argv0 == [info script] } {
	 set DataWindowsRunningAlone 1
	 set tcl_interactive 0
	 set tk_strictMotif 1
	
	 if { [catch { set GIDDEFAULT $env(GIDDEFAULT)}]!=1 } {
	     set GIDDEFAULTTCL $GIDDEFAULT
	     catch { set GIDDEFAULTTCL $env(GIDDEFAULTTCL) }
	     source $GIDDEFAULTTCL/init.tcl
	     source $GIDDEFAULTTCL/tk.tcl
	 }
	 wm withdraw .
    }
}

#--------------------------------------General. For all of them---------

image create bitmap DownImage -data {
#define downbut_width 14
#define downbut_height 14
static char downbut_bits[] = {
   0x00, 0x00, 0xe0, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xe0, 0x01, 0xfc, 0x0f,
   0xf8, 0x07, 0xf0, 0x03, 0xe0, 0x01, 0xc0, 0x00, 0x00, 0x00, 0xfe, 0x1f,
   0xfe, 0x1f, 0x00, 0x00};
}

image create bitmap UpImage -data {
#define upbut_bits_width 14
#define upbut_bits_height 14
static unsigned char upbut_bits_bits[] = {
   0x00, 0x00, 0xfe, 0x1f, 0xfe, 0x1f, 0x00, 0x00, 0xc0, 0x00, 0xe0, 0x01,
   0xf0, 0x03, 0xf8, 0x07, 0xfc, 0x0f, 0xe0, 0x01, 0xe0, 0x01, 0xe0, 0x01,
   0xe0, 0x01, 0x00, 0x00};
}

image create bitmap LeftImage -data {
#define leftbut_bits_width 14
#define leftbut_bits_height 14
static unsigned char leftbut_bits_bits[] = {
   0x00, 0x00, 0x06, 0x00, 0x06, 0x01, 0x86, 0x01, 0xc6, 0x01, 0xe6, 0x1f,
   0xf6, 0x1f, 0xf6, 0x1f, 0xe6, 0x1f, 0xc6, 0x01, 0x86, 0x01, 0x06, 0x01,
   0x06, 0x00, 0x00, 0x00};
}

image create bitmap RightImage -data {
#define rightbut_bits_width 14
#define rightbut_bits_height 14
static unsigned char rightbut_bits_bits[] = {
   0x00, 0x00, 0x00, 0x18, 0x20, 0x18, 0x60, 0x18, 0xe0, 0x18, 0xfe, 0x19,
   0xfe, 0x1b, 0xfe, 0x1b, 0xfe, 0x19, 0xe0, 0x18, 0x60, 0x18, 0x20, 0x18,
   0x00, 0x18, 0x00, 0x00};
}

image create bitmap CloseImage -data {
#define closebut_bits_width 14
#define closebut_bits_height 14
static unsigned char closebut_bits_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x18, 0x0c, 0x30, 0x06, 0x60, 0x03,
   0xc0, 0x01, 0xc0, 0x01, 0x60, 0x03, 0x30, 0x06, 0x18, 0x0c, 0x0c, 0x18,
   0x00, 0x00, 0x00, 0x00};
}

proc CheckCnd { } {
    set TypeList { ovpnt ovline ovsurf ovvol ovlayer }
    
    foreach Type $TypeList {
	set CndNameList [.central.s info conditions $Type]
	if { [llength $CndNameList] } {
	    return $Type
	}
    }
    return ""
}

proc CheckMat { } {
    set MatList [.central.s info materials]
    
    if { [llength $MatList] } {
	return 1
    } else {
	return ""
    }
}

proc CheckIntv { } {
    set PropList [.central.s info intvdata]
    if { [llength $PropList] > 1 } {
	return 1
    } else {
	return ""
    }
}

proc CheckPrbD { } {
    set PropList [.central.s info gendata]
    if { [llength $PropList] > 1 } {
	return 1
    } else {
	return ""
    }
}

proc PostDataMenu { w } {
    global MenuDataEntries MenuDataCommands MenuDataAcc GidPriv
    global gidDataLabels gidDataCommands
    
    if { $GidPriv(POSTDATA) == 0 } {
	return
    }

    catch { unset MenuDataEntries MenuDataCommands }
    
    ClearMenu $w


    set UnderChars {}
    set IdxForData 0
    set num_opt_added 0
    set entries [list [_ "Problem type"] [_ "Data units"] [_ "Interval"] [_ "Local axes"]]
    set commands {"Problem type" "Data units" "Interval" "Local axes"}
    foreach opt $commands optlabel $entries {
	if ![info exists gidDataLabels($opt)] continue
	if { $opt == "Data units" && \
		 ([info exists GidPriv(PRBTYPE,NAME)] && $GidPriv(PRBTYPE,NAME) != "" && \
		      ![.central.s info unitssystems]) } continue
	set pos_opt($opt) $num_opt_added
	lappend MenuDataEntries(0) $optlabel
	lappend MenuDataCommands(0) $gidDataCommands($opt)
	lappend MenuDataEntries(0) "---"
	lappend MenuDataCommands(0) ""
	lappend UnderChars [string tolower [string index $opt 0]]
	incr num_opt_added
    }
    if { $num_opt_added } {
	set MenuDataEntries(0) [lrange $MenuDataEntries(0) 0 [expr [llength $MenuDataEntries(0)] - 2]]
	set MenuDataCommands(0) [lrange $MenuDataCommands(0) 0 \
		                     [expr [llength $MenuDataCommands(0)] - 2]]
    }

    if [info exists "gidDataLabels(Problem type)"] {
	set MenuDataEntries(0,0) ""
	set IdxForData 2
    }

    if [info exists gidDataLabels(Interval)] {
	set idx_opt [expr "$pos_opt(Interval)" * 2]
	set MenuDataEntries(0,$idx_opt) [list [_ "New"] [_ "Current"] [_ "Delete"]]
	set MenuDataCommands(0,$idx_opt) {"Data Intervals NewInterval" "Data Intervals ChangeInterval" \
		                                         "Data Intervals DeleteInterval"}
    }

    if [info exists "gidDataLabels(Local axes)"] {
	set idx_opt [expr "$pos_opt(Local axes)" * 2]
	set MenuDataEntries(0,$idx_opt) [list [_ "Define"] [_ "Draw"] [_ "Draw all"] [_ "Delete"] [_ "Delete all"]]
	set MenuDataCommands(0,$idx_opt) {"Data LocalAxes DefineLocAxes" \
		"Data LocalAxes DrawLocAxes" "Data LocalAxes DrawLocAxes -All-" \
		"Data LocalAxes DeleteLA" "Data LocalAxes DeleteAllLA"}
    }
    
    if { $num_opt_added } {
	CreateCascadedMenu $w MenuDataEntries MenuDataCommands "" 0
    }

    UpdateDataOptions $w $IdxForData $UnderChars

    set GidPriv(POSTDATA) 0
}

proc FindUnderChar { Label ListName } {
    upvar $ListName UnderChars

    set icFound 0
    for {set UnderIdx 0 } { $UnderIdx < [string length $Label]} { incr UnderIdx } {
	set letter [string tolower [string index $Label $UnderIdx]]
	if { ![regexp {[0-9a-z]} $letter] } { continue }
	if { [lsearch $UnderChars $letter] == -1 } {
	    lappend UnderChars $letter
	    set icFound 1
	    break
	}
    }
    if !$icFound {
	set UnderIdx -1
    }
    return $UnderIdx
}

proc GidUpdateUserDataOptions { UnderChars } {
    global gidUserDataOptions
    global DataMenuInfo

    set wmenu_data $DataMenuInfo(menu)

    if ![info exists gidUserDataOptions] {
	set gidUserDataOptions {}
    }

    foreach opt $gidUserDataOptions {
	if { [llength $opt] == 1 } {
	    $wmenu_data insert $opt separator
	} elseif { [llength $opt] == 5 } {
	    set Label [lindex $opt 0]
	    set UnderIdx [FindUnderChar $Label UnderChars]
	    set i 1
	    while { [winfo exists $wmenu_data.m$i] } { incr i }
	    set menu [menu $wmenu_data.m$i]
	    regsub -all {([^%]|^)%W} [lindex $opt 1] "\\1$menu" Action
	    $menu configure -postcommand $Action
	    set Where [lindex $opt 2]
	    if { $Where == "end" } {
		$wmenu_data add cascade -label $Label -underline $UnderIdx \
		    -menu $menu
		set Where [$wmenu_data index end]
	    } else {
		$wmenu_data insert $Where cascade -label $Label -underline $UnderIdx \
		    -menu $menu
	    }
	} else {
	    set Label [lindex $opt 0]
	    set UnderIdx [FindUnderChar $Label UnderChars]
	    set Action [lindex $opt 1]
	    set Where [lindex $opt 2]
	    set Accel [lindex $opt 3]
	    if { $Where == "end" } {
		$wmenu_data add command -label $Label -command $Action -underline $UnderIdx
		set Where [$wmenu_data index end]
	    } else {
		$wmenu_data insert $Where command -label $Label -command $Action -underline $UnderIdx
	    }
	    AddAccelerator $Accel $wmenu_data $Where
	}
    }
}

proc DWInitUserDataOptions {} {

    global gidUserDataOptions
    global gidDataLabels
    global gidDataCommands
    global gidDataBooksHidden

    set gidUserDataOptions {}
    foreach dl {"Problem type" "Data units" "Interval" "Local axes" "Conditions" "Materials" \
	    "Interval Data" "Problem Data"} {
	set gidDataLabels($dl) ""
	set gidDataLabels($dl,singular) ""
    }
    array set gidDataCommands {
	"Problem type" "-np- SetProblemTypeMenu %W"
	"Data units" "-np- DWDataUnits"
	"Interval" ""
	"Local axes" ""
    }

     array set gidDataBooksHidden {
	 "conditions" ""
	 "materials"  ""
	 "intvdata"   "" 
	 "gendata"    ""
     }
}

proc ShowDefaultDataInfo { } {
    WarnWin [_ "Conditions, Materials, Interval data and Problem data are option available only when defined inside a problem type"]
}

proc SetDefaultDataMenu { DataMenu IndexEntry } {
    set DataEntry [list [list [_ "Conditions"] 0] \
	    [list [_ "Materials"] 0] \
	    [list [_ "Interval Data"] 1] \
	    [list [_ "Problem Data"] 1]]

    foreach me $DataEntry {
	set Label    [lindex $me 0]
	set UnderIdx [lindex $me 1]
	$DataMenu insert $IndexEntry command -label $Label -command ShowDefaultDataInfo \
		       -underline $UnderIdx 
	incr IndexEntry
    }
}

proc UpdateDataOptions { DataMenu IndexEntry UnderChars } {
  global DataMenuInfo gidDataLabels GidPriv
  global gidDataBooksHidden
  
  # set GidPriv(PRBTYPE,NAME) [lindex [.central.s info project] 0]
  if { ![info exists GidPriv(PRBTYPE,NAME)] || $GidPriv(PRBTYPE,NAME) == "" } {
    SetDefaultDataMenu $DataMenu $IndexEntry
    return
  }
  
  set DataEntry [list [list 1 [_ "Conditions"] "Conditions" DWCondWindow conditions CheckCnd 0] \
		     [list 2 [_ "Materials"] "Materials" DWMatWindow materials CheckMat 0] \
		     [list 3 [_ "Interval Data"] "Interval Data" DWIntervalDataWindow intvdata CheckIntv 1] \
		     [list 4 [_ "Problem Data"] "Problem Data" DWProblemDataWindow gendata CheckPrbD 0]]
  
  #set IndexEntry 4
  
  catch {
    unset DataMenuInfo
  }
  
  set DataMenuInfo(menu) $DataMenu
  
  # Precondición: END
  
  foreach m $DataEntry {
    set Class [lindex $m 2]
    
    if ![info exists gidDataLabels($Class)] continue
    
    if { $gidDataLabels($Class) == "" } {
      set ClassLabel  [lindex $m 1]
    } else {
      set ClassLabel $gidDataLabels($Class)
    }
    set Cmd [lindex $m 3]
    set AskBook [lindex $m 4]
    set CheckFunc [lindex $m 5]
    set UnderIdx [lindex $m 6]
    
    if { [eval $CheckFunc] != "" } {
      set Books [.central.s info $AskBook BOOKS]
      
      set nBooks [llength $Books]
      set DataMenuInfo($Class,COUNTER) 0
      set DataMenuInfo($Class,entry) $IndexEntry
      if { $nBooks == 0 } {
	set DataMenuInfo($Class) {Default}
	$DataMenu insert $IndexEntry command -label $ClassLabel -command "$Cmd" \
	    -underline $UnderIdx 
	#$DataMenu add command -label $Class -command "$Cmd"
      } else {
	set SubMenu $DataMenu.$AskBook
	catch { destroy $SubMenu }
	$DataMenu insert $IndexEntry cascade -label $ClassLabel -menu $SubMenu \
	    -underline $UnderIdx
	#$DataMenu add cascade -label $Class -menu $SubMenu
	menu $SubMenu
	set DataMenuInfo($Class,submenu) $SubMenu
	set i 0
	set BookOrd 1
	set UnderCharsLocal {}
	set hidden 0
	foreach e $Books {
	  if { $i == 0 } {
	    if { [lsearch $gidDataBooksHidden($AskBook) $e] == -1 } {
	      lappend DataMenuInfo($Class) $e
	      set book $e
	    } else {
	      set hidden 1
	    }
	    set i 1
	  } else {
	    set i 0
	    if !$hidden {
	      set icFound 0
	      set Label [= [DWUnder2Space $book]]
	      for {set UnderIdx 0 } { $UnderIdx < [string length $Label]} { incr UnderIdx } {
		set letter [string tolower [string index $Label $UnderIdx]]
		if { ![regexp {[0-9a-z]} $letter] } { continue }
		if { [lsearch $UnderCharsLocal $letter] == -1 } {
		  lappend UnderCharsLocal $letter
		  set icFound 1
		  break
		}
	      }
	      if !$icFound {
		set UnderIdx -1
	      }
	      $SubMenu add command -label $Label \
		  -command "$Cmd [list $book] $BookOrd" -underline $UnderIdx
	    } else {
	      set hidden 0
	    }
	    incr BookOrd
	  }
	}
      }
      incr IndexEntry
    }
  }
  
  GidUpdateUserDataOptions $UnderChars
}

proc GetDataBooks { name } {

    upvar $name rname

    set DataEntry [list [list 1 [_ "Conditions"] "Conditions" DWCondWindow conditions CheckCnd] \
	    [list 2 [_ "Materials"] "Materials" DWMatWindow materials CheckMat] \
	    [list 3 [_ "Interval Data"] "Interval Data" DWIntervalDataWindow intvdata CheckIntv] \
	    [list 4 [_ "Problem Data"] "Problem Data" DWProblemDataWindow gendata CheckPrbD]]
    

    foreach m $DataEntry {
	set ClassLabel [lindex $m 1]
	set Class [lindex $m 2]
	set Cmd [lindex $m 3]
	set AskBook [lindex $m 4]
	set CheckFunc [lindex $m 5]

	if { [eval $CheckFunc] != "" } {
	    set Books [.central.s info $AskBook BOOKS]
	    
	    set nBooks [llength $Books]
	    set rname($Class,COUNTER) 0
	    if { $nBooks == 0 } {
		set rname($Class) {Default}
	    } else {
		set i 0
		set BookOrd 1
		foreach e $Books {
		    if { $i == 0 } {
		        lappend rname($Class) $e
		        set i 1
		    } else {
		        set i 0
		    }
		}
	    }
	}
    }
}

# revisa por que tienes que hacer esto
set ::gidSubstDataBooks 0

proc SubstDataBooks { } {
    global gidSubstDataBooks

    set gidSubstDataBooks 1

    if { [info exists ::ModUnitWin::win] && [winfo exists $::ModUnitWin::win] } {
	destroy $::ModUnitWin::win
    }

    GetDataBooks rBooks
    
    set ListGDN [info globals GD_*]
    
    foreach GDN $ListGDN {
	upvar \#0 $GDN GidData
	
	set wname $GidData(WINDOW)

	if { [winfo exists $wname] } {
	    set class $GidData(CLASS)
	    set CallWin $GidData(CALLWIN)
	    
	    if { $class == "Conditions" && [winfo exists $wname.cndwnd] } {
		set HasCEW 1
		destroy $wname.cndwind
	    } else {
		set HasCEW 0
	    }
	    #destroy $wname
	    if { [info exists rBooks($class,COUNTER)] } {
		set idx $rBooks($class,COUNTER)
		set book [lindex $rBooks($class) $idx]
		if { $book != "" } {
		    incr idx
		    set GDN [ReplaceDW $GDN $CallWin $book $idx]
		    if { $HasCEW } {
		        DWShowCondEntitiesWin $GDN thiscond
		    }
		    incr rBooks($class,COUNTER)
		} else {
		    destroy $wname
		}
	    } else {
		destroy $wname
	    }
	}
    }
    set gidSubstDataBooks 0
}

proc OnChangeProblemType { dirpt ptname } {
    global GidPriv

    set GidPriv(PRBTYPE,NAME) $ptname

    SubstDataBooks
    set GidPriv(POSTDATA) 1
}

proc RefreshDataWindows { } {
    set ListGDN [info globals GD_*]
    foreach GDN $ListGDN {
	upvar \#0 $GDN GidData
	
	if { [winfo exists $GidData(WINDOW)] } {
	    destroy $GidData(WINDOW)
	    eval $GidData(CALLWIN) $GidData(BOOK) $GidData(BOOKORD)
	}
    }
}

# ------------------------------------------------------------------------------
# RefreshOnAddNewIntv --
#
#   Called from C when a new interval is added.
#
# ------------------------------------------------------------------------------

proc RefreshOnAddNewIntv {} {
  set ListGDN [info globals GD_INT*]
  foreach GDN $ListGDN {
    upvar \#0 $GDN GidData
    
    if { [winfo exists $GidData(WINDOW)] } {
      DWOnAddNewInterval $GDN
    }
  }
}

# ------------------------------------------------------------------------------
# RefreshOnDeleteIntv --
#
#   Called from C when the current interval is deleted.
#
# ------------------------------------------------------------------------------

proc RefreshOnDeleteIntv { I } {
  set ListGDN [info globals GD_INT*]
  foreach GDN $ListGDN {
    upvar \#0 $GDN GidData    
    if { [winfo exists $GidData(WINDOW)] } {
      DWOnDeleteInterval $GDN $I
    }
  }
}

proc DeleteTrace { vname traceCmd } {
    upvar \#0 vname rVar

    trace vdelete rVar w $traceCmd
}

proc TriggerDependencies { GDN } {
    upvar \#0 $GDN GidData
    
    set TYPE [eval $GidData(TYPEFUNC) $GDN]
    
    set IdxDep [array names GidData $TYPE,DEPENDENCIES,*]

    foreach Idx $IdxDep {
	
	regexp (?:.)DEPENDENCIES,(.+) $Idx {} IdxField

	set GidData($TYPE,VALUE,$IdxField) $GidData($TYPE,VALUE,$IdxField)
    }
    
    set GidData($TYPE,SYNC,TKWIDGET) 0
    if { [string equal $GidData(CLASS) "Conditions"] } {
	set GidData(FIRSTSTATE) ""
    } else {
	set GidData(FIRSTSTATE) [BuildStringValues $GDN]
    }
    set GidData($TYPE,SYNC,TKWIDGET) 1
}

proc GiveGlobalXY { frame } {

    set x 0 ; set y 0
    set wtmp $frame
    while 1 {
	incr x [winfo x $wtmp]
	incr y [winfo y $wtmp]
	if { [winfo class $wtmp] == "Toplevel" } { break }
	set wtmp [winfo parent $wtmp]
    }
    return "$x $y"
}

proc DWVarValueWinChange { GDN w N i what numwidth mxlenvalue } { 
  global $GDN
  upvar \#0 $GDN GidData
  
  set totalold $GidData($N,VALUE,$i,0)
  
  set fvw $w.canvas.fvw
  
#     grid rowconf $fvw [expr $totalold/$numwidth+2] -weight 0

  switch $what {
    down { incr GidData($N,VALUE,$i,0) $numwidth }
    up { 
      if { $GidData($N,VALUE,$i,0) <= $numwidth } {
	tk_dialogRAM $w.err [_ "error"] \
	    [_ "There must be at least one value for field"] \
	    error 0 [_ "OK"]
	return
      }
      incr GidData($N,VALUE,$i,0) [expr $numwidth*-1]
    }
  }
  set total $GidData($N,VALUE,$i,0)
  
  for { set j [expr $total+1] } { $j <= $totalold } { incr j } {
    destroy $fvw.l$j
  }
  
  if { [wm overrideredirect $w] } {
    set v 0
  } else { set v 1 }
  incr v [expr $total/$numwidth]
  set u 1
  for { set j [expr $totalold+1] } { $j <= $total } { incr j } {
    entry $fvw.l$j -textvar $GDN\($N,VALUE,$i,$j\)
    set GidData($N,VALUE,$i,$j) $GidData($N,VALUE,$i,[expr $j-$numwidth])
    grid $fvw.l$j  -row $v -column $u -sticky ew
    incr u
    if { $u == [expr $numwidth+1] && $j < $total} {
      set u 1; incr v
    }
  }
  #     grid rowconf $fvw $v -weight 1
  
  regexp {^([0-9]*)x([0-9]*)([-+]*[0-9]*)([-+]*[0-9]*)$} \
      [winfo geom $w] {} width height x y
  
  set vmax $v
  if { $vmax>12 } { set vmax 12 }
  set height [expr [winfo reqheight $fvw.l1]*$vmax+\
		  [winfo reqheight $w.f.up]+10]
  if { [winfo exists $fvw.title1] } {
    incr height [winfo reqheight $fvw.title1]
  }
  wm geom $w ${width}x${height}${x}${y}
  set heightint [expr [winfo reqheight $fvw.l1]*$v]
  $fvw conf -width [expr $width-15] -height $heightint
  $w.canvas conf -scrollregion "0 0 [expr $width-15] $heightint"

  DWReconfigureTextGrid $w.canvas $w.xscroll $w.yscroll
  update
}

proc DWVarValueWinClick { W x y ofocus } {
  set w [winfo width $W]
  set h [winfo height $W]
  if { $x < 0 || $x > $w || $y < 0 || $y > $h } {
    grab release $W
    focus -force $ofocus
    destroy $W
  }
}

proc DWVarValueWin { GDN title w N i fieldnames frame mxlenvalue { transient yes } } {
  global ExtendInfo
  global $GDN
  upvar \#0 $GDN GidData

  set ofocus [focus]

  set topvw $frame.vw

  #set fvw $w.f.f$i.vw.canvas.fvw
  set fvw $topvw.canvas.fvw

  #catch { destroy $w.f.f$i.vw}
  catch {destroy $topvw}
  #toplevel $w.f.f$i.vw -bd 2 -relief ridge
  toplevel $topvw -bd 2 -relief ridge
  canvas $topvw.canvas -bd 0 -xscrollcommand \
      "$topvw.xscroll set" \
      -yscrollcommand "$topvw.yscroll set" -takefocus 0 \
      -highlightthickness 0
  bind $topvw.canvas <1> "break"
  bind $topvw.canvas <B1-Motion> "break"
    
  scrollbar $topvw.yscroll  -relief sunken -command \
      "$topvw.canvas yview" -bd 1 -elementborderwidth 1
  scrollbar $topvw.xscroll  -relief sunken -command \
      "$topvw.canvas xview" -orient horizontal -bd 1 \
      -elementborderwidth 1
  bind $topvw.canvas <Configure> "DWReconfigureTextGrid $topvw.canvas \
	    $topvw.xscroll $topvw.yscroll"
    
  grid $topvw.canvas  -row 1 -column 1 -sticky nsew
  grid $topvw.yscroll -row 1 -column 2 -sticky ns
  grid $topvw.xscroll -row 2 -column 1 -sticky ew
    
  grid rowconf    $topvw 1 -weight 1
  grid columnconf $topvw 1 -weight 1
  $topvw.canvas conf -cursor ""

  frame $fvw
  set ExtendInfo($topvw.canvas) {}
  $topvw.canvas create window 0 0 -window $fvw -anchor nw -tags frame
  grid propagate $fvw 0

  set v 1
  if { $transient == "yes" } {
    wm transient $topvw $w
    wm overrideredirect $topvw 1
    grab $topvw
    $topvw conf -cursor top_left_arrow
    bind $topvw <1> [list DWVarValueWinClick %W %x %y $ofocus]
#         bind $w.f.f$i.vw <1> {
#             set w [winfo width %W]
#             set h [winfo height %W]
#             if { %x < 0 || %x > $w || %y < 0 || %y > $h } {
#                 grab release %W
#                 destroy %W
#             }
#         }
    bind $topvw <Escape> "grab release $topvw; focus -force $ofocus; destroy  $topvw; break"
  } else {
    wm title $topvw $title
    set u 1
    foreach j $fieldnames {
      label $fvw.title$u -text $j -relief ridge -bd 2
      grid $fvw.title$u -row $v -column $u -sticky ew
      grid columnconf $fvw $u -weight 1
      incr u
    }
    incr v
  }

  set numwidth [llength $fieldnames]
  foreach "x y" [GiveGlobalXY $frame] {}
  incr y [winfo height $frame]
  set width [winfo width $frame]
  set total $GidData($N,VALUE,$i,0)
  set u 1
  for { set j 1 } { $j <= $total } { incr j } {
    if { $v == 1 } { grid columnconf $fvw $u -weight 1 }
    entry $fvw.l$j -textvar $GDN\($N,VALUE,$i,$j\)
    grid $fvw.l$j  -row $v -column $u -sticky ew
    incr u
    if { $u == [expr $numwidth+1] } {
      set u 1 ; incr v
    }
  }
  
  grid rowconf $fvw 100 -weight 1
  
  frame $topvw.f
  button $topvw.f.down -image DownImage -command \
      "DWVarValueWinChange $GDN $topvw $N $i down $numwidth $mxlenvalue" -bd 1
  focus $topvw.f.down
  GidHelp $topvw.f.down [_ "Pressing this button, one new line will be added to this window"]
  button $topvw.f.up -image UpImage -command \
      "DWVarValueWinChange $GDN $topvw $N $i up $numwidth $mxlenvalue" -bd 1
  GidHelp $topvw.f.up [_ "Pressing this button, one line is deleted from this window"]
  button $topvw.f.right -image RightImage -command \
      [list DWVarValueWin $GDN $title $w $N $i $fieldnames $frame $mxlenvalue no] -bd 1
  GidHelp $topvw.f.right [_ "Converts this menu to a normal window"]
  button $topvw.f.close -image CloseImage -command \
      "destroy $topvw"  -bd 1
  GidHelp $topvw.f.close [_ "Closes this menu or window"]

  pack $topvw.f.down $topvw.f.up $topvw.f.right \
      $topvw.f.close -side left

  grid $topvw.f -column 1 -row 3 -pady 2 -columnspan 2
  
  set vmax $v
  if { $vmax>11 } { set vmax 11 }
  set height [expr ([winfo reqheight $fvw.l1]+1)*[expr $vmax-1]+\
		  [winfo reqheight $topvw.f.up]+10]
  if { [winfo exists $fvw.title1] } {
    incr height [winfo reqheight $fvw.title1]
  }
  wm geom $topvw ${width}x${height}+${x}+${y}
    
  set heightint [expr [winfo reqheight $fvw.l1]*[expr $v-1]]
  $fvw conf -width [expr $width-15] -height $heightint
  $topvw.canvas conf -scrollregion "0 0 [expr $width-15] $heightint"    
}

proc isyes { text } {
    set opt [string tolower $text ]
    if { $opt == "yes" || $opt == "si" || $text == 1 } {
	return 1
    } else { return 0 }
}

proc EndDWDefineLA { GDN TYPE Idx localaxesold } {
  upvar \#0 $GDN GidData
  
  set localaxesnew [.central.s info localaxes]
  
  if { [llength $localaxesnew] != [llength $localaxesold]+1 } {
    return
  }
  if { [lrange $localaxesnew 0 end-1] != $localaxesold } {
    return
  }
  set GidData($TYPE,OPTIONS1,$Idx) $localaxesnew
  set GidData($TYPE,VALUE,$Idx) [lindex $localaxesnew end]
  set GidData($TYPE,CBTEXT,$Idx) [= [DWUnder2Space $GidData($TYPE,VALUE,$Idx)]]
}

proc DWDefineLA { GDN TYPE Idx } {

    .central.s process escape escape escape escape data LocalAxes DefineLocAxes
    delayedop changefunc [list EndDWDefineLA $GDN $TYPE $Idx [.central.s info localaxes]]
}

proc DWActivateCBmenu { GDN TYPE Idx menu } {
  upvar \#0 $GDN GidData
  
  $menu del 0 end
  
  set cv $GidData($TYPE,VALUE,$Idx)
  set io 0
  if {$GidData($TYPE,TYPE,$Idx) eq "MAT"} {
    set GidData($TYPE,OPTIONS,$Idx) [lindex [DWGetMaterials \
                                                 $GidData($TYPE,MATFIELD,BOOKS)] 1]
  }
  foreach l $GidData($TYPE,OPTIONS,$Idx) {
    
    if ![string compare $l $cv] {
      set GidData($TYPE,POSTING,$Idx) 1
      set GidData($TYPE,CURSEL,$Idx) $io
      set GidData($TYPE,POSTING,$Idx) 0
    }
    $menu add radiobutton -value $io -label [= [DWUnder2Space $l]] -variable $GDN\($TYPE,CURSEL,$Idx\)
    incr io
  }
}

proc DWActivateLAmenu { GDN TYPE Idx menu } {
  upvar \#0 $GDN GidData
  
  set GidData($TYPE,POSTING,$Idx) 1
  $menu del 0 end
  
  set cv $GidData($TYPE,VALUE,$Idx)
  set io 0
  foreach l $GidData($TYPE,OPTIONS,$Idx) {
    if ![string compare $l $cv] {
      #set GidData($TYPE,POSTING,$Idx) 1
      set GidData($TYPE,CURSEL,$Idx) $io
      #set GidData($TYPE,POSTING,$Idx) 0
    }
    $menu add radiobutton -value $io -label [= [DWUnder2Space $l]] -variable $GDN\($TYPE,CURSEL,$Idx\)
    incr io
  }
  set widget [lindex $GidData($TYPE,WIDGET,$Idx) 0]
  set curlen [$widget cget -width]
  set mxlen $curlen
  set GidData($TYPE,OPTIONS1,$Idx) [.central.s info localaxes]
  foreach l $GidData($TYPE,OPTIONS1,$Idx) {
    set lenopt [string length $l]
    if { $lenopt > $mxlen } {
      set mxlen $lenopt
    }
    $menu add radiobutton -value $io -label [= [DWUnder2Space $l]] -variable $GDN\($TYPE,CURSEL,$Idx\)
    incr io
  }
  $menu add separator
  $menu add command -label [_ "Define"]... -command "DWDefineLA $GDN $TYPE $Idx"
  if { $mxlen > $curlen } {
    $widget configure -width $mxlen
  }
  set GidData($TYPE,POSTING,$Idx) 0
} 

proc ParserNumberUnit { Value Number Unit } {
    upvar $Number n
    upvar $Unit u
    
    set numreg {^[  ]*([+-]?[0-9]*\.?[0-9]*([eE][+-]?[0-9]+)?)[  ]*}
    set n "" ; set u ""
    regexp "${numreg}(.*)" $Value {} n {} u
    set u [string trim $u]
    return 1
}

proc DWFillText { GDN f N from to } {
  global $GDN
  global ExtendInfo
  
  upvar \#0 $GDN GidData
  
  set GidData($N,CONTAINER) $f
  
  set currentrow 0
  set comments [array names GidData $N,COMMENT,*]
  if { $comments != "" } {
    label $f.comment  -bd 2 -relief groove -justify left
    grid $f.comment -row $currentrow -column 0 -columnspan 2 -sticky wn
    incr currentrow
    set labelcanvas ""
    foreach i $comments {
      if { $labelcanvas != "" } { append labelcanvas \n }
      append labelcanvas [subst $GidData($i)]
    }
    $f.comment conf -text $labelcanvas
  }
  
  set row_weight_requested    0
  set column_weight_requested 0
  
  set thereishelp 0
  set result ""
  if { $from == 1 && [info exists GidData($N,TKWIDGET,0)] } {
    set save_row $currentrow
    if { [catch "$GidData($N,TKWIDGET,0) INIT $f currentrow $GDN [list $N] 0" result] } {
      WindowMessage "Error in tcl script sending event INIT to $GidData($N,TKWIDGET,0): $result"
      set currentrow $save_row
    } else {
      set len_res [llength $result]
      if { $len_res > 1 } {
	if { $len_res != 2 } {
	  WindowMessage "Error '$result' in result from INIT event: must be a 2-element list"
	  set currentrow $save_row
	} else {
	  set status [string toupper [lindex $result 0]]
	  if { [string equal $status ERROR] || [string equal $status WARNING] } {
	    set msg [lindex $result 1]
	    if { ![string length $msg] } {
	      WindowMessage $msg
	    }
	    # ignoro el 3 elemento correspondiente a la accion
	  }
	}
      } else {
	if { $len_res } {
	  grid $result -row $currentrow -column 0 -columnspan 2 -sticky w
	} else {
	}
	for { set i $save_row } { $i <= $currentrow } { incr i } {
	  array set rowinfo [grid rowconfigure $f $i]
	  if { $rowinfo(-weight) } {
	    set row_weight_requested 1
	    break
	  }
	}
	incr currentrow
      }
    }
  }
  
  set colwidth 0
  
  for { set i $from } { $i <= $to } { incr i } {
    #regsub -all {_} $GidData($N,QUESTION,$i) { } field
    set field $GidData($N,LABELQ,$i)
    set value $GidData($N,VALUE,$i)
    set type  $GidData($N,TYPE,$i)
    
    # verfico por argumentos
    
    set haveARGS 1
    if  { [info exists GidData($N,HEADINGS,$i)] } {
      upvar \#0 $GDN\($N,HEADINGS,$i\) argRef
    } elseif { [info exists GidData($N,OPTIONS,$i)] } {
      upvar \#0 $GDN\($N,OPTIONS,$i\) argRef
    } else {
      set haveARGS 0
    }
    if { $haveARGS } {
      set mxlenvalue 0
      set args {}
      foreach a $argRef {
	regsub -all {_} $a { } a
	set l [string length $a]
	if { $l > $mxlenvalue } {
	  set mxlenvalue $l
	}
	lappend args $a
      }
      incr mxlenvalue
    }
    
    set dolabel 1
    
    switch $type {
      "ENTRY" {
	set widget [entry $f.e$i -relief sunken \
		        -width 12 -textvar $GDN\($N,VALUE,$i\)]
      }
      "FUNC" {
	#WARNING func
	set widget [label $f.e$i \
		        -width 12 -textvar $GDN\($N,VALUE,$i\)]
      }
      "UNITS" {
	if { !$GidData($N,UNITVALID,$i) } {
	  set widget [entry $f.e$i -relief sunken \
		          -width 12 -textvar $GDN\($N,VALUENUM,$i\)]
	} else {
	  if { $GidData($N,UNITVALID,$i) == 1 } {
	    set widget [frame $f.f$i]
	    
	    entry $f.f$i.e -relief sunken \
		-width 12 -textvar $GDN\($N,VALUENUM,$i\)
	    canvas $f.f$i.c
	    set cgeo [GidDrawUnit $GidData($N,NUMERATOR,$i) $GidData($N,DENOMINATOR,$i) black $f.f$i.c]
	    $f.f$i.c configure -width [lindex $cgeo 0] -height [lindex $cgeo 1]
	    pack $f.f$i.c -side right
	    pack $f.f$i.e -side right -fill x -expand 1
	  } else {
	    set gu [GidUnit::CreateInstance]
	    set widget $f.f$i
	    $gu\::Create $widget $GidData($N,MAGNITUD,$i) \
		$GDN\(MAG,$GidData($N,MAGNITUD,$i)\) \
		$GDN\($N,IDXUNIT,$i\) $GDN\($N,VALUENUM,$i\)
	    set GidData($N,INSTANCE,$i) $gu
	  }
	}
      }
      "MAT" -
      "CB" {
	switch [lindex $GidData($N,CBTYPE,$i) 0] {
	  "LABEL" {
	    set widget [label $f.l$i -textvar $GDN\($N,VALUE,$i\)]
	  }
	  "CHECKBOX" {
	    set dolabel 0
	    set widget [checkbutton $f.cb$i -text [subst -nocommands $field] \
		            -onvalue [lindex $args [lindex $GidData($N,CBTYPE,$i) 1]] \
		            -offvalue [lindex $args [lindex $GidData($N,CBTYPE,$i) 2]] \
		            -variable $GDN\($N,VALUE,$i\) \
		            -wraplength 50m -justify left]
	  }
	  "COMBO" {
	    # OJO: mxlenvalue depende de la traduccion y no se esta haciendo!!!!
	    menubutton $f.m$i -indicatoron 1 -width $mxlenvalue \
		-textvar $GDN\($N,CBTEXT,$i\) -menu $f.m$i.m \
		-relief raised -bd 1 -highlightthickness 1 -anchor c \
		-direction flush
	    menu $f.m$i.m -tearoff 0 -bd 1 -activeborderwidth 1 \
		-postcommand "DWActivateCBmenu $GDN $N $i $f.m$i.m"
	    set widget $f.m$i
	  }
	}
      }
      "LA" {
	menubutton $f.m$i -indicatoron 1 -width $mxlenvalue \
	    -textvar $GDN\($N,CBTEXT,$i\) -menu $f.m$i.m \
	    -relief raised -bd 1 -highlightthickness 1 -anchor c \
	    -direction flush
	menu $f.m$i.m  -tearoff 0 -postcommand \
	    "DWActivateLAmenu $GDN $N $i $f.m$i.m" -bd 1 -activeborderwidth 1
	set widget $f.m$i
      }
      "GRID" {
	if { $mxlenvalue < 8 } { set mxlenvalue 8 }
	set widget [frame $f.f$i -relief raised -bd 1]
	set len [llength $args]
	for { set j 0 } { $j < $len } { incr j } {
	  button $f.f$i.l$j -text [lindex $args $j] -command \
	      [list DWVarValueWin $GDN $field $f $N $i $args \
		   $f.f$i $mxlenvalue] -bd 1 -width $mxlenvalue \
	      -takefocus 0 -highlightthickness 0
	  pack $f.f$i.l$j -side left 
	}
	button $f.f$i.b -image DownImage -command \
	    [list DWVarValueWin $GDN $field $f $N $i $args \
		 $f.f$i $mxlenvalue]
	pack $f.f$i.b -side left
      }
    }
    
    set WidgetLabel {}
    if { $dolabel } {
      set WidgetLabel $f.question$i
      
      label  $WidgetLabel -text [subst -nocommands $field] \
	  -wraplength 50m -justify left
      
      set reqwidth [winfo reqwidth $WidgetLabel]
      if { $reqwidth > $colwidth } {
	set colwidth $reqwidth
      }
      
      grid $WidgetLabel -row $currentrow -column 0 -sticky e
      grid $widget -row $currentrow -column 1 -sticky w
    } else {
      grid $widget -row $currentrow -column 0 -columnspan 2 -sticky w -padx 4
    }
    
    if { [info exists GidData($N,STATE,$i)] } {
      set wst $GidData($N,STATE,$i)
      if { $wst == "hidden" } {
	grid remove $widget
	if { $dolabel } {
	  grid remove $WidgetLabel
	}
      } else {
	if { $type == "UNITS" && $GidData($N,UNITVALID,$i) } {
	  if { $GidData($N,UNITVALID,$i) == 2 } {
	    if { $wst == "normal" } {
	      $GidData($N,INSTANCE,$i)::\Enabled
	    } else {
	      $GidData($N,INSTANCE,$i)::\Disabled
	    }
	  } else  {
	    # Puede ser ser solo un edit.
	    
	    catch { 
	      $widget conf -state $wst -fg black
	    }
	    
	    # y esto en caso de frame
	    
	    foreach child [winfo children $widget] {
	      catch {
		$child conf -state $wst -fg black
	      }
	    }
	  }
	} else {
	  catch {
	    $widget configure -state $wst 
	  }
	  if { $wst == "disabled" } {
	    $widget configure -fg gray60
	    if { $dolabel } {
	      $WidgetLabel configure -fg gray60
	    }
	  }
	}
      }
    }
    
    if { [info exists $GDN\($N,HELP,$i\)] } {
      GidHelp "$f.question$i $widget" [subst $GidData($N,HELP,$i)]
      set thereishelp 1
    } elseif { [info exists $GDN\($N,HELP,0\)] } {
      GidHelp "$f.question$i $widget" [subst $GidData($N,HELP,0)]
      set thereishelp 1
    }
    
    if { [info exists $GDN\($N,TKWIDGET,$i\)] } {
      set save_row $currentrow
      incr currentrow
      if { [catch "$GidData($N,TKWIDGET,$i) INIT $f currentrow $GDN [list $N] [list $GidData($N,QUESTION,$i)]" result] } {
	WindowMessage "Error in tcl script sending event INIT to $GidData($N,TKWIDGET,$i): $result"
	set currentrow $save_row
      } else {
	set len_res [llength $result]
	if { $len_res > 1 } {
	  if { $len_res != 2 } {
	    WindowMessage "Error '$result' in result from INIT event: must be a 2-element list"
	    set currentrow $save_row
	  } else {
	    set status [lindex $result 0]
	    if { [string equal $status ERROR] || [string equal $status WARNING] } {
	      set msg [lindex $result 1]
	      if { ![string length $msg] } {
		WindowMessage $msg
	      }
	      # ignoro el 3 elemento correspondiente a la accion
	    }
	  }
	} else {
	  if { $len_res } {
	    grid $result -row $currentrow -column 0 -columnspan 2 -sticky w
	  } else {
	  }
	  for { set row_used $save_row } { $row_used <= $currentrow } { incr row_used } {
	    array set rowinfo [grid rowconfigure $f $row_used]
	    if { $rowinfo(-weight) } {
	      set row_weight_requested 1
	      break
	    }
	  }
	}
      }
    }
    set GidData($N,WIDGET,$i) [list $widget $WidgetLabel]
    incr currentrow
  }
  if { $thereishelp } {
    grid $GidData(HELPBUTTON)
  } else {
    grid remove $GidData(HELPBUTTON)
  }
  
  #grid $f -row 0 -column 0 -sticky snew 
  
  for { set col_used 0 } { $col_used < 10 } { incr col_used } {
    array set colinfo [grid columnconfigure $f $col_used]
    if { $colinfo(-weight) } {
      set column_weight_requested 1
      break
    }
  }
  
  if { !$row_weight_requested } {
    grid rowconf $f $currentrow -weight 1
  }
  if { !$column_weight_requested } {
    grid columnconf $f 2 -weight 1
  }
  grid columnconf $f 0 -minsize [expr $colwidth + 4] -pad 4
  list $row_weight_requested $column_weight_requested
}

proc DWGetDepTraceCmd { GDN TYPE Idx } {
    return "[DWGetDepProcName $GDN $TYPE $Idx] ; #"
}

proc DWGetDepProcName { GDN TYPE Idx } {
    regsub -all "," $TYPE "" TYPE
    return $GDN$TYPE\_$Idx
}

# CreateTraceProc -
#
# Argumentos:
#
# Resultados:
#

proc CreateTraceProc { GDN TYPE Idx } {
    upvar \#0 $GDN GidData
    

    set ProcName [DWGetDepProcName $GDN $TYPE $Idx]
    if { [namespace which $ProcName] != "" } {
	rename $ProcName ""
    }
    eval "proc $ProcName \{ \} $GidData($TYPE,DEPENDENCIES,$Idx)"
    
    
    return $ProcName
}

# RemoveTraceProcs -
#
# Argumentos:
#
# Resultados:
#

proc RemoveTraceProcs { GDN } {
    foreach P [info commands $GDN*] {
	rename $P ""
    }
}

proc DWReconfigureTextGrid { text xscroll yscroll } {
    set b [bind $text <Configure>]
    bind $text <Configure> ""
    if { [winfo exists $xscroll] } { grid forget $xscroll }
    if { [winfo exists $yscroll] } { grid forget $yscroll }
    update idletasks
    if { [winfo exists $xscroll] } {
	if { [lindex [$text xview] 0] == 0 &&  [lindex [$text xview] 1] == 1 } {
	    grid forget $xscroll
	} else { grid $xscroll -row 2 -column 1 -sticky ew}
    }

    if { [winfo exists $yscroll] } {
	
	if { [lindex [$text yview] 0] == 0 && [lindex [$text yview] 1] == 1 } {
	    grid forget $yscroll
	} else { grid $yscroll -row 1 -column 2 -sticky ns }
    }
    after 100 [list bind $text <Configure> $b]
}

proc DWReconfigureText { text xscroll yscroll } {
    upvar ::ExtendInfo($text) geometry

    set b [bind $text <Configure>]
    bind $text <Configure> ""
    grid remove $xscroll 
    grid remove $yscroll

    if { ![llength $geometry] } {
	foreach {x1 y1 x2 y2} [$text bbox frame] {}
	set geometry [list [expr $x2-$x1] [expr $y2-$y1]]
       #set geometry [list [winfo reqwidth $text.f] [winfo reqheight $text.f]]
	#$text create line $x2 $y1 $x2 $y2 -fill red
    }
    set x1_i 0 ; set y1_i 0 ; set x2_i 0 ; set y2_i 0
    foreach "x1_i y1_i x2_i y2_i" [$text bbox images] break
    set width_i [expr $x2_i-$x1_i]
    

    set width_w  [lindex $geometry 0]
    set height_w [lindex $geometry 1]
    set width_c  [winfo width $text]
    set height_c [winfo height $text]
    
    set change_geometry 0
    if { $width_w <= $width_c && $width_i == 0 } {
	set new_width $width_c
	set change_geometry 1
    } else {
	set new_width $width_w
    }
    if { $height_w <= $height_c && $width_i == 0} {
	set new_height $height_c
	set change_geometry 1
    } else {
	set new_height $height_w
    }

    if { $change_geometry } {
	   $text itemconfigure frame -width $new_width -height $new_height
    }
    if { [lindex [$text xview] 0] == 0 &&  [lindex [$text xview] 1] == 1 } {
	grid remove $xscroll
    } else { 
	grid $xscroll 
    }

    if { [lindex [$text yview] 0] == 0 && [lindex [$text yview] 1] == 1 } {
	grid remove $yscroll
    } else { 
	grid $yscroll
    }
    after 100 [list bind $text <Configure> $b]
}

proc DWDeleteAssociatedImage { GDN name1 name2 op } {
    image delete $GDN
}

proc DWCreateText { GDN w name from to } {
  global $GDN
  upvar \#0 $GDN GidData
  set dir $GidData(DirPT)
  set sw $w.sw
  set sf $sw.sf

  catch {
    destroy $sw;
  }

#   if {![winfo exists $sw]} {
#     ScrolledWindow $sw
#     ScrollableFrame $sf
#     set f [$sf getframe]
#   } else {
#     set f [$sf getframe]
#     foreach child [winfo children $f] {
#       destroy $child
#     }
#   }

  ScrolledWindow $sw
  ScrollableFrame $sf
  set f [$sf getframe]

  set fdata [frame $f.fdata]
  set fimg [frame $f.fimg]
  foreach opt {-constrainedheight -constrainedwidth} val [DWFillText $GDN $fdata $name $from $to] {
    $sf configure $opt $val
  }
  set img 0
  foreach i [array names GidData $name,IMGOBJ,*] {
    if {[regexp {.*,([0-9]*)} $i {} num] && 
	(($num >= $from && $num <= $to) ||
	 ($num == 0 && $from == 1))} {
      grid [label $fimg.l$img -image $GidData($i)] -row $img -column 0 -sticky "nw"
      incr img
    }
  }
  grid $fdata -row 0 -column 0 -sticky "snew"
  if {$img} {
    grid $fimg -row 0 -column 1 -sticky "snew"
  } else {
    destroy $fimg
  }
  grid columnconfigure $f 0 -weight 1
  grid rowconfigure $f 0 -weight 1
  $sw setwidget $sf
  grid $sw -row 0 -column 0 -sticky "snew"
  grid rowconfigure $w 0 -weight 1
  grid columnconfigure $w 0 -weight 1
}

proc DWCreateText_ { GDN w name from to } {
    global $GDN
    upvar \#0 $GDN GidData
    set dir $GidData(DirPT)
    set canvas $w.canvas

    set needsconfigure 0

    if { ![winfo exists $canvas] } {
	  canvas $canvas -xscrollcommand "$w.xscroll set" \
		  -yscrollcommand "$w.yscroll set" -bd 0 \
		  -takefocus 0 -highlightthickness 0 \

	bind $canvas <1> "break"
	bind $canvas <B1-Motion> "break"
	bind $canvas <ButtonRelease-1> "break"
	
	scrollbar $w.yscroll  -relief sunken -command \
		"$w.canvas yview" -bd 1 -elementborderwidth 1
	scrollbar $w.xscroll  -relief sunken -command \
		"$w.canvas xview" -orient horizontal -bd 1 -elementborderwidth 1

	bind $canvas <Configure> "DWReconfigureText $w.canvas $w.xscroll \
		$w.yscroll"

	grid $canvas    -row 0 -column 0 -sticky nsew

	grid $w.yscroll -row 0 -column 1 -sticky ns
	grid $w.xscroll -row 1 -column 0 -sticky ew
	grid remove $w.yscroll
	grid remove $w.xscroll
	
	grid rowconf    $w 0 -weight 1
	grid columnconf $w 0 -weight 1
	$canvas conf -cursor ""
	
    } else {
	# RAMSAN
	bind $canvas <Configure> ""
	set needsconfigure 1
	#after idle event generate $canvas <Configure>
    }
    $canvas delete images

    DWFillText $GDN $canvas $name $from $to
    update idletasks

    $w.canvas conf -scrollregion "0 0 [winfo reqwidth $w.canvas.f] \
	    [winfo reqheight $w.canvas.f]"

    #global GidData


    #set imgidx [lindex [array names GidData $name,IMGOBJ,*] 0]

    set imgh 15
    set imgw 0
    foreach i [array names GidData $name,IMGOBJ,*] {
	if { [regexp {.*,([0-9]*)} $i {} num] && (($num >= $from && $num <= $to) || \
		                                      ($num == 0 && $from == 1))} {
	    set posx [winfo reqwidth $canvas.f]
	    incr posx 15

	    $canvas create image $posx $imgh \
		-image $GidData($i) -anchor nw -tags images
	    if { $imgw < [set cw [image width $GidData($i)]] } {
		set imgw $cw
	    }
	    incr imgh [expr [image height $GidData($i)]+15]
	}
    }
    
    if { $imgh > 0 } {
	set width [expr [winfo reqwidth $canvas.f]+$imgw]
	set h [winfo reqheight $canvas.f]
	
	if { $h < $imgh } {
	    set h $imgh
	}
	$w.canvas conf -scrollregion "0 0 $width $h"
    }
    bind $canvas <Configure> "DWReconfigureText $w.canvas $w.xscroll \
	    $w.yscroll"

  if { $needsconfigure } {
    update
    after idle event generate $canvas <Configure>
  }
}


proc DWCreateTabOfTexts { GDN w P basename} {
  global $GDN
  upvar \#0 $GDN GidData
  
  #destruyo la informacion de los widgets
  foreach i [array names GidData *,WIDGET,*] {
    set GidData($i) {}
  }
  
  foreach i [array names GidData *,INSTANCE,*] {
    unset GidData($i)
  }
  
  #lanzo las dependencias iniciales
  set GidData($P,VISIBLE) 0
  TriggerDependencies $GDN
  
  set fieldsnum [llength [array names GidData $P,QUESTION,*]]
  
  if { ![info exists $GDN\($P,TITLE,0\)] } {
    set GidData($P,TITLE,0) $basename
  }
  
  regsub -all "$P,TITLE," [array names GidData $P,TITLE,*] \
      {} titlesnums
  
  set titlesnums [lsort -integer $titlesnums]
  
  if { [llength $titlesnums] == 1 } {
    
    catch { destroy $w.c }
    if { ![winfo exists $w.t0] } {
      frame $w.t0
    }
    DWCreateText $GDN $w.t0 $P 1 $fieldsnum
    pack $w.t0 -fill both -expand yes
  } else {
    if { ![winfo exists $w.c] } {
      set GidData(OPTIONBAR) $w.c
      set func "optionbar $w.c"
    } else { set func "$w.c replace" }
    for { set i 0 } { $i < [llength $titlesnums] } { incr i } {
      if { ![winfo exists $w.t$i] } {
	frame $w.t$i
      }
      set inipos [expr [lindex $titlesnums $i]+1]
      #set inipos [lindex $titlesnums $i]
      if { $i < [expr [llength $titlesnums]-1] } {
	#set endpos [lindex $titlesnums [expr $i+1]]
	set endpos [lindex $titlesnums [expr $i + 1]]
      } else { set endpos $fieldsnum }
      DWCreateText $GDN $w.t$i $P $inipos $endpos
      set name [= $GidData($P,TITLE,[lindex $titlesnums $i])]
      lappend func [list $name $w.t$i]
    }
    eval $func
    
    pack $w.c -fill both -expand yes
    #estados iniciales de tabs
    foreach i $titlesnums {
      set state $GidData($P,TITLESTATE,$i)
      if { [string compare $state normal] } {
	optionbar $w.c state $GidData($P,TITLE,$i) $state
      }
    }
  }
  
  # now it's visible
  set GidData($P,VISIBLE) 1
}


#----------------------------------------PROBLEM DATA--------------

proc DWReadPRBfile { GDN filename } {
    global $GDN
    upvar \#0 $GDN GidData

    foreach i [array names GidData PD*] { unset GidData($i) }
    foreach i [array names GidData ID*] { unset GidData($i) }

    set f [open $filename r]
    set inum 0
    gets $f aa
    while { ![eof $f] } {
	gets $f aa
	if { $aa == "" ||  [string index $aa 0] == "#" } { continue }
	regexp {^([^ ]*) (.*)$} $aa {} field value
	if { $field == "END" } { break }
	if { $field == "QUESTION:" } { incr inum }
	set GidData(PD,$field,$inum) $value
    }
    set inum 0
    gets $f aa
    while { ![eof $f] } {
	gets $f aa
	if { [string index $aa 0] == "#" } { continue }
	regexp {^([^ ]*) (.*)$} $aa {} field value
	if { $field == "END" } { break }
	if { $field == "QUESTION:" } { incr inum }
	set GidData(ID,$field,$inum) $value
    }
    close $f
}

# ------------------------------------------------------------------------------
# DWComboBox --
# 
#   Create a ComboBox with desired default properties:
#   -selectborderwidth 0
#   -selectbackground  [$w cget -entrybg]
#   -selectforeground  black
# ------------------------------------------------------------------------------

proc DWComboBox { w args } {
  eval ComboBox $w $args -selectborderwidth 0
  $w configure -selectbackground [$w cget -entrybg]
  $w configure -selectforeground black
  return $w
}

# ------------------------------------------------------------------------------
# DWOnSelectInterval --
#
#  Invoked under -modifycmd of intervals ComboBox. It should change the current
#  interval showed in the data window.
# ------------------------------------------------------------------------------

proc DWOnSelectInterval { GDN {current -1}} {
  upvar \#0 $GDN GidData

  if {$current==-1} {
    if {$GidData(ID,current) == [set current [expr [$GidData(ID,combo) getvalue]+1]]} {
      return
    }
    if {[catch "CheckDirtyState $GDN" result]} {
      if [string equal $result CANCEL] {
	return
      } else {
	error $result
      }
    }
  }
  set GidData(ID,current) $current
  
  # Hay que pedirle a Gid que cambie de intervalo activo.
  DWSetActiveInterval $GidData(ID,current)
  # Hay que limpiar GidData para
  # luego pedirle los datos a Gid de este intervalo y ponerlos en GidData.
  # disable dependencies to refill data
  set GidData(DEPDISABLED) 1
  DWRefillIntervalData $GDN
  # now enable again dependencies
  set GidData(DEPDISABLED) 0
  TriggerDependencies $GDN
}

proc DWInitComboInterval { GDN } {
  upvar \#0 $GDN GidData

  foreach {GidData(ID,current) max} [.central.s info intvdata num] break
  set values [list]
  for {set i 1} {$i <= $max} {incr i} {
    lappend values $i
  }
  $GidData(ID,combo) configure -values $values
  $GidData(ID,combo) setvalue @[expr $GidData(ID,current)-1]
}

proc DWIntervalDataWindow { {Book "Default"} {BookOrd 1} {UseWindow ""}} {
  global GIDDEFAULT
  
  if { [DWInitWindow INT $Book $BookOrd $UseWindow w] != "created" } {
    return
  }
  
  set GDN GD_INT_$BookOrd
  global $GDN
  globalarray $GDN
  upvar \#0 $GDN GidData
  
  set GidData(CALLWIN) DWIntervalDataWindow
  set GidData(BOOKORD) $BookOrd
  set GidData(WINDOW) $w
  
  # manipulador que atendera la validacion de los datos
  wm protocol $w WM_DELETE_WINDOW "DWCloseWindow $GDN"
  
  # Activa el el primer intervalo pues es que define los books
  
  if { ![GenericFillGidData $GDN ID $Book] } {
    destroy $w
    return
  }
  
  #set GidData(ID,maxinterval) 0
  
  frame $w.level
  
  # A partir de aqui: controles de la interface.
  
  #combobox $w.level.combo -editable 0 -textvariable "$GDN\(ID,currentinterval\)"
  DWComboBox $w.level.combo -editable 0 -modifycmd "DWOnSelectInterval $GDN"
  set GidData(ID,combo) $w.level.combo
    
  if { ![info exist GidPriv(DW_NEW)] } {
    set GidPriv(DW_NEW) [image create photo -file $GIDDEFAULT/bitmaps/new.gif]
  }
  
  button $w.level.new -image $GidPriv(DW_NEW) \
      -command "DWNewInterval $GDN" -und 0 -bd 1 -highlightthickness 0
  ChangeToNewLook $w.level.new
  GidHelp $w.level.new [_ "New interval"]
  
  grid $w.level.combo -row 0 -column 0 -sticky "ew"
  grid $w.level.new -row 0 -column 1 -sticky "ew"
  CreateJumpButton $GDN $w.level 3
  grid columnconfigure $w.level 0 -weight 1
  grid columnconfigure $w.level 2 -weight 1

  #pack $w.level.combo -side left -fill x
  #pack $w.level.new -side left 
  #pack $jumpbutton -anchor se -side bottom
  
  frame $w.f -bd 2 -relief groove
  
  set GidData(ID,mainframe) $w.f
  
  frame $w.but -bg [CCColorActivo [$w cget -background]]
  button $w.but.accept -text [_ "Accept"] -command "DWIntervalAccept $GDN" -und 0 -bd 1        
  set maxWidth [DWGetMaxWidth $w.but.accept 10 "Accept" "Close"]
  $w.but.accept configure -width $maxWidth
  button $w.but.close -text [_ "Close"] \
      -command "DWCloseWindow $GDN" -und 0 -bd 1 -width $maxWidth
  #pack $w.but.accept $w.but.close -side left
  grid $w.but.accept -row 1 -column 1 -sticky e -padx 5 -pady 5
  grid $w.but.close -row 1 -column 2 -sticky w -padx 5 -pady 5 
  
  pack $w.level -side top -anchor nw -padx 2 -pady 2 -fill x
  pack $w.but -side bottom -fill x
  pack $w.f -fill both -expand yes
  
  
  foreach i "$w.but.accept $w.but.close" {
    set l [string tolower [string index [$i cget -text] [$i cget -und]]]
    # this may fail when $l is not a valid keysym
    catch {
      bind $w <Alt-$l> "tkButtonInvoke $i ;break"
    }
  }
  bind $w <Escape> "tkButtonInvoke $w.but.close"
  
  #  set GidData(ID,currentinterval) [InitComboInterval $GDN w]
  #  set GidData(ID,previnterval) $GidData(ID,currentinterval)
  DWInitComboInterval $GDN
  DWCreateTabOfTexts $GDN $GidData(ID,mainframe) ID "Base data"
  
  #trace var GidData(ID,currentinterval) w "DWChangeInterval $GDN ;#"
  
  update idletasks
  wm deicon $w
  focus $w.but.accept

  return $GDN
}

proc UnsetGDN { GDN } {
    global $GDN
    upvar \#0 $GDN GidData

    unset GidData
}

#  GetDirectoryProblemType --
#    Retorna el camino donde se encuentra definido el camino del problema. 
#    Esto fue tomado de ProcWin.tcl en el proc PWStartProc.
#
#  Argumentos:
#
#  Resultados:
#    Retorna el camino del tipo de problemas.

proc GetDirectoryProblemType { } {
    global GIDDEFAULT GidPriv

    set r ""
    catch {
	set r [.central.s info problemtypepath]
    }
    
    return $r


    set aa [.central.s info Project]
    set ProblemType [lindex $aa 0]

    set ProblemDirectory $ProblemType.gid
    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT problemtypes $ProblemType.gid]
    }
    if { ![file isdirectory $ProblemDirectory] } {
	set ProblemDirectory [file join $GIDDEFAULT $ProblemType.gid]
    }
    if { [file pathtype $ProblemDirectory] == "relative" } {
	set ProblemDirectory [file join [pwd] $ProblemType.gid]
    } 
    if { [file isdirectory $ProblemDirectory] } {
	return $ProblemDirectory
    } else {
	return ""
    }
}

# DWGetMaxWidth --
#
#        Calculates maximun width (not pixels) required for the widget w to display
#       the translated strings of the given list.
#
# Arguments:
#       w     widget to display the string, normally are buttons
#       def   minimun width to reach
#        args  strings to display (translated).
#
# Results:
#        Returns the width required to display the longest translated string.
#

proc DWGetMaxWidth { w def args } {
  # width of an A character
  set A_pix [font measure [set fn [$w cget -font]] -displayof $w "0"]
  set max_w 0
  # compute every string width
  foreach str $args {
    set str_pix [font measure $fn -displayof $w [::msgcat::mc $str]]
    if {[set str_w [expr {$str_pix/$A_pix+(($str_pix%$A_pix)!=0)+1}]]>$max_w} {
      set max_w $str_w 
    }
  }
  expr {$max_w>$def?$max_w:$def}
}

proc DWProblemDataWindow { {Book "Default"} {BookOrd 1} {UseWindow ""} } {
  global GIDDEFAULT
  
  if { [DWInitWindow PD $Book $BookOrd $UseWindow w] != "created" } {
    return
  }
  
  set GDN GD_PD_$BookOrd
  
  globalarray $GDN
  global $GDN
  upvar \#0 $GDN GidData
  
  set GidData(CALLWIN) DWProblemDataWindow
  set GidData(BOOKORD) $BookOrd
  set GidData(WINDOW) $w
  
  # manipulador que atendera la validacion de los datos
  wm protocol $w WM_DELETE_WINDOW "DWCloseWindow $GDN"
  
  if {![GenericFillGidData $GDN PD $Book] } {
    destroy $w
    return
  }

  frame $w.ftop
  CreateJumpButton $GDN $w.ftop 1 right
  grid $w.ftop -row 0 -column 0 -sticky "ew"
  grid columnconfigure $w.ftop 0 -weight 1
  #pack $jumpbutton -side top -anchor ne
  frame $w.f -bd 2 -relief groove
  set GidData(PD,mainframe) $w.f
  
  frame $w.but -bg [CCColorActivo [$w cget -background]]
  button $w.but.accept -text [_ "Accept"] -command "DWProblemAccept $GDN" -und 0 -bd 1
  set maxWidth [DWGetMaxWidth $w.but.accept 10 "Accept" "Close"]
  $w.but.accept configure -width $maxWidth
  button $w.but.close -text [_ "Close"] -command "DWCloseWindow $GDN" -und 0 -bd 1 \
      -width $maxWidth

  #pack $w.but.accept $w.but.close
  
  grid $w.but.accept -row 1 -column 1 -sticky e -padx 5 -pady 5
  grid $w.but.close -row 1 -column 2 -sticky w -padx 5 -pady 5 
  
  grid $w.but -row 2 -column 0 -sticky "snew"
  
  DWCreateTabOfTexts $GDN $GidData(PD,mainframe) PD "Base data"
  grid $GidData(PD,mainframe) -row 1 -column 0 -sticky "snew"
  grid columnconfigure $w 0 -weight 1
  grid rowconfigure $w 1 -weight 1
  #     update idletasks
  update
  wm deicon $w
  focus $w.but.accept
  
  foreach i "$w.but.accept $w.but.close" {
    set l [string tolower [string index [$i cget -text] [$i cget -und]]]
    # this may fail when $l is not a valid keysym
    catch {
      bind $w <Alt-$l> "tkButtonInvoke $i ;break"
    }
  }
  bind $w <Escape> "tkButtonInvoke $w.but.close"
  
  return $GDN
}

# ------------------------------------------------------------------------------
# DWOnSelectMaterial --
#
#  Invoked under -modifycmd of materials ComboBox. It should change the material
#  info showed in the data window.
# ------------------------------------------------------------------------------

proc DWOnSelectMaterial {GDN} {
  upvar \#0 $GDN GidData

  if {$GidData(MAT,cursel) == [set sel [$GidData(MAT,combo) getvalue]]} {
    return
  }
  if {$GidData(MAT,cursel)!=-1} {
    CheckDirtyState $GDN
  }
  set GidData(MAT,cursel) $sel

  # BACKWARD COMPATIBILITY
  set GidData(MAT,matname) [DWGetGUIMaterial $GDN]
  # REMOVE AFTER VERSION 8.0
  DWMaterialUpdateProperties $GDN
  DWCreateMaterialFrame $GDN
}

# ------------------------------------------------------------------------------
# DWCreateMaterialFrame --
#
#  Fill in frame of GDN the info corresponding to current material.
# ------------------------------------------------------------------------------

proc DWCreateMaterialFrame { GDN } {
  upvar \#0 $GDN GidData

  DWCreateTabOfTexts $GDN $GidData(MAT,mainframe) [DWGetTypeMAT $GDN] \
      {Base properties}
}

#BACKWARD COMPATIBILITY
proc DWGetCurrentMaterial { GDN } {
  DWGetGIDMaterial $GDN
}

# ------------------------------------------------------------------------------
# DWGetGIDMaterial --
#
#  Return the current original (untranslated) material name 
# ------------------------------------------------------------------------------

proc DWGetGIDMaterial { GDN } {
  upvar \#0 $GDN GidData

  lindex $GidData(MAT,materials) $GidData(MAT,cursel)
}

proc DWGetGUIMaterial { GDN } {
  upvar \#0 $GDN GidData

  lindex [$GidData(MAT,combo) cget -values] $GidData(MAT,cursel)
}

#----------------------------------------MATERIALS--------------------
# KILL THIS PROC
proc DWChangeMatName { GDN } {
    global $GDN

    upvar \#0 $GDN GidData

    if { $GidData(MAT,matname) == "" } { return }
    
    if { $GidData(MAT,prevmatname) == $GidData(MAT,matname) } {
	return
    }

    if { $GidData(MAT,prevmatname) != "" && $GidData(MAT,prevmatname) != -1} {

	CheckDirtyState $GDN
  
	#        if [catch "CheckDirtyState $GDN" result] {
	#            if [string equal $result CANCEL] {
	#                return
	#            } else {
	#                error $result
	#            }
	#        }
    }
  
    set GidData(MAT,prevmatname) $GidData(MAT,matname)

    DWCreateTabOfTexts $GDN $GidData(MAT,mainframe) MAT,[DWSpace2Under $GidData(MAT,matname)] \
	    {Base properties}
}


proc DWUpFirstLetter { str } {
  if [regexp {^[0-9A-Z_](.*)} $str] {
    return $str
  }
  append uf [string toupper [string index $str 0]] [string range $str 1 end]
  return $uf
}

proc DWDownFirstLetter { str } {
  if [regexp {^[0-9A-Z_]+$} $str] {
    return $str
  }
  append df [string tolower [string index $str 0]] [string range $str 1 end]
  return $df
}

proc DWMatWindow { {Book "Default"} {BookOrd 1} {UseWindow ""} } {
  global GIDDEFAULT GidPriv
  global gidDataLabels
  
  if { [DWInitWindow MAT $Book $BookOrd $UseWindow w] != "created" } {
    return
  }
  
  set GDN GD_MAT_$BookOrd
  
  global $GDN
  globalarray $GDN
  upvar \#0 $GDN GidData
  
  set GidData(CALLWIN) DWMatWindow
  set GidData(BOOKORD) $BookOrd
  set GidData(WINDOW) $w
  
  # manipulador que atendera la validacion de los datos
  wm protocol $w WM_DELETE_WINDOW "DWCloseWindow $GDN"
  
  if { ![MATFillGidData $GDN $Book] } {
    destroy $w
    return
  }
  
  frame $w.level
  
#  combobox $w.level.combo -editable 0 -textvariable $GDN\(MAT,matname\)
  DWComboBox $w.level.combo -editable 0 -modifycmd "DWOnSelectMaterial $GDN"
  set GidData(MAT,combo) $w.level.combo
  
  if { ![info exist GidPriv(DW_MODIFY)] } {
    set GidPriv(DW_MODIFY) [image create photo -file $GIDDEFAULT/bitmaps/prefs.gif]
    set GidPriv(DW_NEW) [image create photo -file $GIDDEFAULT/bitmaps/new.gif]
    set GidPriv(DW_DELETE) [image create photo \
                                -file $GIDDEFAULT/bitmaps/redcross22x22.gif]
    #         DynamicHelp::configure -bg white -delay 300
  }
  
  button $w.level.mod -image $GidPriv(DW_MODIFY) \
      -command "DWModifyMat $GDN" -und 0 -bd 1 -highlightthickness 0
  ChangeToNewLook $w.level.mod
  GidHelp $w.level.mod [_ "Update changes"]
  
  button $w.level.new -image $GidPriv(DW_NEW) \
      -command "DWNewMat $GDN $w" -und 0 -bd 1 -highlightthickness 0
  ChangeToNewLook $w.level.new
  GidHelp $w.level.new [_ "New %s" [DWDownFirstLetter $GidData(MAT,singular)]]
  
  button $w.level.del -image $GidPriv(DW_DELETE) \
      -command "DWDeleteMat $GDN" -und 0 -bd 1 -highlightthickness 0
  ChangeToNewLook $w.level.del
  GidHelp $w.level.del [_ "Delete %s" [DWDownFirstLetter $GidData(MAT,singular)]]
  set GidData(widgets,modify)  $w.level.mod
  set GidData(widgets,new) $w.level.new
  set GidData(widgets,delete) $w.level.del

  grid $w.level.combo -row 0 -column 0 -sticky "snew"
  grid $w.level.mod   -row 0 -column 1 -sticky "snew"
  grid $w.level.new   -row 0 -column 2 -sticky "snew"
  grid $w.level.del   -row 0 -column 3 -sticky "snew"

  set jumpbutton [CreateJumpButton $GDN $w.level 5]

  #grid $jumpbutton    -row 0 -column 5 -sticky "ew"
  grid columnconfigure $w.level 0 -weight 3
  grid columnconfigure $w.level 4 -weight 1

  if {0} {
  after idle \
      [string map \
	   "%cb $w.level.combo %mod $w.level.mod %new $w.level.new %del $w.level.del" {
	     set hc [winfo reqheight %cb]
	     set hm [winfo reqheight %mod]
#             WarnWinText "hc = $hc hm = $hm"
	     if {$hc<$hm} {
	       incr hc -2
	       foreach w [concat %mod %new %del [winfo children %jb]] {
		 $w configure -height $hc
	       }
	     } else {
	       foreach w [winfo children %jb] {
		 $w configure -height $hm
	       }
	     }
	   }]
  }
  frame $w.f -bd 2 -relief groove
  set GidData(MAT,mainframe) $w.f
  
  frame $w.but -relief ridge -bd 2
  
  # ----- Opcion Assign -----
  
  set MenuAssign $w.but.assign.menu
  menubutton $w.but.assign -text [_ "Assign"] -und 0 -relief raised \
      -menu $MenuAssign -bd 1  -highlightthickness 1
  set GidData(widgets,assign) $w.but.assign

  menu $MenuAssign -bd 1 -activeborderwidth 1 \
      -postcommand "PostCmdAssignMat $GDN $w $MenuAssign"
  
  # ----- Opcion Draw -----
  
  set MenuDraw $w.but.draw.menu
  menubutton $w.but.draw -text [_ "Draw"] -und 0 -relief raised \
      -menu $MenuDraw -bd 1  -highlightthickness 1
  set GidData(widgets,draw) $w.but.draw
  
  menu $MenuDraw -bd 1 -activeborderwidth 1 \
      -postcommand "DWPostDrawMaterial $GDN $MenuDraw"
  
  $MenuDraw  add command -label "XXXX" \
      -command "DWDrawMaterials $GDN $w onemat"    
  
  set labelmat ""
  catch {
    set labelmat $gidDataLabels(Materials)
  }
  if { $labelmat == "" } {
    set labelmat [_ "Materials"]
  }
  
  $MenuDraw  add command -label [_ "All %s" [DWUnder2Space [DWDownFirstLetter $labelmat]]] -command \
      "DWDrawMaterials $GDN $w allmats"
  
  # ----- Opcion Unassign -----
  set MenuUnassign $w.but.unassign.menu
  menubutton $w.but.unassign -text [_ "Unassign"] -und 0 -relief raised \
      -menu $MenuUnassign -bd 1  -highlightthickness 1
  set GidData(widgets,unassign) $w.but.unassign
  menu $MenuUnassign -bd 1 -activeborderwidth 1 \
      -postcommand "DWUnassignMat $w $GDN"
  
  # ----- Opcion Import/Export -----
  button $w.but.impexp -text [_ "Import/Export"] \
      -command [list DWMatImportExport $w $Book]
  set GidData(widgets,impexp) $w.but.impexp
  
  #pack $w.but.assign $w.but.draw $w.but.unassign $w.but.impexp -side left
  grid $w.but.assign $w.but.draw $w.but.unassign $w.but.impexp
  grid columnconfigure $w.but 4 -weight 1
  
  frame $w.but2 -bg [CCColorActivo [$w cget -background]]
  button $w.but2.close -text [_ "Close"] \
      -command "DWCloseWindow $GDN" -und 0
  pack $w.but2.close -pady 5
  
  pack $w.level -fill x  -side top -padx 2 -pady 2
  pack $w.but2 -side bottom -fill x
  pack $w.but -ipady 3 -fill x -side bottom
  pack $w.f -fill both -expand yes
  
  #trace var GidData(MAT,matname) w "DWChangeMatName $GDN ;#"

#   foreach i $GidData(MAT,nameslist) {
#     $w.level.combo add $i
#   }
  set combo_info [list]
  foreach mat $GidData(MAT,materials) {
    lappend combo_info [= [DWUnder2Space $mat]]
  }
  $GidData(MAT,combo) configure -values $combo_info
  $GidData(MAT,combo) setvalue first
#  set GidData(MAT,prevmatname) ""
  
  #set GidData(MAT,matname) [lindex $GidData(MAT,nameslist) 0]
  set GidData(MAT,cursel) 0
  DWCreateMaterialFrame $GDN
  # BACKWARD COMPATIBILITY
  set GidData(MAT,matname) [DWGetGUIMaterial $GDN]
  # REMOVE AFTER VERSION 8.0
  
  update idletasks

  DWMaterialUpdateProperties $GDN

  wm deicon $w
  focus $w.but.assign
  
  ##foreach i "$w.level.mod $w.level.new $w.but.assign $w.but.draw 
  foreach i "$w.but.assign $w.but.draw \
	     $w.but.unassign $w.but2.close" {
    set l [string tolower [string index [$i cget -text] [$i cget -und]]]
    # this may fail when $l is not a valid keysym
    catch {
      bind $w <Alt-$l> "tkButtonInvoke $i ;break"
    }
  }
  
  bind $w <Escape> "tkButtonInvoke $w.but2.close"
  
  return $GDN
}

proc DWIsGeomtry { } {
  if { [lindex [.central.s info Project] 4] eq "GEOMETRYUSE" } {
    return 1
  }
  return 0
}

proc DWMaterialUpdateProperties { GDN } {
  upvar \#0 $GDN GidData

  set book $GidData(BOOK) 
  set mat [DWGetGIDMaterial $GDN]
  set opt_list [DataBehaviour::GetMaterialsOpts]
  array set book_values [DataBehaviour::Materials 1 $book $opt_list]
  array set mat_values [DataBehaviour::Materials 0 $mat $opt_list]
  foreach opt $opt_list {
    set b $book_values($opt)
    set m $mat_values($opt)
    if {$m eq "hide" || ($m eq "default" && $b eq "hide")} {
      # we must hide the option
      if {[llength [grid info $GidData(widgets,$opt)]]} {
        grid remove $GidData(widgets,$opt)
      }
    } else {
      # we must ensure the the option is visible
      if {![llength [grid info $GidData(widgets,$opt)]]} {
        grid $GidData(widgets,$opt)
      }
      if {$m eq "disable" || ($m eq "default" && $b eq "disable")} {
        # visible but disabled
        $GidData(widgets,$opt) configure -state disabled
      } else {
        # visible and enabled
        $GidData(widgets,$opt) configure -state normal
      }
    }
  }
}

#----------------------------------------CONDITIONS------------------

proc DWReadCondfile { filename } {
    global GidData
    foreach i [array names GidData CND,*] { unset GidData($i) }
    set GidData(CND,nameslist) ""

    set f [open $filename r]
    while { ![eof $f] } {
	gets $f aa
	if { $aa == "" || [string index $aa 0] == "#" } { continue }
	if { ![regexp {NUMBER:[ ]*[0-9]*[ ]*CONDITION:?[ ]*([^ ]*)} \
		$aa {} cndname] } { break }
	lappend GidData(CND,nameslist) $cndname
	set inum 0
	while { ![eof $f] } {
	    gets $f aa
	    if { [string index $aa 0] == "#" } { continue }
	    regexp {^([^ ]*) (.*)$} $aa {} field value
	    if { $field == "END" } { break }
	    if { $field == "QUESTION:" } { incr inum }
	    set GidData(CND,$cndname,$field,$inum) $value
	}
    }
    close $f
}

proc DWSpace2Under { str } {
    regsub -all { } $str {_} str
    return $str
}

proc DWUnder2Space { str } {
    regsub -all {_} $str { } str
    return $str
}

# ------------------------------------------------------------------------------
# DWOnSelectCNDLevel --
#
#  Invoked when a level button is pressed.
# ------------------------------------------------------------------------------

proc DWOnSelectCNDLevel { GDN {cnd_idx first}} {
  upvar \#0 $GDN GidData
  
  if {[set ov $GidData(CND,varlevel)] == $GidData(CND,level)} {
	# ramsan adding
	$GidData(CND,combo) setvalue $cnd_idx
	DWOnSelectCondition $GDN $cnd_idx
	return
  }
  set GidData(CND,level) $ov

  $GidData(CND,combo) configure -values $GidData(CND,$ov,GUINAMES)
  if { [string equal $ov "ovlayer"] } {
    grid remove $GidData(CND,ASSIGN-ENTITY)
    grid $GidData(CND,ASSIGN-LAYER) -row 0 -column 0
  } else {
    grid remove $GidData(CND,ASSIGN-LAYER)
    grid $GidData(CND,ASSIGN-ENTITY) -row 0 -column 0
  }
  # show the condition requested, normally the first one
  $GidData(CND,combo) setvalue $cnd_idx
  DWOnSelectCondition $GDN $cnd_idx
}

proc DWSetCNDLevel { GDN level {cnd_idx first}} {
  upvar \#0 $GDN GidData

  set GidData(CND,varlevel) $level
  DWOnSelectCNDLevel $GDN $cnd_idx
}

# KILL this proc!!!
proc DWChangeCondLevel { GDN } {
    global $GDN
    upvar \#0 $GDN GidData

    set ov $GidData(CND,level)

    $GidData(CND,combo) listbox del 0 end

    foreach CndName $GidData(CND,$ov) {
      $GidData(CND,combo) add $CndName
    }

    if { $GidData(CHANGECND) } {
      set GidData(CND,condname) [lindex $GidData(CND,$ov) 0]
    }

    if { [string equal $ov "ovlayer"] } {
      grid remove $GidData(CND,ASSIGN-ENTITY)
      grid $GidData(CND,ASSIGN-LAYER) -row 0 -column 0
    } else {
      grid remove $GidData(CND,ASSIGN-LAYER)
      grid $GidData(CND,ASSIGN-ENTITY) -row 0 -column 0
   }
}

# ------------------------------------------------------------------------------
# DWAfterFinishButton --
#
# ------------------------------------------------------------------------------

proc DWAfterFinishButton { GDN } {
  .central.s process escape escape escape escape
  # restore the state of the widgets.
  #TriggerDependencies $GDN
}

# DWDrawConds --
#
#       Muestra gráficamente las condiciones asignadas.
#
# Argumentos:
#
#      wCond --> ventana de condiciones desde donde fué invocado.
#      what --> subcomando de draw. Puede tomar los valores:
#
#               - thiscond 
#                  se refiere a la condición actual $GidData(CND,cndname)
#                  si field es "" dibuja todas las condiones, en caso contrario dibuja
#                  dibuja las asociadas al campo $field. Las condiciones se dibujan
#                  con símbolos.
#
#               - thisbook
#
#               - colors 
#                  
#               - allconds
#
#               - allcondsLA
#
#               - allcondsLAC
#      field --> campo asociado se interpreta en función del valor del argumento what
#
# Resultado:
#
#      Las condiciones dibujadas hasta que el usuario presione escape o el botón finish.
     
proc DWDrawConds { GDN what {field ""}} {
  global $GDN
  upvar \#0 $GDN GidData
  
  set _CndName [DWGetGIDCondName $GDN]
  set wCond $GidData(WINDOW)
  
  set singular [DWDownFirstLetter $GidData(CND,singular)]
  
  switch $what {
    thiscond {
      if { $_CndName == "" } {
	WarnWin [_ "Sorry, but first a %s must be selected" $singular] $wCond
	return
      }
      if { $field == "" } {
	.central.s process escape escape escape escape data cond draw \
	    $_CndName \
	    -draw-
      } else {
	.central.s process escape escape escape escape data cond draw \
	    $_CndName \
	    $field
      }
    }
    thisbook {
      .central.s process escape escape escape escape \
	  data cond draw -BOOKS- $GidData(BOOK) -draw-
    }
    thisbookLA {
      .central.s process escape escape escape escape \
	  data cond draw  -LocalAxes- -BOOKS- $GidData(BOOK) -draw-
    }
    thisbookLAC {
      .central.s process escape escape escape escape \
	  data cond draw -LocalAxes- -LocalAxes- -BOOKS- $GidData(BOOK) -draw-
    }
    colors {
      if { $_CndName == ""} {
	WarnWin [_ "Sorry, but first a %s must be selected" $singular] $wCond
	return
      }
      if { $field == "" } {
	.central.s process escape escape escape escape data cond draw \
	    -ByColor- $_CndName \
	    -draw-
      } else {
	.central.s process escape escape escape escape data cond draw \
	    -ByColor- $_CndName \
	    $field
      }
    }
    allconds {
      
      .central.s process escape escape escape escape data cond draw \
	  -drawall-
    }
    thiscondLA {
      if { $_CndName == ""} {
	WarnWin [_ "Sorry, but first a %s must be selected" $singular] $wCond
	return
      }
      .central.s process escape escape escape escape data cond draw \
	  -LocalAxes- $_CndName -draw-
    }
    thiscondLAC {
      if { $_CndName == ""} {
	WarnWin [_ "Sorry, but first a %s must be selected" $singular] $wCond
	return
      }
      .central.s process escape escape escape escape data cond draw \
	  -LocalAxes- -LocalAxes- $_CndName -draw-
    }
    allcondsLA {
      .central.s process escape escape escape escape data cond draw \
	  -LocalAxes- -drawall-
    }
    allcondsLAC {
      .central.s process escape escape escape escape data cond draw \
	  -LocalAxes- -LocalAxes- -drawall-
    }  
  }
  
  set SmallWinSelecting [.central.s info variable SmallWinSelecting]
  FinishButton $wCond $wCond.but [_ "Press 'Finish' to end selection"] \
      "DWAfterFinishButton $GDN" \
      disableall $SmallWinSelecting
}

proc DWUpdateConds { GDN line level cond } {
  global $GDN
  upvar \#0 $GDN GidData

  if { $line == "" } {
    return
  }
  set NumProp $GidData(CND,$cond,numprop)
  
  # ramsan (after changing glwidget-opengl)
  for { set i 0} { $i < $NumProp } { incr i 1 } {
    set GidData(CND,$cond,VALUE,[expr $i+1]) [lindex $line [expr {$i+3}]]
  }
  
  # Cambio de level
  DWSetCNDLevel $GDN $level @[lsearch -exact $GidData(CND,$level,GIDNAMES) $cond]
}

# DWGetSelection --
#
# Argumentos:
#
# Resultados:
#

proc DWGetSelection { lb } {
    set sel [$lb curselection]
    if { [llength $sel] == 0 } {
	if { [$lb size] == 0 } { return "" }
	$lb sel set 0
	set sel [$lb curselection]
    }
    return [$lb get [lindex $sel 0]]
}

proc DWGetBSelection { lb } {
    set sel [$lb curselection]
    if { [llength $sel] == 0 } {
	return ""
    }
    set idx [lindex $sel 0]
    return [list $idx [$lb get $idx]]
}


# DWShowCondEntitiesWin --
#
# Argumentos:
#
# Resultados:
#
proc DWShowCondEntitiesWin { GDN ThisOrAll } {
  global $GDN
  upvar \#0 $GDN GidData
  
  set wCond $GidData(WINDOW)
  set CndName [DWGetGUICondName $GDN]
  set _CndName [DWGetGIDCondName $GDN]
  set singular [DWDownFirstLetter $GidData(CND,singular)]
  if { $_CndName == ""} {
    WarnWin [_ "Sorry, but first a %s must be selected" $singular] $wCond
    return
  }

  set w $wCond.cndwind
  set GeoName DatawCondListEnt$GidData(BOOKORD)\WindowGeom

  if { $ThisOrAll != "allcond" } {
    if { $GidData(BOOK) == "Default" } {
      set Title "$CndName"
    } else {
      set Title "[= [DWUnder2Space $GidData(BOOK)]] : $CndName"
    }
  } else {
    set Title [_ "All %s" $GidData(CND,plural)]
  }
  
  if { [InitWindow $w $Title $GeoName] == "close" } {
    return
  }
  MakeAlwaysOnTop $w
  
  wm minsize  $w 1 1
  
  frame $w.lb -bd 0
  scrollbar $w.lb.yscroll -relief sunken -command \
      "$w.lb.list yview" -bd 1 -elementborderwidth 1
  scrollbar $w.lb.xscroll -relief sunken -orient horizontal \
      -command "$w.lb.list xview" -bd 1 -elementborderwidth 1
  listbox $w.lb.list -yscroll \
      "$w.lb.yscroll set" \
      -xscroll "$w.lb.xscroll set" -relief sunken \
      -selectmode extended -width 30 -height 20 \
      -borderwidth 0 -relief flat -highlightthickness 0
  
  pack $w.lb.yscroll -side right -fill y
  pack $w.lb.xscroll -side bottom -fill x
  pack $w.lb.list -expand yes -fill both
  
  frame $w.but -bg [CCColorActivo [$w cget -background]]
  
  button $w.but.close -text [_ "Close"] -command "destroy $w" -bd 1
  set maxWidth [DWGetMaxWidth $w.but.close 8 "Close" "Transfer" "Send"]
  $w.but.close configure -width $maxWidth
  
  bind $w.but.close <Return> "tkButtonInvoke $w.but.close"
  bind $w <Escape> "tkButtonInvoke $w.but.close"
  
  button $w.but.copy -text [_ "Transfer"] -width $maxWidth \
      -command "DWUpdateConds $GDN \[DWGetSelection $w.lb.list] $GidData(CND,level) $_CndName" -bd 1
  
  menubutton $w.but.back -text [_ "Send"] -width $maxWidth \
      -menu $w.but.back.m -bd [$w.but.copy cget -bd] -relief [$w.but.copy cget -relief]
  
  if { [lindex [.central.s info Project] 4] == "GEOMETRYUSE" } {
    set type geometry
  } else { set type mesh }
  
  if { ![info exists ::GidPriv(LayersAlsoLower)] } {
    set ::GidPriv(LayersAlsoLower) 0
  }
  foreach "current_intv -" [.central.s info intvdata num] break
  
  menu $w.but.back.m
  $w.but.back.m add check -label [_ "Also lower entities"] \
      -var GidPriv(LayersAlsoLower)
  $w.but.back.m add command -label [_ "Send others to layer back"] -command \
      "DWSendEntitiesToBack $w $_CndName $type $w.lb.list $current_intv tobackopposite"
  $w.but.back.m add command -label [_ "Send to layer back"] -command \
      "DWSendEntitiesToBack $w $_CndName $type $w.lb.list $current_intv toback"
  $w.but.back.m add command -label [_ "Bring all to front"] -command \
      "DWSendEntitiesToBack $w $_CndName $type $w.lb.list $current_intv alltofront"
  $w.but.back.m add command -label [_ "Help"] -command \
      "DWSendEntitiesToBack $w $_CndName $type $w.lb.list $current_intv help"
  
  #pack $w.but.copy $w.but.close -side left -padx 5 -pady 5
  if { $ThisOrAll != "allcond" } {
    grid $w.but.copy -row 1 -column 1 -padx 5 -pady 5
    grid $w.but.back  -row 1 -column 2 -padx 5 -pady 5
    grid $w.but.close -row 1 -column 3 -padx 5 -pady 5
  } else {
    grid $w.but.close -row 1 -column 2 -padx 5 -pady 5
  }
  
  pack $w.but -side bottom -fill x
  pack $w.lb -expand yes -fill both -side top
  
  if { [lindex [.central.s info Project] 4] == "GEOMETRYUSE" } {
    set type geometry
  } else { set type mesh }
  
  if { $ThisOrAll != "allcond" } {
    set aa [.central.s info conditions $_CndName $type]    
    if { [string is integer [lindex [lindex $aa 0] 0]] } {
	set indexsort 0
    } else {
	set indexsort 1
    }
    set aa [lsort -integer -index $indexsort $aa]
    foreach i $aa { $w.lb.list insert end $i }
    bind $w.lb.list <Double-1> \
	"DWUpdateConds $GDN \[DWGetSelection $w.lb.list] $GidData(CND,level) $_CndName"
  } else {
    set over {ovpnt ovline ovsurf ovvol ovlayer}
    foreach iover $over {        
      set name [.central.s info conditions $iover]
      if { $name != "" } {
	$w.lb.list insert end "Applied: $iover"
	foreach iname $name {
	  set aa [.central.s info conditions $iname $type]
	  if { [string is integer [lindex [lindex $aa 0] 0]] } {
	    set indexsort 0
	  } else {
	    set indexsort 1
	  }
	  set aa [lsort -integer -index $indexsort $aa]
	  if { $aa != "" } {
	    $w.lb.list insert end "Name: $iname"
	    foreach i $aa { $w.lb.list insert end $i }
	  }
	}
      }
    }
  }
  focus -force $w.lb.list
}

proc DWSendEntitiesToBack { w CndName type list current_intv what } {

    if { $what == "help" } {
	set text [_ "These commands send all entities that have the same condition with the\
		  same data than the selected entities to layers back or the opposite.\n\
		  When an entity is in the layer back, it cannot be viewed neither selected.\n\
		  To send entities again to front, use: Bring All to front"]
	WarnWin $text
	return
    }
    if { $what == "alltofront" } {
	.central.s waitstate 1
	WaitStater::SetWatch $w
	.central.s process Layer BringToFrontAll escape
	.central.s waitstate 0
	WaitStater::UnsetWatch $w
	return
    }
    set selvalues ""
    foreach i [$list curselection] {
	lappend selvalues [lrange [$list get $i] 3 end]
    }
    if { $selvalues == "" } {
	WarnWin [_ "Error: it is necessary to select one or more entities"]
	return
    }
    .central.s waitstate 1
    WaitStater::SetWatch $w
    .central.s disable graphics 1

    foreach "current_intv_new -" [.central.s info intvdata num] break
    if { $current_intv != $current_intv_new } {
	.central.s disable warnline 1
	.central.s process escape escape escape escape data intervals changeinterval \
	    $current_intv escape
	.central.s disable warnline 0
    }

    set isnode 0
    set entities ""
    foreach i [.central.s info conditions $CndName $type] {
	set val [lrange $i 3 end]
	if { [lsearch $selvalues $val] != -1 } {
	    if { [lindex $i 0] == "N" } {
		set isnode 1
		lappend entities [lindex $i 1]
	    } elseif { [lindex $i 0] == "E" } {
		set isnode 0
		lappend entities [lindex $i 1]
	    } elseif { [lindex $i 0] == "L" } {
		lappend entities [lindex $i 1]
	    } else {
		set isnode 0
		lappend entities [lindex $i 0]
	    }
	}
    }

    if { $current_intv != $current_intv_new } {
	.central.s disable warnline 1
	.central.s process escape escape escape escape data intervals changeinterval \
	    $current_intv_new escape
	.central.s disable warnline 0
    }

    if { $entities == "" } {
	WarnWin [_ "No entity sent"]
	.central.s disable graphics 0
	.central.s waitstate 0
	WaitStater::UnsetWatch $w
	return
    }

    set comm ".central.s process"
    switch $what {
	toback {
	    lappend comm layer SendToBack 
	}
	tobackopposite {
	    lappend comm layer SendToBackOpposite 
	}
    }
    if { $::GidPriv(LayersAlsoLower) != 0 } {
	lappend comm LowerEntities
    }
    set ovwhat [lindex [.central.s info conditions $CndName] 0]
    switch $type {
	geometry {
	    switch $ovwhat {
		ovpnt {
		    lappend comm Points
		}
		ovline {
		    lappend comm Lines
		}
		ovsurf {
		    lappend comm Surfaces
		}
		ovvol {
		    lappend comm Volumes
		}
		ovlayer {
		    lappend comm All
		}
	    }
	}
	mesh {
	    if { $ovwhat == "ovlayer" } {
		lappend comm All
	    } elseif { $isnode } {
		lappend comm Nodes
	    } else {
		lappend comm Elements
	    }
	}
    }
    eval $comm
    if { $ovwhat != "ovlayer" } {
	while 1 {
	    eval .central.s process [lrange $entities 0 100]
	    set entities [lrange $entities 101 end]
	    if { $entities == "" } { break }
	}
    } else {
	foreach i $entities {
	    .central.s process layer:$i
	}
    }
    .central.s process escape
    .central.s disable graphics 0
    .central.s process redraw
    .central.s waitstate 0
    WaitStater::UnsetWatch $w
}

# ------------------------------------------------------------------------------
# DWCreateConditionFrame --
#
#  Fill in frame of GDN the info corresponding to current condition.
# ------------------------------------------------------------------------------

proc DWCreateConditionFrame { GDN } {
  upvar \#0 $GDN GidData
  
  DWCreateTabOfTexts $GDN $GidData(CND,mainframe) [DWGetTypeCND $GDN] "Base properties"
}

# ------------------------------------------------------------------------------
# DWOnSelectCondition --
#
#  Invoked under -modifycmd of conditions ComboBox. It should change the condition
#  info showed in the data window.
# ------------------------------------------------------------------------------

proc DWOnSelectCondition { GDN {sel -1}} {
  upvar \#0 $GDN GidData

  if {$sel==-1} {
    if {$GidData(CND,cursel)==[set sel [$GidData(CND,combo) getvalue]]} {
      return
    }
  } else {
    set sel [$GidData(CND,combo) getvalue]
  }
  set GidData(menudraw,needpost) 1
  set GidData(CND,cursel) $sel

  # BACKWARD COMPATIBILITY
  set GidData(CND,condname) [DWGetGUICondName $GDN]
  # REMOVE AFTER VERSION 8.0  

  DWCreateConditionFrame $GDN
  focus $GidData(CND,mainframe)
}

# KILL this proc!!!
proc DWChangeCondName { GDN } {
  global $GDN
  upvar \#0 $GDN GidData
  
  if { $GidData(CND,condname) == "" } { return }
  
  set _CndName [DWGetGIDCondName $GDN]
  set GidData(menudraw,needpost) 1
  
  DWCreateConditionFrame $GDN
  #DWCreateTabOfTexts $GDN $GidData(CND,mainframe) CND,$_CndName "Base properties"
}

proc RaiseIfOpen { w } {
  if { [winfo exists $w] } {
    raise $w
    focus $w
    return 1
  } else {
    return 0
  }
}

proc DWInitWindow { GDclass Book BookOrd UseWindow wvar } {
  global gidDataLabels
  
  upvar $wvar w
  
  array set DataList {
    CND {"Conditions"    .gid.conditions DWConditions}
    MAT {"Materials"     .gid.materials  DWMaterials}
    INT {"Interval Data" .gid.intvdata   DWIntervals}
    PD  {"Problem Data"  .gid.prbdata    DWProblemData}
  }
  
  set w [ExistsDataWindow $GDclass $BookOrd]
  if { $w != "" } {
    if { [wm state $w] != "normal" } {
      wm deiconify $w
    }
    raise $w
    focus $w
    return raised
  }
  set wdata $DataList($GDclass)
  
  if { $Book == "Default" } {
    set Title [lindex $wdata 0]
    if { $gidDataLabels($Title) != "" } {
      set Title $gidDataLabels($Title)
    }
  } else {
    set Title [= [DWUnder2Space $Book]]
  }
  if { $UseWindow == "" } {
    set GeoName "[lindex $wdata 2]$BookOrd\WindowGeom"
    set w [DWGetWindowName [lindex $wdata 1] $BookOrd]
    
    if { [InitWindow $w $Title $GeoName] == "close" } {
      return close
    }
    MakeAlwaysOnTop $w
  } else {
    set w $UseWindow
    wm title $w $Title
  }
  return created
}


proc DWCondWindow { {Book "Default"} {BookOrd 1} {UseWindow ""} } {
  global GIDDEFAULT GidPriv
  global gidDataLabels
  
  set GDN GD_CND_$BookOrd
  if { [DWInitWindow CND $Book $BookOrd $UseWindow w] != "created" } {
    return $GDN
  }
  
  global $GDN
  globalarray $GDN
  upvar \#0 $GDN GidData
  
  set GidData(CALLWIN) DWCondWindow
  set GidData(BOOKORD) $BookOrd
  set GidData(WINDOW) $w
  
  # manipulador que atendera la validacion de los datos
  wm protocol $w WM_DELETE_WINDOW "DWCloseWindow $GDN"
  
  if { ![CNDFillGidData $GDN $Book] } {
    destroy $w
    return
  }
  
  set singular [DWDownFirstLetter $GidData(CND,singular)]
  set Singular [DWUpFirstLetter $GidData(CND,singular)]
  set plural   [DWDownFirstLetter $GidData(CND,plural)]
  set Plural   [DWUpFirstLetter $GidData(CND,plural)]
  
  frame $w.level
  set FirstLevel ""
  foreach i "point line coonsurf volume layer" j "ovpnt ovline ovsurf ovvol ovlayer" {
    if { [lsearch $GidData(levels) $j]!=-1 } {
      
      if { $FirstLevel == "" } {
	set FirstLevel $j
      }
      
      if { ![info exist GidPriv(image_${i}16)] } {
	set GidPriv(image_${i}16) [image create photo -file $GIDDEFAULT/bitmaps/${i}16x16.gif]
      }
      set pp [ $w.level cget -background]
#       radiobutton $w.level.$i -image $GidPriv(image_${i}16) \
#         -variable $GDN\(CND,level\) -value $j -indicatoron 0 -bd 1 -selectcolor $pp
      radiobutton $w.level.$i -image $GidPriv(image_${i}16) \
	  -variable $GDN\(CND,varlevel\) -value $j -indicatoron 0 -bd 1 \
          -highlightthickness 0 \
	  -selectcolor $pp -command "DWOnSelectCNDLevel $GDN" 
      pack $w.level.$i -side left
      GidHelp $w.level.$i [_ "Selecting points, lines, surfaces, volumes or layers\
		only %s belonging to that level are displayed" $plural]
    }
  }

  set GidPriv(ShowIntervalInCond) 0    
  #kike: para mostrar el intervalo actual en la ventana de condiciones
  #problema, solo se refresca el valor al abrir la ventana.
  #No se actualiza la etiqueta al cambiar en C el valor de project->IntvToUse
  #LinkIntVariableTCL("GidPriv(CurrentInterval)",(char*)&project->IntvToUse);    
  #a pesar de que si cambia GidPriv(CurrentInterval)
  #para eso puedo usar set GidPriv(CurrentInterval) [DWGetActiveInterval]
  if { $GidPriv(ShowIntervalInCond)==1 } {      
    #if { ![info exist GidPriv(CurrentInterval)] } {
    #  set GidPriv(CurrentInterval) [DWGetActiveInterval]
    #}
    set GidPriv(CurrentInterval) [DWGetActiveInterval]
    label $w.level.l1 -text [_ "Current Interval:"]
    label $w.level.l2 -textvariable GidPriv(CurrentInterval)
    pack  $w.level.l2 $w.level.l1 -side right      
  }
  
  frame $w.select
  
  #    combobox $w.select.combo -editable 0 -textvariable $GDN\(CND,condname\)
  DWComboBox $w.select.combo -editable 0 -modifycmd "DWOnSelectCondition $GDN"
  set GidData(CND,combo) $w.select.combo

  CreateJumpButton $GDN $w.select 2

#   pack $w.select.combo -side left -expand 1 -anchor sw
#   pack $jumpbutton -side bottom -anchor se
  grid $w.select.combo -row 0 -column 0 -sticky "snew"
  #grid $jumpbutton -row 0 -column 2 -sticky "snew"
  grid columnconfigure $w.select 0 -weight 3
  grid columnconfigure  $w.select 1 -weight 1
  
  frame $w.f -bd 2 -relief groove
  set GidData(CND,mainframe) $w.f
  
  frame $w.but -relief ridge -bd 2
  set AssignEntity $w.but.assign
  button $AssignEntity -text [_ "Assign"] -command "DWAssignCond $GDN" -und 0
  set AssignLayer $w.but.assign_layer
  set MenuLayer $AssignLayer.menu
  menubutton $AssignLayer -text [_ "Assign"] -und 0 -relief raised \
      -menu $MenuLayer -bd 1  -highlightthickness 1
  menu $MenuLayer -bd 1 -activeborderwidth 1 \
      -postcommand "DWPostLayers $GDN $MenuLayer DWAssignCond"
  set GidData(CND,ASSIGN-ENTITY) $AssignEntity
  set GidData(CND,ASSIGN-LAYER) $AssignLayer
  
  # ----- Opcion ENTITIES -----
  #kike button $w.but.ent -text [_ "Entities"] -command "DWEntitiesCond $GDN thiscond" -und 0
  
  set MenuEntities $w.but.ent.menu
  menubutton $w.but.ent -text [_ "Entities"] -und 0 -relief raised \
      -menu $MenuEntities -bd 1  -highlightthickness 1
  menu $MenuEntities -bd 1 -activeborderwidth 1 \
      -postcommand "DWPostEntitiesCnd $GDN $MenuEntities"
  $MenuEntities add command -label  "XXXX" \
      -command "DWEntitiesCond $GDN thiscond"
  $MenuEntities add command -label [_ "All conditions"] \
      -command "DWEntitiesCond $GDN allcond"

    # ----- Opcion DRAW -----
  
  set MenuDraw $w.but.draw.menu 
  menubutton $w.but.draw -text [_ "Draw"] -und 0 -relief raised \
      -menu $MenuDraw -bd 1  -highlightthickness 1
  menu $MenuDraw -bd 1 -activeborderwidth 1 \
      -postcommand "DWPostDrawCond $GDN $MenuDraw"
  
  # ----- Opcion Unassign -----
  
  set MenuUnassign $w.but.unassign.menu
  menubutton $w.but.unassign  -text [_ "Unassign"] -und 0 -relief raised \
      -menu $MenuUnassign -bd 1  -highlightthickness 1
  
  menu $MenuUnassign -bd 1 -activeborderwidth 1 \
      -postcommand "DWPostUnassign $GDN $MenuUnassign"
  
  #pack $w.but.assign $w.but.ent $w.but.draw $w.but.unassign -side left
  grid $w.but.assign -row 0 -column 0 -sticky "w"
  grid $w.but.ent -row 0 -column 1 -sticky "w"
  grid $w.but.draw -row 0 -column 2 -sticky "w"
  grid $w.but.unassign -row 0 -column 3 -sticky "w"
  
  grid columnconfigure $w.but 4 -weight 1
  
  frame $w.but1 -bg [CCColorActivo [$w cget -background]]
  button $w.but1.close -text [_ "Close"] -command "DWCloseWindow $GDN" -und 0
  pack $w.but1.close -pady 5
  
  grid $w.level -row 0 -column 0 -sticky snew
  #pack $w.level -fill x  -side top -padx 2 -pady 2
  #pack $w.f -side top -fill both -expand yes
  grid $w.f -row 2 -column 0 -sticky snew
  #pack $w.combo -side top -anchor nw -padx 2 -pady 2
  #pack $w.select -side top -anchor nw -padx 2 -pady 2 -fill x
  grid $w.select -row 1 -column 0 -sticky snew
  #pack $w.close -side bottom
  #pack $w.but -ipady 3 -fill x
  grid $w.but -row 3 -column 0 -sticky we
  #pack $w.but1 -fill  x
  grid $w.but1 -row 4 -column 0 -sticky snew
  
  grid rowconfigure $w 2 -weight 1
  
  grid columnconfigure $w 0 -weight 1
  
#   trace var GidData(CND,level) w "DWChangeCondLevel $GDN;#"
  
#  set GidData(menudraw,needpost) 0

#  trace var GidData(CND,condname) w "DWChangeCondName $GDN ;#"
  set GidData(CND,level) ""
  DWSetCNDLevel $GDN $FirstLevel
  update idletasks
  wm deicon $w
  focus $w.but.assign
  
  foreach i "$w.but.assign $w.but.ent $w.but.draw $w.but.unassign $w.but1.close" {
    set l [string tolower [string index [$i cget -text] [$i cget -und]]]
    # this may fail when $l is not a valid keysym
    catch {
      bind $w <Alt-$l> "tkButtonInvoke $i ;break"
    }
  }
  bind $w <Escape> "tkButtonInvoke $w.but1.close"
  return $GDN
}

proc DWPostUnassign { GDN m } {
    upvar \#0 $GDN GidData

    set cnd [DWGetGIDCondName $GDN]
    set Singular [DWUpFirstLetter $GidData(CND,singular)]
    set Plural   [DWUpFirstLetter $GidData(CND,plural)]
    set Book     $GidData(BOOK)

    $m del 0 end
    if [string equal $GidData(CND,level) "ovlayer"] {
	$m add cascade -label [_ "%s Layer" $cnd ] -menu $m.mlayer
	if ![winfo exist $m.mlayer] {
	    menu $m.mlayer -bd 1 -activeborderwidth 1
	}
	DWPostLayers $GDN $m.mlayer DWUnassignSome 1
	if ![llength [.central.s info layer]] {
	    $m.mlayer entryconfigure end -state disabled
	}
    } else {
	$m add command -label [_ "%s Entities" $cnd] \
	    -command "DWUnassignSome $GDN"
    }
    $m add command -label [_ "All %s" $cnd] \
	    -command "DWUnassignAllThis $GDN"
    if { $Book != "Default" } {
	$m add command -label [_ "All %s" $Plural] \
	    -command "DWUnassignAllBookCND $GDN"
    }
    $m add command -label [_ "All conditions"] \
	    -command "DWUnassignAllCND $GDN"
}


proc DWPostLayers { GDN m cmd {chk 0} } {
  $m del 0 end
  if { $chk } {
    upvar \#0 $GDN GidData
    set cnd [DWGetGIDCondName $GDN]
    set aa {}
    foreach e [.central.s info conditions $cnd geometry] {
      set texto [lindex $e 1]
      #set texto "$texto ("
      #set bb [lrange $e 3 end]
      #foreach l $bb {
      #        set texto "$texto $l"
      #}
      #set texto "$texto )"
      lappend aa $texto
    }
    foreach l [lsort -unique $aa] {
      $m add command -label $l -command "$cmd $GDN [lindex $l 0]"
    }
  } else {
    foreach l [lsort -unique [.central.s info layer]] {
      $m add command -label $l -command "$cmd $GDN $l"
    }
  }
}



proc DWSendMessage { GDN TYPE itk } {
}

proc DWCheckClose { GDN } {
    upvar \#0 $GDN GidData

    set result ""
    if [catch "CheckDirtyState $GDN" result] {
	if [string equal $result CANCEL] {
	    error CANCEL
	}
	# error in tcl script, show it & continue closing
	WindowMessage "$result"
    }

    set TYPE [eval $GidData(TYPEFUNC) $GDN]
    if { $GidData($TYPE,SYNC,TKWIDGET) } {
	foreach iproc [array names GidData $TYPE,TKWIDGET*] {
	    regexp (?:.)TKWIDGET,(.+) $iproc {} itk
	    if { $itk } {
		set QUESTION $GidData($TYPE,QUESTION,$itk)
	    } else {
		set QUESTION 0
	    }
	  if [catch "$GidData($iproc) CLOSE $GDN [list $TYPE] [list $QUESTION]" result] {
		# follow up the error
		error "Error in tcl script sending event CLOSE to $GidData($iproc): $result"
	    } else {
		set len_res [llength $result]
		if { $len_res > 1 } {
		    if { $len_res != 2 } {
		        WindowMessage "Error '$result' in result from CLOSE event: must be a 2-element list"
		    } else {
		        set status [string toupper [lindex $result 0]]
		        set isERROR [string equal $status ERROR]
		        if { $isERROR || [string equal $status WARNING] } {
		            set msg [lindex $result 1]
		            if [string length $msg] {
		                WindowMessage $msg
		            }
		            if $isERROR {
		                error CANCEL
		            }
		        } else {
		            WindowMessage "invalid status '$status' in SYNC event: must be ERROR or WARNING"
		        }
		    }
		}
	    }
	}
    }
}

proc DWCloseWindow { GDN } {
    upvar \#0 $GDN GidData

    if [catch "DWCheckClose $GDN" result] {
	if [string equal $result CANCEL] {
	    return
	}
	destroy $GidData(WINDOW)
	unset GidData
	error $result
    }
    destroy $GidData(WINDOW)
    unset GidData
}

# DWCreateGrid --
#
#        A partir de una cadena que define una grid #N# N g1 g2 ... gN,
#        crea la estructura con patrón GidData($HEAD,VALUE,i,j) que toma
#        los valores en gk.
# Argumentos:
#
#        HEAD --> encabezamiento de la estructura. 
#                 Ej.  - CND,Point-Constraint
#                      - MAT,Steel
#       iField --> índice del campo asociado.
#       StrValue --> cadena de valores
#
# Resultados:
#

proc DWCreateGrid { GDN HEAD iField StrValues } {
    global $GDN
    upvar \#0 $GDN GidData
    
    set j 0
    
    catch {
	foreach i [array names GidData($HEAD,VALUE,$iField,*)] { 
	    unset GidData($i)
	}
    }
    foreach GridValue $StrValues {
	set GidData($HEAD,VALUE,$iField,$j) [DWUnder2Space $GridValue]
	incr j 1
    }
    incr j -1
    if { $GidData($HEAD,VALUE,$iField,0) != $j } {
	WindowMessage "Incorrect number of values for GRID field $GidData($HEAD,QUESTION,$iField)"
	return 0
    }
    return 1
}

proc VerifyProblemTypeDir { GDN } {
    upvar \#0 $GDN GidData

    if { [set GidData(DirPT) [GetDirectoryProblemType]] == "" } {
	return 0
    }
    
    return 1
}

proc DWMakeSingular { str } {
    set str [string trimright $str]
    set l [string length $str]
    if { $l > 1 } {
	set last [string index $str [expr $l-1]]
	if { $last == "s" || $last == "S" } {
	    if ![regexp -nocase ".*CLASS$" $str] {
		set str [string range $str 0 [expr $l-2]]
	    }
	}
    }

    return $str
}

#  CNDFillGidGata -- 
#     Construye dentro de CNDDataName la estructura con el patron
#     CNDData(CND,*).
#  Argumentos:
#     CNDDataName --> Nombre de la variable donde se creará la estructura.
#  Resultados:
#     Las subestructuras que se generan en CNDDataName son las siguientes:
#       CNDDataName(CND,nameslist) --> Lista de los nombres de las condiciones
#       definidas. Ej.: Point-Constraints Line-Constraints ...
#
#       CNDDataName(CND,<name>,CONDTYPE,0) --> descripción del tipo de condicion
#            para la condicion <name>. Puede tomar uno de los valores:
#            over points, over lines, over surfaces, over volumes.
#
#       CNDDataName(CND,<name>,DIRTY) --> indica si los VALUES han cambiado.
#          Inicialmente no han cnmbiado.
#          0 --> no han cambiado.
#          1 --> han cambiado
#
#       CNDDataName(CND,<name>,numprop) --> cantidad de propiedades.
#
#       CNDDataName(CND,<name>,QUESTION,i) --> valor de la i-ésima QUESTION
#            para la condición <name>. i >= 1.
#
#       CNDDataName(CND,<name>,VALUE,i) --> valor del i-ésima VALUE
#            para la condición <name>. i >= 1.
#
#       CNDDataName(CND,<name>,HELP,i) --> valor de la i-ésima HELP asociada a
#            la i-ésima QUESTION para la condición <name>. i >= 1.
#
       
proc CNDFillGidData { GDN {BOOK Default} } {
  global $GDN
  global gidDataLabels
  upvar \#0 $GDN GidData
  
  
  VerifyProblemTypeDir $GDN
  
  set GidData(BOOK) $BOOK
  #    set GidData(TYPEFUNC) CNDGetType
  set GidData(TYPEFUNC) DWGetTypeCND
  set GidData(CLASS) "Conditions"
  set GidData(top) "CND"
  set GidData(DEPDISABLED) 0
  set GidData(CHANGECND) 1
  
  if { $BOOK == "Default" } {
    if { $gidDataLabels(Conditions) != "" } {
      set GidData(CND,plural) $gidDataLabels(Conditions)
    } else {
      set GidData(CND,plural) [_ "Conditions"]
    }
    
    if { $gidDataLabels(Conditions,singular) != "" } {
      set GidData(CND,singular) $gidDataLabels(Conditions,singular)
    } else {
      set GidData(CND,singular) [_ "Condition"]
    }
  } else {
    set GidData(CND,plural) [= [DWUnder2Space $BOOK]]
    set GidData(CND,singular) [DWMakeSingular  $GidData(CND,plural)]
  }
  
  
  array set PatternNames {
    ovpnt  POINT
    ovline LINE
    ovsurf SURFACE
    ovvol  VOLUME
    ovlayer LAYER
  }
  set CndTypeList { ovpnt ovline ovsurf ovvol ovlayer }
  set CndTypeNameList { "over points" "over lines" "over surfaces" "over volumes" "over layers"}
  
  foreach CndType $CndTypeList CndTypeName $CndTypeNameList {
    set CurCndNameList [.central.s info conditions $CndType]
    
    #lappend GidData(CND,nameslist) $CurCndNameList
    
    foreach CndName $CurCndNameList {
      if {[lindex [::GiD_ConditionBehaviour $CndName visible] 1] eq "disable"} {
        # this condition is not visible
        continue
      }
      # Verifico el book.
      
      set CndBook [.central.s info conditions $CndName BOOK]
      
      if { $CndBook == $BOOK } {
	lappend GidData(levels) $CndType
	set _CndName $CndName
	
	# Convierto _ a espacio.
	
	regexp -nocase ^$PatternNames($CndType)_(.+) $CndName {} CndName
	set CndName [DWUnder2Space $CndName]
	lappend GidData(CND,$CndType,GUINAMES) [= $CndName]
	lappend GidData(CND,$CndType,GIDNAMES) $_CndName
	
	set OtherFieldsList [.central.s info conditions $_CndName OTHERFIELDS]
	set OtherFieldsNum  [lindex $OtherFieldsList 0]
	
	set GidData(CND,$_CndName,VISIBLE) 0
	
	set GidData(CND,$_CndName,STATE) 1
	set GidData(CND,$_CndName,HASLA) 0
	set GidData(CND,$_CndName,CONDTYPE,0) $CndTypeName
	set PropList [.central.s info conditions $_CndName]
	set PropList [lrange $PropList 1 end]
	set NumProp  [lindex $PropList 0]
	set GidData(CND,$_CndName,numprop) $NumProp
	for { set i 1 } { $i <= $NumProp } { incr i 1 } {
	  set qValue [lindex $PropList [expr $i*2-1]]
	  set StringValues [lindex $PropList [expr $i*2]]
	  ProcessField $GDN "CND,$_CndName" $i $qValue $StringValues
	}
	set GidData(BOOK,HASLA) $GidData(CND,$_CndName,HASLA)
	
	for { set i 1 } { $i <= $OtherFieldsNum } { incr i 1 } {
	  set OFType [lindex $OtherFieldsList [expr $i*3-2]]
	  set OFPos [lindex $OtherFieldsList [expr $i*3]]
	  set OFValue [lindex $OtherFieldsList [expr $i*3-1]]
	  ProcessOtherField $GDN "CND,$_CndName" $OFType $OFPos $OFValue
	}
	#GenScriptDependencies $GDN "CND,$_CndName"
	DWBindTrace $GDN "CND,$_CndName"
      }
    }
  }
  return 1
}

#  MATFillGidGata -- 
#     Construye dentro de CNDDataName la estructura con el patron
#     MATDataName(MAT,*).
#  Argumentos:
#     MATDataName --> Nombre de la variable donde se creará la estructura.
#  Resultados:
#     Las subestructuras que se generan en MATDataName son las siguientes:
#       MATDataName(MAT,nameslist) --> Lista de los nombres de los materiales
#       definidos. Ej.: Steel Concrete ...
#
#       MATDataName(MAT,<name>,DIRTY) --> indica si los VALUES han cambiado.
#          Inicialmente no han cnmbiado.
#          0 --> no han cambiado.
#          1 --> han cambiado
#
#       MATDataName(MAT,<name>,numprop) --> cantidad de propiedades.
#
#       MATDataName(MAT,<name>,QUESTION,i) --> valor de la i-ésima QUESTION
#            para el material <name>. i >= 1.
#
#       MATDataName(MAT,<name>,VALUE,i) --> valor del i-ésima VALUE
#            para el material <name>. i >= 1.
#
#       MATDataName(MAT,<name>,<FIELD>,i) --> valor del campo <FIELD>
#            asociado a la i-ésima QUESTION para el material <name>. i >= 1.
       
proc MATFillGidData { GDN { BOOK Default } } {
  global $GDN
  global gidDataLabels
  upvar \#0 $GDN GidData
  
  VerifyProblemTypeDir $GDN
  
  #set GidData(MAT,nameslist) ""
  set GidData(MAT,materials) [list]
  set GidData(BOOK) $BOOK
  set GidData(CLASS) "Materials"
  set GidData(top) "MAT"
  #set GidData(TYPEFUNC) MATGetType
  set GidData(TYPEFUNC) DWGetTypeMAT
  set GidData(FILLFUNC) MATFillGDOnlyValues
  set GidData(SAVEFUNC) DWModifyMat
  set GidData(DEPDISABLED) 0
  
  if { $BOOK == "Default" } {
    if { $gidDataLabels(Materials) != "" } {
      set GidData(MAT,plural) $gidDataLabels(Materials)
    } else {
      set GidData(MAT,plural) [_ "Materials"]
    }
    
    if { $gidDataLabels(Materials,singular) != "" } {
      set GidData(MAT,singular) $gidDataLabels(Materials,singular)
    } else {
      set GidData(MAT,singular) [_ "Material"]
    }
  } else {
    set GidData(MAT,plural) [= [DWUnder2Space $BOOK]]
    set GidData(MAT,singular) [DWMakeSingular $GidData(MAT,plural)]
  }
  
  
  set MatNameList [.central.s info materials]
  
  foreach _MatName $MatNameList {
    
    #set _MatName [string trim $_MatName]
    #set MatName [DWUnder2Space $_MatName]
    set OtherFieldsList [.central.s info materials $_MatName OTHERFIELDS]
    set OtherFieldsNum [lindex $OtherFieldsList 0]
    
    set MatBook [.central.s info materials $_MatName BOOK]
    
    if { $MatBook == $BOOK } {
      #lappend GidData(MAT,nameslist) $MatName
      lappend GidData(MAT,materials) $_MatName
      set PropList [.central.s info materials $_MatName]
      
      set GidData(MAT,$_MatName,VISIBLE) 0
      
      set NumProp [lindex $PropList 0]
      set GidData(MAT,$_MatName,numprop) $NumProp
      
      for { set i 1 } { $i <= $OtherFieldsNum } { incr i 1 } {
	set OFType [lindex $OtherFieldsList [expr $i*3-2]]
	set OFPos [lindex $OtherFieldsList [expr $i*3]]
	set OFValue [lindex $OtherFieldsList [expr $i*3-1]]
	ProcessOtherField $GDN "MAT,$_MatName" $OFType $OFPos $OFValue
      }
      for { set i 1 } { $i <= $NumProp } { incr i 1 } {
	set qValue [lindex $PropList [expr $i*2-1]]
	set StringValues [lindex $PropList [expr $i*2]]
	ProcessField $GDN "MAT,$_MatName" $i $qValue $StringValues
      }        
      #GenScriptDependencies $GDN "MAT,$_MatName"
      DWBindTrace $GDN "MAT,$_MatName"
    }
  }
  return 1
}

array set TypeInfo {
    MAT,ARGS      -1
    CB,ARGS       2
    FUNC,ARGS     2
    LA,ARGS       2
    UNITS,ARGS    0
}

proc ParserType { Question } {
    global TypeInfo

    # reconce una cadena seguida de argmentos entre ()
#     set re "(.+)\#(MAT|CB|LA|FUNC|UNITS|TKWIDGET)\#(.*)\$"
     set re "(.+)\#(MAT|CB|LA|FUNC|UNITS)\#(.*)\$"

    if [regexp -nocase $re $Question {} id type args] {
	set id   [string trim $id]
	set type [string toupper $type]
	set args [string trim $args]
	if { $args == "" } {
	    if { $TypeInfo($type,ARGS) > 0 } {
		WindowMessage "In $Question: field type $type does needs arguments. Assuming ENTRY"
		set type "ENTRY"
	    }
	    return [list $type $id]
	}
	if ![regexp \\((.+)\\)\$ $args {} args] {
	    WindowMessage "In $Question : invalid arguments in $type field. Assuming ENTRY"
	    return [list ENTRY $id]
	}

	# Proceso los argumentos
	
	set _args [split $args ","]
	if { [llength $_args] == 1 } {
	    set _args [split $args " "]
	}
	set args {}
	foreach a $_args {
	    set a [string trim $a]
	    if [string length $a] {
		lappend args [string trim $a]
	    }
	}
	
	if { $TypeInfo($type,ARGS) == 1 } {
	    if { [llength $args] > 1 } {
		set args [lindex $args 0]
		WindowMessage "In $Question: only one argument allowed in $type. Using the first '$args'"
	    }
	}
	return [list $type $id $args]
    }

    set re {([^\(]+)\((.+)\)$}
    if [regexp $re $Question {} id args] {
	# es una grid
	# Proceso los argumentos
	
	set _args [split $args ","]
	if { [llength $_args] == 1 } {
	    set _args [split $args " "]
	}
	set args {}
	foreach a $_args {
	    lappend args [string trim $a]
	}
	return [list "GRID" $id $args]
    }
    return [list "ENTRY" $Question]
}

proc ProcessUnitValue { GDN HEAD Idx ValueName } {
    global $GDN
    upvar \#0 $GDN GidData
    upvar $ValueName Value

    set GidData($HEAD,NUMERATOR,$Idx) ""
    set GidData($HEAD,DENOMINATOR,$Idx) ""
    set GidData($HEAD,MAGNITUD,$Idx) ""
    set GidData($HEAD,IDXUNIT,$Idx)  -1

    ParserNumberUnit $Value n u

    if { $n == "" || $u == ""} {
	return "There must be one number and one unit in expresion $Value"
    } else {
        # [format "%g" $n]
	set GidData($HEAD,VALUENUM,$Idx) $n 
	regsub -all { } $u {} u
	set GidData($HEAD,VALUEUNIT,$Idx) $u
	ParserUnit::Init $u
	ParserUnit::Start
	if { [lindex $ParserUnit::Status 0] != "ERROR" } {
	    CreateExpTextList $ParserUnit::Numerator NumeratorTextList 
	    CreateExpTextList $ParserUnit::Denominator DenominatorTextList
	    set GidData($HEAD,NUMERATOR,$Idx) $NumeratorTextList
	    set GidData($HEAD,DENOMINATOR,$Idx) $DenominatorTextList
	    set UInfo [FindUnitGidAndPrj $ParserUnit::Numerator $ParserUnit::Denominator]
	    
	    if { [llength $UInfo] } {
		set Value "$GidData($HEAD,VALUENUM,$Idx)$GidData($HEAD,VALUEUNIT,$Idx)"
		set GidData($HEAD,UNITVALID,$Idx) 2
		set umag [lindex $UInfo 0]
		set uidx [lindex $UInfo 1]
		set utable [lindex $UInfo 2]
		if ![info exists GidData(MAG,$umag)] {
		    set GidData(MAG,$umag) [.central.s info magnitudes 1 $umag units]
		    set ugl [.central.s info magnitudes 0 $umag units]
		    
		    if { $utable == 1 } {
		        set IdxNeedUpdate 0
		        set gidx 0
		        set GidData($HEAD,IDXUNIT,$Idx) $uidx
		    } else {
		        set IdxNeedUpdate 1
		        set gidx [llength $GidData(MAG,$umag)]
		        incr gidx -1
		    }
		    set lidx 0
		    foreach u $ugl {
		        set N [lindex $u 1]
		        set D [lindex $u 2]
		        if { [FindUnitInList $N $D $GidData(MAG,$umag)] == {} } {
		            lappend GidData(MAG,$umag) $u
		            incr gidx
		        }
		        if { $IdxNeedUpdate && $lidx == $uidx } {
		            set GidData($HEAD,IDXUNIT,$Idx) $gidx
		        }
		        incr lidx
		    }
		} else {
		    set GidData($HEAD,IDXUNIT,$Idx) [FindUnitInList $ParserUnit::Numerator \
		                                         $ParserUnit::Denominator $GidData(MAG,$umag)]
		}
		set GidData($HEAD,MAGNITUD,$Idx) $umag
	    } else {
		set GidData($HEAD,UNITVALID,$Idx) 1
	    }
	} else {
		set GidData($HEAD,UNITVALID,$Idx) 0
	}
    }
    return ""
}

proc DWGetMaterials { books } {
    set strError {}
    if { [llength $books] } {
	set loptions {}
	set visited {}
	set alreadyVisited {}
	set notVisited {}
	set materials [.central.s info materials]
	foreach b $books {
	    if { [lsearch -exact $visited $b] == -1 } {
		lappend visited $b
		set found 0
		foreach m $materials {
		    if ![string compare [.central.s info materials $m BOOK] $b] {
		        lappend loptions $m
		        set found 1
		    }
		}
		if !$found {
		    lappend notVisited $b
		}
	    } else {
		lappend alreadyVisited $b
	    }
	}
	set strError ""
	if [llength $notVisited] {
	    set strError "The following books are not defined: $notVisited"
	}
	if [llength $alreadyVisited] {
	    if [string length $strError] {
		append strError "\n"
	    }
	    append strError "The following books are referenced more than once: $alreadyVisited.\n"
	}
    } else {
	set loptions [.central.s info materials]
	
    }
    if ![llength $loptions] {
	append strError "Requested materials not found"
    }
    return [list $strError $loptions]
}

proc ProcessField { GDN HEAD Idx Question Value } {
  global $GDN
  upvar \#0 $GDN GidData
  
  set Question [string trim $Question]
  set Value [string trim $Value]
  set typeInfo [ParserType $Question]
  
  set FType [lindex $typeInfo 0]
  set fieldName [lindex $typeInfo 1]
  #if { [llength $fieldName] != 1 } {
  #  # Por que no puede contener espacios?????
  #  # investigalo.   
  #  error "Invalid field name '$fieldName' in question '$Question' at $GidData(CLASS)"
  #}
  switch $FType {
    "GRID" {
      set GidData($HEAD,HEADINGS,$Idx) [lindex $typeInfo end]
      if { [llength $Value] > 2 && [lindex $Value 0] == "#N#" } {
	if { [lindex $Value 1] != [expr [llength $Value]-2] } {
	  error "Error in $HEAD: #N# GRID field $fieldName, declared [lindex $Value 1] values but exists [expr [llength $Value]-2]"
	}
	DWCreateGrid $GDN $HEAD $Idx [lrange $Value 1 end]
      } else {
	set FType "ENTRY"
	set fieldName $Question
      }
    }
    "UNITS" {
      set err_str [ProcessUnitValue $GDN $HEAD $Idx Value]
      if { $err_str != "" } {
	error "$err_str in field: $Question"
      }
      
    }
    "MAT" -
    "LA" -
    "CB" {
      if { $FType == "LA" } {
	set GidData($HEAD,CBTYPE,$Idx) "COMBO"
	set GidData($HEAD,OPTIONS1,$Idx) [.central.s info localaxes]
	set GidData($HEAD,OPTIONS,$Idx) {}
	foreach i [lindex $typeInfo end] {
	  regsub -nocase (\#A\#|\#G\#)$ $i {} text
	  lappend GidData($HEAD,OPTIONS,$Idx) $text
	}
	set GidData($HEAD,CBTEXT,$Idx) [= [DWUnder2Space $Value]]
	set GidData($HEAD,POSTING,$Idx) 0
	set GidData($HEAD,HASLA) 1
      } else {
	if { $FType == "MAT" } {
          set GidData($HEAD,MATFIELD,BOOKS) [lindex $typeInfo 2]
	  set infomat [DWGetMaterials [lindex $typeInfo 2]]
	  set strError [lindex $infomat 0]
	  if [string length $strError] {
	    WindowMessage $strError
	  }
	  if [llength [set loptions [lindex $infomat 1]]] {
	    set GidData($HEAD,OPTIONS,$Idx) $loptions
	    set isCombo 1
	  } else {
	    set FType "ENTRY"
	    set isCombo 0
	    WindowMessage "In $Question: requested materials not found. Assuming ENTRY field"
	  }
	} else {
	  set GidData($HEAD,OPTIONS,$Idx) [lindex $typeInfo end]
	  set len [llength $GidData($HEAD,OPTIONS,$Idx)]
	  set isCombo 0
	  if { $len == 1 } {
	    set GidData($HEAD,CBTYPE,$Idx) "LABEL"
	  } elseif { $len == 2 } {
	    set firstisyes [isyes [lindex $GidData($HEAD,OPTIONS,$Idx) 0]]
	    set secondisyes [isyes [lindex $GidData($HEAD,OPTIONS,$Idx) 1]]
	    if $firstisyes {
	      set GidData($HEAD,CBTYPE,$Idx) [list "CHECKBOX" 0 1]
	    } elseif $secondisyes {
	      set GidData($HEAD,CBTYPE,$Idx) [list "CHECKBOX" 1 0]
	    } else {
	      set isCombo 1
	    }
	  } else {
	    set isCombo 1
	  }
	}
	if $isCombo {
	  set GidData($HEAD,CBTYPE,$Idx) "COMBO"
	  if { [set GidData($HEAD,CURSEL,$Idx) [lsearch -exact $GidData($HEAD,OPTIONS,$Idx) $Value]] == -1 } {
	    set GidData($HEAD,CURSEL,$Idx) 0
	    set Value [lindex $GidData($HEAD,OPTIONS,$Idx) 0]
	  }
	  set GidData($HEAD,CBTEXT,$Idx) [= [DWUnder2Space $Value]]
	  set GidData($HEAD,POSTING,$Idx) 0
	}
      }
    }
    default {
      #set Value [DWUnder2Space [string trim $Value]]
      set Value [string trim $Value]
    }
  }
  set GidData($HEAD,QUESTION,$Idx) $fieldName
  set GidData($HEAD,LABELQ,$Idx) [= [DWUnder2Space $fieldName]] 
  set GidData($HEAD,VALUE,$Idx) $Value
  set GidData($HEAD,TYPE,$Idx) $FType
}


# Este proc es utilizado for GenericFillGDFull en los eventos accept
# de los datos parciales intvdata y gendata

proc ProcessFieldOnlyValue { GDN HEAD Idx Question Value } {
    global $GDN
    upvar \#0 $GDN GidData

    set Question [string trim $Question]
    set Value [string trim $Value]
    set typeInfo [ParserType $Question]
    set FType [lindex $typeInfo 0]
    set fieldName [lindex $typeInfo 1]

    # QUE impide que un campo tenga espacios?

    if { [llength $fieldName] != 1 } {
	error "Invalid field name '$fieldName' in question '$Question' at $GidData(CLASS)"
    }
    switch $FType {
	"GRID" {

	    set GidData($HEAD,HEADINGS,$Idx) [lindex $typeInfo end]
	    if { [llength $Value] > 2 && [lindex $Value 0] == "#N#" } {
		DWCreateGrid $GDN $HEAD $Idx [lrange $Value 1 end]
	    } else {
		set FType "ENTRY"
		set fieldName $Question
	    }
	}
	UNITS {
	    if { [set err_str [ProcessUnitValue $GDN $HEAD $Idx Value]] != "" } {
		tk_dialogRAM .gid.err [_ "Error"] \
		    [join [list $err_str " [_ "in field:"] $Question"] ""] error 0 [_ "OK"]
	    }
	}
    }
    set GidData($HEAD,QUESTION,$Idx) $fieldName
    set GidData($HEAD,VALUE,$Idx) $Value
    set GidData($HEAD,TYPE,$Idx) $FType
}


proc MATFillGDOnlyValues { GDNOV GDN } {
  global $GDN $GDNOV
  upvar \#0 $GDN GidData
  upvar \#0 $GDNOV GDOnlyValue
  
  # Nombre del material actual.
  
  #     set MatName $GidData(MAT,prevmatname)
  #     set _MatName [DWSpace2Under $MatName]
  set _MatName [DWGetGIDMaterial $GDN]
  
  set PropList [.central.s info materials $_MatName]
  set NumProp [lindex $PropList 0]
  set GDOnlyValue(MAT,$_MatName,numprop) $NumProp
  
  for { set i 1 } { $i <= $NumProp } { incr i 1 } {
    set qValue [lindex $PropList [expr $i*2-1]]
    set StringValues [lindex $PropList [expr $i*2]]
    ProcessField $GDNOV "MAT,$_MatName" $i $qValue $StringValues
  }
}

proc CheckDirtyState { GDN } {
  global $GDN gidSubstDataBooks
  
  upvar \#0 $GDN GidData
 
  if { $gidSubstDataBooks || ![info exists GidData(SAVEFUNC)] } {
    return
  }

  # OJO el type ya va en GidData, revisar BuildStringValues
  set CurValues  [BuildStringValues $GDN]

  set TYPE [eval $GidData(TYPEFUNC) $GDN]
  
  if { [string compare $CurValues $GidData(FIRSTSTATE)] } {
    set strMes [_ "Data has changed. Do you want to save it?"]
    set Title [_ "Warning:"][_ $GidData(CLASS)]-[= [DWUnder2Space $GidData(BOOK)]]
    set answer [tk_dialogRAM .gid.askyn  $Title\
		    $strMes question 0 [_ "Yes"] [_ "No"]]
    switch $answer {
      0 {
	set GidData($TYPE,SYNC,TKWIDGET) 0
	eval $GidData(SAVEFUNC) $GDN
	set GidData($TYPE,SYNC,TKWIDGET) 1
      }
      1 {
	# do not save the data & continue
      }
      2 {
	# abort the operation
	error CANCEL
      }
    }
  }
}

proc DWGetGIDCondName { GDN } {
  upvar \#0 $GDN GidData
  
  lindex $GidData(CND,$GidData(CND,level),GIDNAMES) $GidData(CND,cursel)    
}

proc DWGetGUICondName { GDN } {
  upvar \#0 $GDN GidData

  lindex $GidData(CND,$GidData(CND,level),GUINAMES) $GidData(CND,cursel)    
}

proc DWGetTypeCND { GDN } {
  upvar \#0 $GDN GidData
  
  return "CND,[DWGetGIDCondName $GDN]"
}

proc DWGetTypeID { GDN } {
    return ID
}

proc DWGetTypePD { GDN } {
    return PD
}

# ------------------------------------------------------------------------------
# DWGetTypeMAT --
#
#  return the prefix of the element's index in GDN for the current material
# ------------------------------------------------------------------------------

proc DWGetTypeMAT { GDN } {
  upvar \#0 $GDN GidData

  return "MAT,[DWGetGIDMaterial $GDN]"
}

#  GenericFillGidGata -- 
#     Construye dentro de GidDataName la estructura con el patron
#     GidDataName($TYPE,*).
#  Argumentos:
#     TYPE --> Es el nombre del tipo de estructura. Puede tomar los valores:
#       ID : interval data.
#       PD : problem data.
#     GidDataName --> Nombre de la variable donde se creará la estructura.
#  Resultados:
#     Las subestructuras que se generan en GidDataName son las siguientes:
#
#       GidDataName($TYPE,DIRTY) --> indica si los VALUES han cambiado.
#          Inicialmente no han cnmbiado.
#          0 --> no han cambiado.
#          1 --> han cambiado
#
#       GidDataName($TYPE,numprop) --> número de propiedades.
#
#       GidDataName($TYPE,QUESTION,i) --> valor de la i-ésima QUESTION
#
#       GidDataName($TYPE,VALUE,i) --> valor del i-ésima VALUE
#
#       GidDataName($TYPE,<FIELD>,k) --> valor del campo <FIELD>
#            asociado a la k-ésima QUESTION. k >= 1.
       
proc GenericFillGidData { GDN TYPE {BOOK Default} } {
  global $GDN
  global gidDataLabels
  upvar \#0 $GDN GidData
  
  VerifyProblemTypeDir $GDN
  
  switch $TYPE {
    "ID" {
      set DataArg intvdata
      set GidData(TYPEFUNC) DWGetTypeID
      set GidData(SAVEFUNC) DWIntervalAccept
      set GidData(CLASS) "Interval Data"
      
      # Activo el primer intervalo, es donde se definen los BOOKS.
      
      DWSetActiveInterval 1
    }
    "PD" {
      set DataArg gendata
      set GidData(TYPEFUNC) DWGetTypePD
      set GidData(SAVEFUNC) DWProblemAccept
      set GidData(CLASS) "Problem Data"
    }
    default {
      error "Tipo de dato inválido en GenericFillGidData: $TYPE"
    }
  }
  set GidData(top) $TYPE
  set GidData(FILLFUNC) GenericFillGDOnlyValues
  set GidData(BOOK) $BOOK
  set GidData(DEPDISABLED)   0
  set GidData($TYPE,VISIBLE) 0
  
  set name $GidData(CLASS)
  if { $BOOK == "Default" } {
    if { $gidDataLabels($name) != "" } {
      set GidData($TYPE,plural) $gidDataLabels($name)
    } else {
      set GidData($TYPE,plural) [_ $name]
    }
    
    if { $gidDataLabels($name,singular) != "" } {
      set GidData($TYPE,singular) $gidDataLabels($name,singular)
    } else {
      set GidData($TYPE,singular) [_ $name]
    }
  } else {
    set GidData($TYPE,plural) [= [DWUnder2Space $BOOK]]
    set GidData($TYPE,singular) [DWMakeSingular $GidData($TYPE,plural)]
  }

  set PropList [.central.s info $DataArg]
  
  set NumProp [lindex $PropList 0]
  set NumPropReal 0
  
  set OtherFieldsList [.central.s info $DataArg OTHERFIELDS]
  
  set OtherFieldsNum  [lindex $OtherFieldsList 0]
  
  set BookStart [lsearch -exact $OtherFieldsList $BOOK]
  
  if { $BookStart != -1 } {
    set RestList [lrange $OtherFieldsList $BookStart end]
    set BookStart [expr [lindex $RestList 1]+ 1]
    set BookEnd [lsearch -exact $RestList BOOK]
    if { $BookEnd == -1 } {
      set BookEnd $NumProp
    } else {
      set BookEnd [lindex $RestList [expr $BookEnd + 2]]
    }
  } else {
    set BookStart 1
    set BookEnd $NumProp
  }
  
  set GidData($TYPE,numprop) [expr $BookEnd - $BookStart + 1]
  set GidData($TYPE,BSTART) $BookStart
  set GidData($TYPE,BEND) $BookEnd
  
  for { set i $BookStart; set j 1 } { $i <= $BookEnd } { incr i; incr j} {
    set qValue [lindex $PropList [expr $i*2-1]]
    set StringValues [lindex $PropList [expr $i*2]]
    
    ProcessField $GDN "$TYPE" $j $qValue $StringValues
  }
  
  incr BookStart -1

  for { set i 1 } { $i <= $OtherFieldsNum } { incr i 1 } {
    set OFPos [lindex $OtherFieldsList [expr $i*3]]
    if { ($OFPos >= $BookStart) && ($OFPos <= $BookEnd) } {
      set OFType [string toupper [lindex $OtherFieldsList [expr $i*3-2]]]
      if { $OFPos == $BookStart && $OFType != "TITLE" && $OFType != "TKWIDGET" } {
	continue
      }
      if { $OFPos == $BookEnd && $OFType == "TITLE" } {
	continue
      }
      set OFValue [lindex $OtherFieldsList [expr $i*3-1]]
      set OFIdx [expr $OFPos - $BookStart]
      ProcessOtherField $GDN $TYPE $OFType $OFIdx $OFValue
    }
  }
  
  DWBindTrace $GDN $TYPE
  return 1
}

proc DWRefillIntervalData { GDN } {
  global $GDN
  upvar \#0 $GDN GidData
  
  set BOOK $GidData(BOOK)
  
  set PropList [.central.s info intvdata]
  set NumProp [lindex $PropList 0]
  
  set BookStart $GidData(ID,BSTART)
  set BookEnd   $GidData(ID,BEND) 
  
  for { set i $BookStart; set j 1 } { $i <= $BookEnd } { incr i; incr j} {
    set StringValues [lindex $PropList [expr $i*2]]
    set GidData(ID,VALUE,$j) $StringValues
    if { [lindex $StringValues 0] == "#N#" } {
      DWCreateGrid $GDN ID $j [lrange $StringValues 1 end]
    }
  }
}

proc ProcessOtherField { GDN TYPE OFT OFI OFV } {
    upvar \#0 $GDN GidData

    set OFT [string toupper $OFT]

    switch $OFT {
	TITLE {
	    #WarnWin "TITLE: $OFI --> $OFV"
	    set OFV [DWUnder2Space $OFV]
	    set GidData($TYPE,TITLESTATE,$OFI) normal
	    set GiDData($TYPE,ORIGINALTITLE,$OFI) $OFV
	}
	IMAGE {
	    if { ![file exist [set f [file join $GidData(DirPT) $OFV]]] } {
		WindowMessage "File $f does not exist"
		return
	    }
	    if [catch {set GidData($TYPE,IMGOBJ,$OFI) [image create bitmap -file $f]}] {
		if [catch {set GidData($TYPE,IMGOBJ,$OFI) [image create photo -file $f]}] {
		    WindowMessage "Image '$f' is not correct"
		    return
		}
	    }
	    trace var GidData($TYPE,IMGOBJ,$OFI) u "DWDeleteAssociatedImage $GidData($TYPE,IMGOBJ,$OFI)"
	}
	LABEL {
	    set GidData($TYPE,LABEL,$OFV) $OFI
	    return
	}
	STATE {
	    switch [string toupper $OFV] {
		DISABLED {
		    set OFV disabled
		}
		HIDDEN {
		    set OFV hidden
		}
		NORMAL -
		default {
		    # asumo estado normal
		    set OFV normal
		}
	
	    }
	}
	DEPENDENCIES {
	    ParserDep::Init $OFV
	    if { ![ParserDep::Start] } {
		set WarnStr "Syntax error in dependencies at field $OFI. "
		append WarnStr "Assuming no dependencies\n"
		append WarnStr $ParserDep::ErrFound
		WindowMessage $WarnStr
		return
	    }
	    # Si ya existen dependencias asociadas a este campo tenemos que 
	    # anexarlas.
	    
	    append GidData($TYPE,DEPSOURCE,$OFI) $ParserDep::DepList " "
	    #set GidData($TYPE,DEPENDENCIES,$OFI) $ParserDep::DepList
	    return
	}
    }
    set GidData($TYPE,$OFT,$OFI) $OFV
}

proc GenericFillGDFull { GDN TYPE FGDN } {
  global $GDN $FGDN
  upvar \#0 $GDN GidData
  upvar \#0 $FGDN FGidData
  
  switch $TYPE {
    "ID" {
      set DataArg intvdata
    }
    "PD" {
      set DataArg gendata
    }
    default {
      error "Tipo de dato inválido: $TYPE"
    }
  }
  
  set FGidData($TYPE,SYNC,TKWIDGET) 0
  set FGidData(TYPEFUNC) $GidData(TYPEFUNC)
  
  set PropList [.central.s info $DataArg]
  set NumProp [lindex $PropList 0]
  
  set FGidData($TYPE,numprop) $NumProp
  
  for { set i 1 } { $i <= $NumProp } { incr i } {
    set qValue [lindex $PropList [expr $i*2-1]]
    #regsub -all {\[} $qValue {\\[} qValue
    set StringValues [lindex $PropList [expr $i*2]]
    
    ProcessFieldOnlyValue $FGDN $TYPE $i $qValue $StringValues
  }
  
  # No necesito los OTHERFIELDS.
  
  # Ahora sustituyo los valores de FGidData por los de GidData
  # Hay que tener cuidado con las Grid y las unidades
  
  set NumProp $GidData($TYPE,numprop)
  set Start $GidData($TYPE,BSTART)
  set End   $GidData($TYPE,BEND)
  
  for { set i 1; set j $Start } { $i <= $NumProp } { incr i; incr j } {
    set Value $GidData($TYPE,VALUE,$i)
    switch $GidData($TYPE,TYPE,$i) {
      GRID {
        set NumCells $GidData($TYPE,VALUE,$i,0)
        set FNumCells $FGidData($TYPE,VALUE,$j,0)
        set FGidData($TYPE,VALUE,$j,0) $NumCells
        for {set k 1} {$k <= $NumCells} {incr k} {
          set FGidData($TYPE,VALUE,$j,$k) $GidData($TYPE,VALUE,$i,$k)
        }
        for {} { $k <= $FNumCells } { incr k } {
          unset FGidData($TYPE,VALUE,$j,$k)
        }
      }
      UNITS {
        set FGidData($TYPE,VALUE,$j) $Value
      }
      default {
        set FGidData($TYPE,VALUE,$j) $Value
      }
    }
  }
}


proc DWBindTrace { GDN TYPE } {
    upvar \#0 $GDN GidData

    set until $GidData($TYPE,numprop)
    for { set i 1 } { $i <= $until } { incr i } {
	DeleteTrace GidData($TYPE,STATE,$i) "DWOnChangeSTATE $GDN $TYPE $i ; \#"
	trace variable GidData($TYPE,STATE,$i) w "DWOnChangeSTATE $GDN $TYPE $i ; \#"
	# enlazo las dependencias primero
	if [info exists GidData($TYPE,DEPSOURCE,$i)] {
	    if { [ScriptGen $GDN $TYPE $i $GidData($TYPE,DEPSOURCE,$i) GidData($TYPE,DEPENDENCIES,$i) WarnStr] } {
		CreateTraceProc $GDN $TYPE $i
		DeleteTrace GidData($TYPE,VALUE,$i) [DWGetDepTraceCmd $GDN $TYPE $i]
		trace variable GidData($TYPE,VALUE,$i) w [DWGetDepTraceCmd $GDN $TYPE $i]
	    } else {
		unset GidData($TYPE,DEPENDENCIES,$i)
		WindowMessage "Error in dependencies : $WarnStr\n Assuming no dependencies.($GidData($TYPE,DEPSOURCE,$i))"
	    }
	}
	set ftype $GidData($TYPE,TYPE,$i)
	switch $ftype {
	    "MAT" -
	    "LA" -
	    "CB" {
		if { $GidData($TYPE,CBTYPE,$i) == "COMBO" } {
		    # limpio el trace de CURSEL
		    
		    DeleteTrace GidData($TYPE,CURSEL,$i)      "DWOnChangeCURSEL $GDN $TYPE $i; \#"
		    trace variable GidData($TYPE,CURSEL,$i) w "DWOnChangeCURSEL $GDN $TYPE $i; \#"
		    
		    # limpio el trace de VALUE
		    DeleteTrace GidData($TYPE,VALUE,$i)      "DWOnChangeCBVALUE $GDN $TYPE $i; \#"
		    trace variable GidData($TYPE,VALUE,$i) w "DWOnChangeCBVALUE $GDN $TYPE $i; \#"
		    set GidData($TYPE,SYNC,$i) 1
		}
	    }
	    "GRID" {
		set GidData($TYPE,OLDVALUE,$i) $GidData($TYPE,VALUE,$i)
		DeleteTrace GidData($TYPE,VALUE,$i)      "DWOnChangeGRIDVALUE $GDN $TYPE $i; \#"
		trace variable GidData($TYPE,VALUE,$i) w "DWOnChangeGRIDVALUE $GDN $TYPE $i; \#"
	    }
	    "UNITS" {
		set GidData($TYPE,OLDVALUENUM,$i) $GidData($TYPE,VALUENUM,$i)
		DeleteTrace GidData($TYPE,VALUENUM,$i) \
                    "DWOnChangeVALUENUM $GDN $TYPE $i; \#"
		trace variable GidData($TYPE,VALUENUM,$i) w \
                    "DWOnChangeVALUENUM $GDN $TYPE $i; \#"
		DeleteTrace GidData($TYPE,VALUE,$i) \
                    "DWOnChangeUNITFIELD $GDN $TYPE $i; \#"
		trace variable GidData($TYPE,VALUE,$i) w \
                    "DWOnChangeUNITFIELD $GDN $TYPE $i; \#"
		DeleteTrace GidData($TYPE,IDXUNIT,$i) \
                    "DWUpdateStrUnit $GDN $TYPE $i; \#"
		if { $GidData($TYPE,UNITVALID,$i) == 2 } {
		    trace variable GidData($TYPE,IDXUNIT,$i) w \
                        "DWUpdateStrUnit $GDN $TYPE $i; \#"
		}
		set GidData($TYPE,SYNC,$i) 1
	    }
	}
    }
}

proc DWOnChangeGRIDVALUE { GDN TYPE Idx } {
    upvar \#0 $GDN GidData

    set NewValue $GidData($TYPE,VALUE,$Idx)

    if { ([lindex $NewValue 0] != "\#N\#") || ![regexp {^[ ]*[1-9]+[0-9]*[ ]*$} [lindex $NewValue 1]] } {
	WindowMessage "Invalid value $NewValue for GRID field $GidData($TYPE,QUESTION,$Idx)"
    } else {
	if [DWCreateGrid $GDN $TYPE $Idx [lrange $NewValue 1 end]] {
	    set GidData($TYPE,OLDVALUE,$Idx) $NewValue
	} else {
	    DWCreateGrid $GDN $TYPE $Idx [lrange $GidData($TYPE,OLDVALUE,$Idx) 1 end]
	    set GidData($TYPE,VALUE,$Idx) $GidData($TYPE,OLDVALUE,$Idx)
	}
    }
}

proc DWOnChangeSTATE { GDN TYPE Idx } {
    upvar \#0 $GDN GidData
    
    set cm [split $TYPE ","]
    set top [lindex $cm 0]
    set member [lindex $cm 1]
    set class [ClassInfo::GetClass $top]
    set question $GidData($TYPE,QUESTION,$Idx)
    if [catch "GiD_AccessValue set $class $member $question STATE $GidData($TYPE,STATE,$Idx)"] {

    }
}

proc DWUpdateStrUnit { GDN TYPE Idx } {
    upvar \#0 $GDN GidData

    set UInfo [lindex $GidData(MAG,$GidData($TYPE,MAGNITUD,$Idx)) $GidData($TYPE,IDXUNIT,$Idx)]
    set GidData($TYPE,VALUEUNIT,$Idx) [lindex $UInfo end]
}

proc DWOnChangeVALUENUM { GDN TYPE Idx } {
    upvar \#0 $GDN GidData
    
    if $GidData($TYPE,SYNC,$Idx) {
	if { $GidData($TYPE,VALUENUM,$Idx) == "" || $GidData($TYPE,VALUENUM,$Idx) == "-" } return
	#          if [catch { set r [format "%g" $GidData($TYPE,VALUENUM,$Idx)] }] {
	#              WindowMessage "Invalid value: $GidData($TYPE,VALUENUM,$Idx), must be a real number"
	#              set GidData($TYPE,VALUENUM,$Idx) $GidData($TYPE,OLDVALUENUM,$Idx)
	#          } else {
	#              set GidData($TYPE,SYNC,$Idx) 0
	
	#              set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
	#              set GidData($TYPE,SYNC,$Idx) 1
	#          }
	set GidData($TYPE,SYNC,$Idx) 0
	set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
	
	set GidData($TYPE,SYNC,$Idx) 1
    }
}

proc DWOnChangeUNITFIELD { GDN TYPE Idx } {
    upvar \#0 $GDN GidData
    
    if $GidData($TYPE,SYNC,$Idx) {

	ParserNumberUnit $GidData($TYPE,VALUE,$Idx) n u

	if { $n == "" || $u == "" } {
	    # Muesto el error
	    WindowMessage "Invalid unit expresion $GidData($TYPE,VALUE,$Idx) in question $GidData($TYPE,QUESTION,$Idx). There must be one number and one unit"
	    # Restauro el valor anterior valido
	    set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
	} else {
	    #set n [format "%g" $n]
	    regsub -all { } $u {} u
	    ParserUnit::Init $u
	    ParserUnit::Start
	    if { [lindex $ParserUnit::Status 0] == "ERROR" } {
		# Muesto el error
		WindowMessage "Invalid unit expresion $GidData($TYPE,VALUE,$Idx) in question $GidData($TYPE,QUESTION,$Idx)"
		# Restauro el valor anterior valido
		set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
	    } else {
		set GidData($TYPE,SYNC,$Idx) 0
		if { $GidData($TYPE,UNITVALID,$Idx) == 2 } {
		    set UInfo [FindUnitGidAndPrj $ParserUnit::Numerator $ParserUnit::Denominator]
		    if [llength $UInfo] {
		        set umag [lindex $UInfo 0]
		        if { $umag == $GidData($TYPE,MAGNITUD,$Idx) } {
		            set GidData($TYPE,VALUENUM,$Idx) $n
		            set GidData($TYPE,IDXUNIT,$Idx) \
		                [FindUnitInList $ParserUnit::Numerator \
		                     $ParserUnit::Denominator $GidData(MAG,$umag)]
		        } else {
		            WindowMessage "Incompatible unit $u for question $GidData($TYPE,QUESTION,$Idx)"
		            # Restauro el valor anterior valido
		            set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
		        }
		    } else {
		        # Muesto el error
		        WindowMessage "Unit $u not defined in question $GidData($TYPE,QUESTION,$Idx)"
		        # Restauro el valor anterior valido
		        set GidData($TYPE,VALUE,$Idx) "$GidData($TYPE,VALUENUM,$Idx)$GidData($TYPE,VALUEUNIT,$Idx)"
		    }
		} else {
		    set GidData($TYPE,VALUENUM,$Idx) $n
		}
		set GidData($TYPE,SYNC,$Idx) 1
	    }
	}
    }
}



# Este es el trace lanzado por CURSEL, cuando se escoge una opcion en el CB

proc DWOnChangeCURSEL { GDN TYPE Idx } {
    upvar \#0 $GDN GidData

    if !$GidData($TYPE,POSTING,$Idx) {
	if $GidData($TYPE,SYNC,$Idx) {

	    set GidData($TYPE,SYNC,$Idx) 0
	    set m [lindex $GidData($TYPE,WIDGET,$Idx) 0].m
	    set i $GidData($TYPE,CURSEL,$Idx)
	    set l [llength $GidData($TYPE,OPTIONS,$Idx)]
	    if { $i < $l } {
		set GidData($TYPE,VALUE,$Idx) [lindex $GidData($TYPE,OPTIONS,$Idx) $i]
	    } else {
		set GidData($TYPE,VALUE,$Idx) [lindex $GidData($TYPE,OPTIONS1,$Idx) [expr $i-$l]]
	    }
	    set GidData($TYPE,SYNC,$Idx) 1
	}
	# Actualizo el texto del boton
      set GidData($TYPE,CBTEXT,$Idx) [= [DWUnder2Space $GidData($TYPE,VALUE,$Idx)]]
    }
}

proc DWParseCBValue { value chkType } {

    set value [string trim $value]
    set re "^(.*)\#(MAT|CB)\#(.*)\$"

    set strError ""

    if [regexp -nocase $re $value {} value type args] {
	set value [string trim $value]
	set type [string toupper $type]
	set args [string trim $args]

	if [string compare $chkType $type] {
	    return [list "type mismatch ($type != $chkType): must be $chkType" {} {}]
	}

	if [string length $args] {
	    if ![regexp \\((.+)\\)\$ $args {} args] {
		return [list "invalid arguments in $type field." {} {}]
	    }
	    set _args [split $args ","]
	    if { [llength $_args] == 1 } {
		set _args [split $args " "]
	    }
	    set args {}
	    foreach a $_args {
		set a [string trim $a]
		if [string length $a] {
		    lappend args [string trim $a]
		}
	    }
	}

	if ![string compare $type "MAT"] {
	    set infomat [DWGetMaterials $args]
	    set strError [lindex $infomat 0]
	    set args [lindex $infomat 1]
	    
	} elseif ![llength $args] {
	    set strError "CB field needs arguments"
	    set value {}
	}
	
	return [list $strError $value $args]
    }
	
    return [list "" $value]
}

proc DWRestoreCBValue { GDN TYPE Idx } {
    upvar \#0 $GDN GidData

    set loptions $GidData($TYPE,OPTIONS,$Idx)
    if ![string compare $GidData($TYPE,TYPE,$Idx) "LA"] {
	lappend loptions $GidData($TYPE,OPTIONS1,$Idx)
    }
    set GidData($TYPE,VALUE,$Idx) [lindex $loptions $GidData($TYPE,CURSEL,$Idx)]
}

# Este es el trace lanzado por VALUE,
# por ejemplo desde una dependencia.

proc DWOnChangeCBVALUE { GDN TYPE Idx } {
  upvar \#0 $GDN GidData
  
  if $GidData($TYPE,SYNC,$Idx) {
    set GidData($TYPE,SYNC,$Idx) 0
    set changeOptions 0
    set co -1
    
    if [string compare $GidData($TYPE,TYPE,$Idx) "LA"] {
      # Es #MAT# o #CB#
      
      # No usar ParseType, permitir valor vacio ==> mantener el valor actual
      
      set cbInfo [DWParseCBValue $GidData($TYPE,VALUE,$Idx) $GidData($TYPE,TYPE,$Idx)]
      
      if ![string length [set strError [lindex $cbInfo 0]]] {
	
	set cv [lindex $cbInfo 1]
	if { [llength $cbInfo] > 2 } {
	  # Se modifica el contenido del CB
	  set changeOptions 1
	  set loptions [lindex $cbInfo 2]
	  if [string length $cv] {
	    if { [set co [lsearch -exact $loptions $cv ]] == -1 } {
	      WindowMessage "In GidData($TYPE,QUESTION,$Idx): option $cv not found within set ($loptions). Using the first one"
	      set co 0
	      set GidData($TYPE,VALUE,$Idx) [lindex $loptions 0]
	    } else {
	      # Value valido
	      set GidData($TYPE,VALUE,$Idx) $cv
	    }
	  } else {
	    # Valor por omision de la lista
	    set cv [lindex $GidData($TYPE,OPTIONS,$Idx) $GidData($TYPE,CURSEL,$Idx)]
	    if { [set co [lsearch -exact $loptions $cv]] == -1 } {
	      # Asumo la primer option
	      set co 0
	      set GidData($TYPE,VALUE,$Idx) [lindex $loptions 0]
	    } else {
	      set GidData($TYPE,VALUE,$Idx) $cv
	    }
	  }
	} else {
	  # No se modifica el contenido de la lista
	  set loptions $GidData($TYPE,OPTIONS,$Idx)
	}
      }
    } else {
      set loptions [concat $GidData($TYPE,OPTIONS,$Idx) $GidData($TYPE,OPTIONS1,$Idx)]
      set cv $GidData($TYPE,VALUE,$Idx)
    }
    
    if $changeOptions {
      set GidData($TYPE,OPTIONS,$Idx) $loptions
    } elseif { [set co [lsearch -exact $loptions $GidData($TYPE,VALUE,$Idx)]] == -1 } {
      set strError "In GidData($TYPE,QUESTION,$Idx): option $cv not found within set ($loptions). Using previous value"
    }
    
    if { $co == -1 } {
      # No se pudo encontrar una option valida
      WindowMessage $strError
      DWRestoreCBValue $GDN $TYPE $Idx
    } else {
      set GidData($TYPE,CURSEL,$Idx) $co
    }
    set GidData($TYPE,SYNC,$Idx) 1
  }    
}

proc BuildStringValues { GDN } {
  global $GDN
  upvar \#0 $GDN GidData
  
  # Sincronizar
  
  set StructName [eval $GidData(TYPEFUNC) $GDN]

  DWInvokeTkWidget $GDN
  
  set StringValues ""

  set NumProp $GidData($StructName,numprop)
  
  for {set i 1} {$i <= $NumProp} {incr i 1} {
    append StringValues "[Field2String $GDN $StructName $i] "
  }
  
  return $StringValues
}

proc DWSendTKWIDGETEvent {GDN TYPE idx Ev args} {
  upvar \#0 $GDN GidData
    
  if {[catch "eval $GidData($TYPE,TKWIDGET,$idx) $Ev $GDN [list $TYPE] [list $GidData($TYPE,QUESTION,$idx)] $args" result]} {
    # follow up the error
    error "Error in tcl script sending event $Ev to $GidData($TYPE,TKWIDGET,$idx): $::errorInfo"
  } else {
    set len_res [llength $result]
    if { $len_res > 1 } {
      if { $len_res != 2 } {
	WindowMessage "Error '$result' in result from $Ev event: must be a 2-element list"
      } else {
	set status [string toupper [lindex $result 0]]
	set isERROR [string equal $status "ERROR"]
	if {$isERROR || ($status eq "WARNING") } {
	  set msg [lindex $result 1]
	  if [string length $msg] {
	    WindowMessage $msg
	  }
	  if $isERROR {
	    return CANCEL
	  }
	} else {
	  WindowMessage "invalid status '$status' in $Ev event: must be ERROR or WARNING"
	}
      }
    }
  }
  return OK
}

proc DWInvokeTkWidget { GDN } {
  upvar \#0 $GDN GidData
  
  set StructName [eval $GidData(TYPEFUNC) $GDN]
  
  set result ""
  if { $GidData($StructName,SYNC,TKWIDGET) } {
    foreach iproc [array names GidData $StructName,TKWIDGET*] {
      regexp (?:.)TKWIDGET,(.+) $iproc {} itk
      if { $itk } {
	set QUESTION $GidData($StructName,QUESTION,$itk)
      } else {
	set QUESTION 0
      }
      if [catch  "$GidData($iproc) SYNC $GDN [list $StructName] [list $QUESTION]" result] {
	# follow up the error
	error "Error in tcl script sending event SYNC to $GidData($iproc): $::errorInfo"
      } else {
	set len_res [llength $result]
	if { $len_res > 1 } {
	  if { $len_res != 2 } {
	    WindowMessage "Error '$result' in result from SYNC event: must be a 2-element list"
	  } else {
	    set status [string toupper [lindex $result 0]]
	    set isERROR [string equal $status ERROR]
	    if { $isERROR || [string equal $status WARNING] } {
	      set msg [lindex $result 1]
	      if [string length $msg] {
		WindowMessage $msg
	      }
	      if $isERROR {
		error CANCEL
	      }
	    } else {
	      WindowMessage "invalid status '$status' in SYNC event: must be ERROR or WARNING"
	    }
	  }
	}
      }
    }
  }
}

proc Field2String { GDN StructName i } {
    upvar \#0 $GDN GidData

    set value $GidData($StructName,VALUE,$i)
    
    set FieldType $GidData($StructName,TYPE,$i)

    switch $FieldType {
	GRID {
	    set NumCells $GidData($StructName,VALUE,$i,0)
	    set value "#N# $NumCells "
	    for {set j 1} {$j <= $NumCells} {incr j 1} {
		append value "[DWSpace2Under [string trim $GidData($StructName,VALUE,$i,$j)]] "
	    }
	    set value [string trim $value]
	}
	UNITS {
            if { [info exists GidData($StructName,INSTANCE,$i)] &&
                 $GidData($StructName,INSTANCE,$i) != ""} {
              if {[$GidData($StructName,INSTANCE,$i)\::ValidateReal]==-1} {
                error CANCEL
              }
              set value $GidData($StructName,VALUE,$i)
            }
            set value [string trim $value]
            if { [llength $value] > 1 } {
              set value "\"$value\""
            }
	}
	ENTRY {
	    set value [string trim $value]
	      if { [llength $value] > 1 } {
		  set value "\"$value\""
	      }
	    #set value [string trim $value]
	}
	default {
	    set value [DWSpace2Under [string trim $value]]
	}
    }
    return $value
}

proc _Field2String { GDN StructName i } {
    upvar \#0 $GDN GidData

    set value $GidData($StructName,VALUE,$i)
    
    set FieldType $GidData($StructName,TYPE,$i)
    
    if { $FieldType == "GRID" } {
	set NumCells $GidData($StructName,VALUE,$i,0)
	set value "#N# $NumCells "
	for {set j 1} {$j <= $NumCells} {incr j 1} {
	    append value "$GidData($StructName,VALUE,$i,$j) "
	}
    }
    set value [string trim $value]
    #regsub -all " " $value "\\ " value
    if { [llength $value] > 1 } {
	set value "\"$value\""
    }
    return $value
}



# Eventos disparados en la ventana de condiciones.

# ------------------------------------------------------------------------------
# DWPostEntitiesCnd --
# ------------------------------------------------------------------------------

proc DWPostEntitiesCnd { GDN m } {
  $m entryconfigure 0 -label [DWGetGUICondName $GDN]
}

# -------------------------------------------------------------------------- 
# DWPostDrawCond -- 
# --------------------------------------------------------------------------

proc DWPostDrawCond { GDN m } {
  upvar \#0 $GDN GidData
  
  if { !$GidData(menudraw,needpost) || 
       [$GidData(CND,combo) getvalue] == -1 } {
    return
  }
  set GidData(menudraw,needpost) 0
  set _CndName [DWGetGIDCondName $GDN]
  
  $m delete 0 end
  if {$GidData(BOOK) ne "Default"} {
    # draw book options
    if { $GidData(BOOK,HASLA) } {
      $m add cascade -label [_ "All %s" [DWDownFirstLetter $GidData(CND,plural)]] -menu $m.book
      if { ![winfo exists $m.book] } {
	menu $m.book -bd 1 -activeborderwidth 1
      } else {
	$m.book delete 0 end
      }
      $m.book add command -label [_ "Exclude local axes"] -command "DWDrawConds $GDN thisbook"
      $m.book add command -label [_ "Only local axes"] -command "DWDrawConds $GDN thisbookLA"
      $m.book add command -label [_ "Include local axes"] -command "DWDrawConds $GDN thisbookLAC"
    } else {
      $m add command -label [_ "All %s" [DWDownFirstLetter $GidData(CND,plural)]] -command "DWDrawConds $GDN thisbook"
    }
  }
  # thiscond options
  if $GidData(CND,$_CndName,HASLA) {
    $m add cascade -label [DWGetGUICondName $GDN] -menu $m.cond
    if { ![winfo exists $m.cond] } {
      menu $m.cond -bd 1 -activeborderwidth 1
    } else {
      $m.cond delete 0 end
    }
    $m.cond add command -label [_ "Exclude local axes"] -command "DWDrawConds $GDN thiscond"
    $m.cond add command -label [_ "Only local axes"] -command "DWDrawConds $GDN thiscondLA"
    $m.cond add command -label [_ "Include local axes"] -command "DWDrawConds $GDN thiscondLAC"
  } else {
    $m add command -label [DWGetGUICondName $GDN] \
	-command "DWDrawConds $GDN thiscond"
  }
  $m add command -label [_ "Colors"] -command "DWDrawConds $GDN colors"
  $m add cascade -label [_ "All conditions"] -menu $m.all
  if { ![winfo exists $m.all] } {
    menu $m.all -bd 1 -activeborderwidth 1
  } else {
    $m.all delete 0 end
  }
  $m.all add command -label [_ "Exclude local axes"] \
      -command "DWDrawConds $GDN allconds"
  $m.all add command -label [_ "Only local axes"] \
      -command "DWDrawConds $GDN allcondsLA"
  $m.all add command -label [_ "Include local axes"] \
      -command "DWDrawConds $GDN allcondsLAC"
  
  $m add cascade -label [_ "Field's value"] -menu $m.mfield
  $m add cascade -label [_ "Field's color"] -menu $m.mcolor
  if { ![winfo exists $m.mfield] } {
    menu $m.mfield -bd 1 -activeborderwidth 1
  } else {
    $m.mfield delete 0 end
  }
  if { ![winfo exists $m.mcolor] } {
    menu $m.mcolor -bd 1 -activeborderwidth 1
  } else {
    $m.mcolor delete 0 end
  }
  foreach i [array names GidData CND,$_CndName,QUESTION,*] {
    regexp {([^\#]+)(.*)} $GidData($i) {} _field
    set field [DWUnder2Space $_field]
    $m.mcolor add command -label [= $field] \
	-command "DWDrawConds $GDN colors $_field"
    $m.mfield add command -label [= $field] \
	-command "DWDrawConds $GDN thiscond $_field"
  }
}

# Metodo (evento) DWAssingCond
#        Asigna las condiciones a ?. Es invocado por el botón
#        Asign de la ventana de condiciones que se crea en
#        DWCondWindow.
# Argumentos:
#        w  --> ventana desde donde fue invocado.
# Resultado:
#        

proc DWAssignCond { GDN {l ""} } {
  global GidPriv
  global $GDN
  upvar \#0 $GDN GidData
  
  set w $GidData(WINDOW)
  
  set _CndName [DWGetGIDCondName $GDN]
  
  if [catch "BuildStringValues $GDN" Values] {
    if [string equal $Values CANCEL] {
      return
    } else {
      error $Values
    }
  }
  
  if [string length $l] {
    .central.s process escape escape escape escape data cond assign \
	$_CndName change $Values $l escape
  } else {
    .central.s process escape escape escape escape data cond assign \
	$_CndName change $Values
    set SmallWinSelecting [.central.s info variable SmallWinSelecting]
    FinishButton $w $w.but.assign [_ "Press 'Finish' to end selection"] \
	"DWAfterFinishButton $GDN" disableall $SmallWinSelecting
  }
}

# Metodo (evento)DWEntitiesCond
#        ?. Es invocado por el botón
#        Entities de la ventana de condiciones que se crea en
#        DWCondWindow.
# Argumentos:
#        w  --> ventana desde donde fue invocado.
# Resultado:
#        

proc DWEntitiesCond { GDN ThisOrAll } {
    #WarnWin "Option not developed"

    DWShowCondEntitiesWin $GDN $ThisOrAll
}

# DWUnassignSome --
#
# Argumentos:
#
# Resultados:

proc DWUnassignSome { GDN {l ""}} {
    global $GDN
    upvar \#0 $GDN GidData

    set w $GidData(WINDOW)
    
    if [string length $l] {
	.central.s process escape escape escape escape data cond assign \
	    [DWGetGIDCondName $GDN] unassign $l escape
    } else {
	.central.s process escape escape escape escape data cond assign \
	    [DWGetGIDCondName $GDN] unassign

	set SmallWinSelecting [.central.s info variable SmallWinSelecting]
	FinishButton $w $w.but.assign [_ "Press 'Finish' to end selection"] \
	    "DWAfterFinishButton $GDN" disableall $SmallWinSelecting
    }
}

# DWUnassignAllThis --
#
# Argumentos:
#
# Resultados:

proc DWUnassignAllThis { GDN } {
    global $GDN
    upvar \#0 $GDN GidData

    set w $GidData(WINDOW)
    set singular [DWDownFirstLetter $GidData(CND,singular)]
    set aa [tk_dialogRAM $w.tempwinpr [_ "Unassign conditions"] \
		[_ "Sure, unassign all current %s's entities for this interval?" $singular]\
		gidquestionhead 1 [_ "Yes"] [_ "Cancel"]]

    if { $aa == 1 } { return }
    
    .central.s process escape escape escape escape data cond \
	    assign [DWGetGIDCondName $GDN] delete yes escape 
}

# DWUnassignAllCND --
#
# Argumentos:
#
# Resultados:

proc DWUnassignAllCND { GDN } {
    upvar \#0 $GDN GidData

    set w $GidData(WINDOW)

    set aa [tk_dialogRAM $w.tempwinpr [_ "Unassign conditions"] \
		[_ "Sure, unassign all conditions' entities?"] \
		gidquestionhead 1 [_ "Yes"] [_ "Cancel"]]
    
    if { $aa == 1 } { return }
    
    .central.s process escape escape escape escape data cond \
	unassign yes escape 
}

# DWUnassignAllBookCND --
#
# Argumentos:
#
# Resultados:

proc DWUnassignAllBookCND { GDN } {
    upvar \#0 $GDN GidData

    set w $GidData(WINDOW)
    set plural [DWDownFirstLetter $GidData(CND,plural)]
    set Plural [DWUpFirstLetter $GidData(CND,plural)]
    set aa [tk_dialogRAM $w.tempwinpr [_ "Unassign %s" $Plural] \
		[_ "Sure, unassign all %s' entities?" $plural] \
		gidquestionhead 1 [_ "Yes"] [_ "Cancel"]]
    
    if { $aa == 1 } { return }
    

    foreach idx [array names GidData CND,*,GIDNAMES] {
	foreach cnd $GidData($idx) {
	    .central.s process escape escape escape escape data cond \
		assign $cnd delete yes escape 
	}
    }
}


# Eventos disparados en la ventana de intervalos.

# Evento DWNewInterval --
#    Es invocado por el botón NEW del diálogo de los intervalos. Agrega
#    un nuevo intervalo. Refresca el combo de los intervalos.
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    Adicioan un nuevo intervalo y actualiza el combo de los intervalos.

proc DWNewInterval { GDN } {
  global $GDN
  upvar \#0 $GDN GidData
  
  
  set aa [tk_dialogRAM $GidData(WINDOW).asktmp [_ "Confirm"] \
	      [_ "Copy conditions' entities from interval %s?" $GidData(ID,current)] \
	      gidquestionhead 0 [_ "Yes"] [_ "No"] [_ "Cancel"]]
  
  switch $aa {
    0 {
      set opt yes
    }
    1 {
      set opt no
    }
    default {
      return
    }
  }
  # Adiciono un nuevo interval, esto cambia el intervalo activo.
  
  .central.s process escape escape escape escape Data Intervals \
      NewInterval Yes $opt
  
  # Restauro el intervalo activo.
  
  DWSetActiveInterval $GidData(ID,current)
}

proc DWOnAddNewInterval { GDN } {
  upvar \#0 $GDN GidData
  
  set cb $GidData(ID,combo)
  set values [$cb cget -values]
  set new_max [expr [lindex $values end]+1]
  lappend values $new_max
  $cb configure -values $values
  # quizas un after idle para cambiar el copntenido al intervalo activo!
}

proc DWOnDeleteInterval { GDN I } {
  upvar \#0 $GDN GidData

  set cb $GidData(ID,combo)
  $cb configure -values [lrange [$cb cget -values] 0 end-1]
  set sel [expr $I-2]
  $cb setvalue @$sel
  if { $GidData(ID,current) == $I } {
    # DW contents should change
    DWOnSelectInterval $GDN $sel
  }
}

# Evento DWIntervalAccept --
#    Es invocado por el botón Accept del diálogo de los intervalos. Acepta
#    los cambios realizado al intervalo actual.
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    Le informa GID de los cambios en los values del intervalo actual.

proc DWIntervalAccept { GDN } {
  global $GDN TmpGidData
  upvar \#0 $GDN GidData
  
  # Hay que guardar el intervalo activo.
  
  set ISaved [DWGetActiveInterval]
  
  # Activar el GidData(ID,currentinterval)
  # ya que GenericFillGD trabaja con el intervalo activo
  
  DWSetActiveInterval $GidData(ID,current)

  set result ""
  if { [catch "DWInvokeTkWidget $GDN" result] } {
    DWSetActiveInterval $ISaved
    if [string equal $result CANCEL] {
      return
    } else {
      error $result
    }
  }

  # validate the units values
  
  if { [catch "DWValidateUnitFields $GDN" result] } {
    DWSetActiveInterval $ISaved
    if [string equal $result CANCEL] {
      return
    } else {
      error $result
    }
  }

  GenericFillGDFull $GDN ID TmpGidData
  
  # este no lanza InvokeTkWidget, garantizado por GenericFillGDFull
  set Values [BuildStringValues TmpGidData]

  .central.s process escape escape escape escape data intervaldata $Values
  
  set GidData(ID,SYNC,TKWIDGET) 0
  set GidData(FIRSTSTATE) [BuildStringValues $GDN]
  set GidData(ID,SYNC,TKWIDGET) 1
  
  FloatMessage $GidData(ID,mainframe).mess [_ "%s modified" [DWUpFirstLetter $GidData(ID,plural)]]
  
  DWSetActiveInterval $ISaved

  unset TmpGidData
}

proc DWGetActiveInterval { } {
  lindex [.central.s info intvdata num] 0
}

proc DWSetActiveInterval { I } {
  .central.s process escape escape escape escape Data Intervals \
      ChangeInterval $I
}

# Eventos disparados en la ventana de materiales

# ------------------------------------------------------------------------------
# DWPostDrawMaterial --
# ------------------------------------------------------------------------------

proc DWPostDrawMaterial {GDN m} {
  $m entryconfigure 0 -label [DWGetGUIMaterial $GDN]
}

# PostCmdAssignMat --
#
# Argumentos:
#
# Resultados:

proc PostCmdAssignMat { GDN w Menu } {
  upvar \#0 $GDN GidData

  set geomlistNames [list [_ "Points"] [_ "Lines"] [_ "Surfaces"] [_ "Volumes"]] 
  set geomlist "Points Lines Surfaces Volumes"
  set meshlistNames [list [_ "Elements"]]
  set meshlist "Elements"
  
  $Menu del 0 end
  if { [catch { set whatuse [lindex [.central.s info Project] 4] }] } {
    set whatuse "GEOMETRYUSE"
  }
  if {$whatuse eq "GEOMETRYUSE"} {
    set etype "geomlist"
    set elist [list Points Lines Surfaces Volumes]
    set elist_names [list [_ "Points"] [_ "Lines"] [_ "Surfaces"] [_ "Volumes"]]
  } else {
    set etype "meshlist"
    set elist [list Elements]
    set elist_names [list [_ "Elements"]]
  }
  set b_ent [lindex [::DataBehaviour::Materials 1 $GidData(BOOK) $etype] 1]
  set m_ent [lindex [::DataBehaviour::Materials 0 [DWGetGIDMaterial $GDN] $etype] 1]
  foreach i $elist j $elist_names {
    set e_t [string tolower $i]
    if {($m_ent eq "default" && ($b_ent eq "default" ||
                                 [lsearch $b_ent $e_t]!=-1)) ||
        ([lsearch $m_ent $e_t] != -1)} {
      $Menu add command -label $j -command "DWAssignMaterials $GDN $w $i"
    }
  }
}

# DWAssignMat --
#
# Argumentos:
#
# Resultados:

proc DWAssignMaterials  { GDN w type } {
  global $GDN
  
  upvar \#0 $GDN GidData
  
#   set MatName $GidData(MAT,matname)
#   set _MatName [DWSpace2Under $MatName]

  set _MatName [DWGetGIDMaterial $GDN]
  
  if [catch "CheckDirtyState $GDN" result] {
    if [string equal $result CANCEL] {
      return
    } else {
      error $result
    }
  }
  
  if { $_MatName == ""} {
    WarnWin [_ "Sorry, but first a %s must be selected" [DWDownFirstLetter $GidData(MAT,singular)]] $w
    return
  }
  
  if { $type != "Elements" } {
    .central.s process escape escape escape escape data mat assign \
	$_MatName $type
  } else {
    .central.s process escape escape escape escape data mat assign \
	$_MatName
  }
  set SmallWinSelecting [.central.s info variable SmallWinSelecting]
  FinishButton $w $w.but.assign [_ "Press 'Finish' to end selection"] \
      "DWAfterFinishButton $GDN" disableall $SmallWinSelecting
}

# DWDrawMaterials --
#
# Argumentos:
#
# Resultados

proc DWDrawMaterials { GDN w what } {
  global $GDN
  upvar \#0 $GDN GidData
  
  switch $what {
    onemat {
      .central.s process escape escape escape escape data material draw \
	  [DWGetGIDMaterial $GDN]
    }
    allmats {
      .central.s process escape escape escape escape data material draw \
	  -drawall-
    }
  }
  set SmallWinSelecting [.central.s info variable SmallWinSelecting]
  FinishButton $w $w.but.assign [_ "Press 'Finish' to end selection"] \
      "DWAfterFinishButton $GDN" disableall $SmallWinSelecting
}

# Evento DWUnassignMat --
#    Es invocado por el botón Unassign del diálogo de los materiales. Hace ? 
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    ?

proc DWUnassignMat {w GDN} {
  upvar \#0 $GDN GidData
  
#   set MatName $GidData(MAT,matname)
#   set _MatName [DWSpace2Under $MatName]

  set MatName [DWGetGUIMaterial $GDN]
  set _MatName [DWGetGIDMaterial $GDN]
  set Book $GidData(BOOK)
  
  #WarnWin "Book=$Book GidData(MAT,singular)=[DWDownFirstLetter $GidData(MAT,singular)]" 
  
  set m $w.but.unassign.menu
  $m del 0 end
  set sm $m.ent
  $m add cascade -label [_ "Entities"] -menu $sm
  if {![winfo exist $sm]} {
    menu $sm -bd 1 -activeborderwidth 1 \
	-postcommand "PostCmdUnassignSomeMat $w $GDN $sm"
  }
  set singular [DWDownFirstLetter $GidData(MAT,singular)]
  $m add command -label $MatName -command "DWUnassignAllThisMat $w $GDN"
  if { $Book != "Default" } {
    $m add command -label [_ "All book %s" [= [DWUnder2Space $Book]]] \
	-command "DWUnassignAllBookMat $w $GDN"
  }
  $m add command -label [_ "All %s" $GidData(MAT,plural)]  \
      -command "DWUnassignAllMat $w $GDN"
}

proc PostCmdUnassignSomeMat { w GDN Menu } {
  set geomlistNames [list [_ "Points"] [_ "Lines"] [_ "Surfaces"] [_ "Volumes"]] 
  set geomlist "Points Lines Surfaces Volumes"
  set meshlistNames [list [_ "Elements"]]
  set meshlist "{}"
  
  $Menu del 0 end
  if { [catch { set whatuse [lindex [.central.s info Project] 4] }] } {
    set whatuse GEOMETRYUSE
  }
  switch $whatuse {
    GEOMETRYUSE {
      foreach i $geomlist j $geomlistNames {
	$Menu add command -label $j -command [list DWUnassignSomeMat $w $GDN $i]
      }
    }
    MESHUSE {         
      foreach i $meshlist j $meshlistNames {
	$Menu add command -label $j -command [list DWUnassignSomeMat $w $GDN $i]
      }
    }
  }
}

proc DWUnassignSomeMat { w GDN type} {
  .central.s process escape escape escape escape Data Materials UnAssign Entities $type
  set SmallWinSelecting [.central.s info variable SmallWinSelecting]
  FinishButton $w $w.but.assign [_ "Press 'Finish' to end selection"] \
      "DWAfterFinishButton $GDN" disableall $SmallWinSelecting
}

proc DWUnassignAllThisMat { w GDN } {
  upvar \#0 $GDN GidData
  
#   set MatName $GidData(MAT,matname)
#   set _MatName [DWSpace2Under $MatName]

  set _MatName [DWGetGIDMaterial $GDN]
  set MatName [DWGetGUIMaterial $GDN]
  if { $MatName == ""} {
    WarnWin [_ "Sorry, but first a material must be selected"] $w
    return
  }
  
  set aa [tk_dialogRAMFull $w.tempwin [_ "Unassign materials"] \
	      [_ "Sure, you want to unassign all material %s?" $MatName] \
	      "" "" gidquestionhead 0 [_ "OK"] [_ "Cancel"]]
  if { $aa == "0" } {
    .central.s process escape escape escape escape Data Materials UnAssign SomeMat $_MatName
  }
}

proc DWUnassignAllBookMat { w GDN } {
  upvar \#0 $GDN GidData
  
#   set MatName $GidData(MAT,matname)
#   set _MatName [DWSpace2Under $MatName]

  set MatName [DWGetGUIMaterial $GDN]
  set Book $GidData(BOOK)
  
  if { $Book == "Default"} {
    WarnWin [_ "Sorry, but first a material book must be selected"] $w
    return
  }

  set aa [tk_dialogRAMFull $w.tempwin [_ "Unassign %s" $GidData(MAT,singular)] \
	      [_ "Sure, you want to unassign all book %s?" [= $Book]] \
	      "" "" gidquestionhead 0 [_ "OK"] [_ "Cancel"]]
  if { $aa == "0" } {
    .central.s process escape escape escape escape Data Materials UnAssign SomeBook $Book
  }
}

proc DWUnassignAllMat { w GDN } {
  .central.s process escape escape escape escape Data Materials UnAssign AllMat
}



# Evento DWImportExport --
#
# Argumentos:
#
# Resultados:
#

proc DWMatImportExport { w Book } {
    global DefaultSearchDirectoryP
    #set initialdir [GetDirectoryProblemType]
    set initialdir $DefaultSearchDirectoryP
    set filename [::tk::dialog::file:: open \
		      -title [_ "Load Database"] \
		      -initialdir $initialdir \
		      -parent $w \
		      -filetypes [_ "{{Materials} {.mat}}"]] 
    if { [string compare $filename ""] != 0 } {
	set DefaultSearchDirectoryP [file dirname $filename]
	saveMaterialsWindow $filename $Book
    }
}

# Evento DWModifyMat --
#    Es invocado por el botón Modify del diálogo de los materiales. Debe
#    pasar los valores editados al GID.
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    Envía los valores de los campos a GID utilizando el pipeline de process.
#    Los valores de los campos se obtienen de BuildStringValues

proc DWModifyMat { GDN } {
  global $GDN DataWindowsRunningAlone
  upvar \#0 $GDN GidData
  
#   set MatName $GidData(MAT,prevmatname)
#   set _MatName [DWSpace2Under $MatName]
  set _MatName [DWGetGIDMaterial $GDN]
  if [catch "BuildStringValues $GDN" Values] {
    if [string equal $Values CANCEL] {
      return
    } else {
      error $Values
    }
  }

  .central.s process escape escape escape escape data materials newmaterial $_MatName $_MatName yes $Values

  FloatMessage $GidData(WINDOW)\.level.mess [_ "%s %s modified" \
		                                 [DWUpFirstLetter $GidData(MAT,singular)] \
		                                 [DWGetGUIMaterial $GDN]]
  set GidData(FIRSTSTATE) $Values
}


# Evento DWNewMat --
#    Es invocado por el botón New del diálogo de los materiales. Debe
#    crear un nuevo material a partir de uno existente.
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    ?


# Revisa el codigo este

proc DWNewMat { GDN w } {
  global $GDN
  upvar \#0 $GDN GidData
  
  set materialstr [DWDownFirstLetter $GidData(MAT,singular)]
  set Materialstr [DWUpFirstLetter $GidData(MAT,singular)]
  set _NewMatName [tk_dialogEntryRAM $w.newmat [_ "New %s" $materialstr] \
		       [_ "Enter new %s name" $materialstr] gidquestionhead "any" "" ]
  if { "$_NewMatName" != "--CANCEL--" } {
    
    #elimino las posibles "'s, żNO SE POR QUE LE ADICIONA LAS "'s ANTES DE RETORNAR?
    # si ha introducido espacios los cambio por _
    set _NewMatName [DWSpace2Under [string trim $_NewMatName {" }]] ; #"
    set NewMatName [= [DWUnder2Space $_NewMatName]]
    
    # Verificar que el material no exista
    
    if { ![catch [list .central.s info materials $_NewMatName]] } {
      WarnWin [_ "Invalid new %1\$s name: %2\$s already exists in data base.\nTo override it use Modify" \
		   $materialstr $NewMatName] 
    } else {
      # set _BaseMatName [DWSpace2Under $GidData(MAT,matname)]
      set _BaseMatName [DWGetGIDMaterial $GDN]
      if { [AddNewMaterial $GDN $_NewMatName $_BaseMatName] } {
        # inherit the data behaviour
        set base_props [DataBehaviour::GetMaterialsOpts]
        lappend base_props geomlist meshlist
        set behaviour {}
        foreach {p v} [GiD_DataBehaviour material $_BaseMatName $base_props] {
          if {$v ne "default"} {
            lappend behaviour $p $v
          }
        }
        foreach {p v} $behaviour {
          if {$p eq "meshlist" || $p eq "geomlist"} {
            GiD_DataBehaviour material $_NewMatName $p $v
          } else {
            GiD_DataBehaviour material $_NewMatName $v $p
          }
        }
	CopyMatGidData $GDN $_NewMatName $_BaseMatName
#       $w.level.combo add $NewMatName
#       set GidData(MAT,matname) $NewMatName
	$GidData(MAT,combo) configure -values [concat [$GidData(MAT,combo) cget -values] [list $NewMatName]]
	$GidData(MAT,combo) setvalue last
	DWOnSelectMaterial $GDN
	FloatMessage $w.level.mess [= "%s %s added" $Materialstr $NewMatName]
      }
    }
  }
}

proc DWDeleteMat { GDN } {
  global DataMenuInfo
  upvar \#0 $GDN GidData
  
  
#   set matname $GidData(MAT,matname)
  set matname [DWGetGUIMaterial $GDN]
  set strmes [_ "Are you sure to delete %1\$s %2\$s?" [DWDownFirstLetter $GidData(MAT,singular)] $matname]
  set Ret [tk_dialogRAMFull .gid.askyn [_ "Confirm: %s" [DWUpFirstLetter $GidData(MAT,plural)]] \
	       $strmes "" "" gidquestionhead 0 [_ "Yes"] [_ "No"]]
  if { $Ret == 0 } {
    set _matname [DWGetGIDMaterial $GDN]
    .central.s process escape escape escape escape data material deletematerial $_matname
    set idxdata [array names GidData MAT,$_matname,*]
    
    foreach i $idxdata {
      unset GidData($i)
    }
    set combo $GidData(MAT,combo)
#     set e [$combo get]
#     set l [$combo listbox get 0 end]
    
#     set idx [lsearch $l $e]
    set idx [$combo getvalue]
    
    $combo configure -values [lreplace [$combo cget -values] $idx $idx]
    set GidData(MAT,materials) [lreplace $GidData(MAT,materials) $idx $idx]
    if {[$combo setvalue @$idx] || [$combo setvalue last]} {
      set GidData(MAT,cursel) -1
      DWOnSelectMaterial $GDN
    } else {
      destroy $GidData(WINDOW)
      if { $GidData(BOOK) == "Default" } {
	set i $DataMenuInfo(Materials,entry)
	$DataMenuInfo(menu) entryconfigure $i -state disabled
      } else {
	set i [lsearch $DataMenuInfo(Materials) $GidData(BOOK)]
	$DataMenuInfo(Materials,submenu) entryconfigure $i -state disabled
      }
      unset GidData
    }
  }
}

proc DWProcess { values } {
  foreach v $values {
    if { [llength $v] > 1 && [string compare [lindex $v 0] "\#N\#"] } {
      set strv \"$v\"
    } else {
      set strv $v
    }
    .central.s process $strv
  }
}

# Eventos disparados en la ventana de problemas

# Evento DWProblemAccept --
#    Es invocado por el botón Accept del diálogo de los datos del problema. Hace ? 
#
# Argumentos:
#    w --> ventana desde donde se invocó.
#
# Resultados:
#    ?

proc DWProblemAccept { GDN } {
  global TmpGidData
  upvar \#0 $GDN GidData
  
  set result ""
  if [catch "DWInvokeTkWidget $GDN" result] {
    if [string equal $result CANCEL] {
      return
    } else {
      error $result
    }
  }
  
  # validate units

  if [catch "DWValidateUnitFields $GDN" result] {
    if [string equal $result CANCEL] {
      return
    } else {
      error $result
    }
  }

  GenericFillGDFull $GDN PD TmpGidData
  
  # no lanza InvokeTkWidget, garantizado por GenericFill...
  set Values [BuildStringValues TmpGidData]
  
  .central.s process escape escape escape escape data problemdata $Values
  
  FloatMessage $GidData(PD,mainframe).mess "[DWUpFirstLetter $GidData(PD,plural)] modified"
  set GidData(PD,SYNC,TKWIDGET) 0
  set GidData(FIRSTSTATE) [BuildStringValues $GDN]
  set GidData(PD,SYNC,TKWIDGET) 1
  
  unset TmpGidData
}

proc DWValidateUnitFields { GDN } {
  upvar \#0 $GDN GidData

  set TYPE [eval $GidData(TYPEFUNC) $GDN]
  foreach idx [array names GidData $TYPE,INSTANCE,*] {
    # ValidateReal modifies VALUENUM and this the VALUE
    if {[$GidData($idx)\::ValidateReal]==-1} {
      error CANCEL
    }
  }
}

# -- Procedimientos auxiliares --

# AddNewMaterial --
#
#        Adiciona un nuevo material basado en uno existente.
#
# Argumentos:
#
#        NewMatName --> nombre del nuevo material.
#        BaseMatName --> nombre del material base.
#
# Resultados:
#
#        Agrega dentro de GID un nuevo material. El nombre del
#        nuevo material debe ser distinto del material base. Si
#        la operación fué exitosa retorna 1, en caso contrario
#        retorna 0.

proc AddNewMaterial { GDN NewMatName BaseMatName } {
  if { $NewMatName != "" } {
    if [catch "BuildStringValues $GDN" Values] {
      if [string equal $Values CANCEL] {
	return 0
      } else {
	error $Values
      }
    }
    
    .central.s process escape escape escape escape data materials \
	newmaterial $BaseMatName $NewMatName $Values
    return 1
  }
  return 0
}

# CopyMatGidData --
#
#        Crea la estrucra GidData para un nuevo material y copia los
#        valores a partir de un material existente.
#
# Argumentos:
#
#        NewMatName --> nombre del nuevo material.
#        BaseMatName --> nombre del material base.
#
# Resultados:
#
#        GidData contiene la información referente al nuevo material.
#        GidData(MAT,$NewMatName,*)
#        GidData(MAT,nameslist) += $NewMatName

proc CopyMatGidData { GDN NewMatName BaseMatName } {
  global $GDN
  upvar \#0 $GDN GidData
  
#   lappend GidData(MAT,nameslist) [DWUnder2Space $NewMatName]
  lappend GidData(MAT,materials) $NewMatName
  #WarnWin [array names GidData "MAT,$BaseMatName,*"]
  set lidx [array names GidData "MAT,$BaseMatName,*"]
  regsub -all {\(} $BaseMatName {\\(} BaseMatName
  regsub -all {\)} $BaseMatName {\\)} BaseMatName
  foreach i $lidx {
    regsub $BaseMatName $i $NewMatName j
    #WarnWin "$i --> $j"
    set GidData($j) $GidData($i)
    #regexp "(MAT,$BaseMatName,)(.*)" $i {} {} Idx
    #set GidData(MAT,$NewMatName,$Idx) $GidData($i)
  }
  #GenScriptDependencies $GDN MAT,$NewMatName
  DWBindTrace $GDN MAT,$NewMatName
}

# globalarray --
#
# Argumentos:
#
# Resultados:
#

proc globalarray { name } {
    global $name

    upvar \#0 $name GD

    catch {unset GD}

    set GD(0) 1
    unset GD(0)
    
    return $name
}

proc DWGetWindowName { head bord } {
    set w $head$bord
    while { [winfo exists $w] } {
	set w $w$bord
    }
    return $w
}

proc ExistsDataWindow { GDclass BookOrd } {
    set GDN GD_$GDclass\_$BookOrd

    if { [info globals $GDN] != {} } {
	upvar \#0 $GDN GidData

      if { [info exists GidData(WINDOW)] } {
	      set w $GidData(WINDOW)
	    if { [winfo exists $w] } {
		return $w
	    } 
      }
    }
    return ""
}

proc DWDestroyChildren { w } {
    foreach i [winfo children $w] {
    }
}

proc ReplaceDW { GDN NewDWCmd {Book Default} {BookOrd 1} } {
    upvar \#0 $GDN GidData

    if [catch "DWCheckClose $GDN" result] {
	if [string equal $result CANCEL] {
	    return
	}
	WindowMessage "ReplaceDW: '$result'"
	set w $GidData(WINDOW)
	
	set geom [winfo geom $w]
	foreach i [winfo children $w] {
	    destroy $i
	}
	
	unset GidData
	set retval [eval $NewDWCmd [list $Book] $BookOrd $w]
	wm geom $w $geom
	return $retval
    }
    
    set w $GidData(WINDOW)

    set geom [winfo geom $w]
    foreach i [winfo children $w] {
	destroy $i
    }
    
    unset GidData
    set retval [eval $NewDWCmd [list $Book] $BookOrd $w]
    wm geom $w $geom
    return $retval
}


proc FillJumpMenu { GDN } {
  global gidDataLabels
  global gidDataBooksHidden
  
  upvar \#0 $GDN GidData
  
  
  set DataEntry [list [list [_ "Conditions"] "Conditions" conditions CheckCnd DWCondWindow CND] \
		     [list [_ "Materials"] "Materials"  materials CheckMat DWMatWindow MAT] \
		     [list [_ "Interval Data"] "Interval Data" intvdata CheckIntv DWIntervalDataWindow INT] \
		     [list [_ "Problem Data"] "Problem Data" gendata CheckPrbD DWProblemDataWindow PD]]
  
  set jb      $GidData(JUMPBUTTON)
  set Class   $GidData(CLASS)
  set Book    $GidData(BOOK)
  set BookOrd $GidData(BOOKORD)
  
  set m [$jb cget -menu]
  
  $m delete 0 last
  
  set UnderChars {}
  
  foreach i $DataEntry {
    set theClass  [lindex $i 1]
    
    # if ![info exists gidDataLabels($theClass)] continue
    
    set isDeleted [expr ![info exists gidDataLabels($theClass)]]
    
    if { $isDeleted || $gidDataLabels($theClass) == "" } {
      set ClassLabel [lindex $i 0]
    } else {
      set ClassLabel $gidDataLabels($theClass)
    }
    set AskBook   [lindex $i 2]
    set CheckFunc [lindex $i 3]
    set DWCmd     [lindex $i 4]
    set GD        [lindex $i 5]
    
    if { [eval $CheckFunc] != "" } {
      set BookList [.central.s info $AskBook BOOKS]
      
      if { [llength $BookList] == 0 } {
	if { $isDeleted } continue
	if { $Class == $theClass || [ExistsDataWindow $GD 1] != "" } {
	  set bAddSeparator 0
	} else {
	  $m add command -label [= [DWUnder2Space $ClassLabel]] -command "ReplaceDW $GDN $DWCmd" \
	      -underline 0
	  lappend UnderChars [string index $theClass 0]
	  set bAddSeparator 1
	}
      } else {
	set bAddSeparator 0
	set isbook 1
	set bord   1
	
	foreach b $BookList {
	  if { $isbook } {
	    if { [lsearch $gidDataBooksHidden($AskBook) $b] == -1 } {
	      if { $b != $Book && [ExistsDataWindow $GD $bord] == ""} {
		set Label [= [DWUnder2Space $b]]
		set icFound 0
		for {set UnderIdx 0 } { $UnderIdx < [string length $Label]} { incr UnderIdx } {
		  set letter [string tolower [string index $Label $UnderIdx]]
		  if { ![regexp {[0-9a-z]} $letter] } { continue }
		  if { [lsearch $UnderChars $letter] == -1 } {
		    lappend UnderChars $letter
		    set icFound 1
		    break
		  }
		}
		if !$icFound {
		  set UnderIdx -1
		}
		$m add command -label $Label -command "ReplaceDW $GDN $DWCmd [list $b] $bord" \
		    -underline $UnderIdx
		set bAddSeparator 1
	      }
	    }
	    set isbook 0
	    incr bord
	  } else {
	    set isbook 1
	  }
	}
      }
      if { $bAddSeparator } {
	$m add separator
      }
    }
  }
  $m delete last
}


proc AddHelpTagFirst { w } {
    set cur ""
    catch { set cur [$w cget -cursor] }
    if { $cur == "question_arrow" } { set cur "" }
    set tags [list Help $cur]
    bindtags $w [concat $tags [bindtags $w]]
    catch { $w conf -cursor question_arrow }
    foreach i [winfo children $w] {
	AddHelpTagFirst $i
    }
}

proc RemoveHelpTag { w } {
    if { [lindex [bindtags $w] 0] == "Help" } {
	catch { $w conf -cursor [lindex [bindtags $w] 1] }
	bindtags $w [lrange [bindtags $w] 2 end]
    }
    foreach i [winfo children $w] {
	RemoveHelpTag $i
    }
}

proc EndPickHelp { w wh x y } {

    RemoveHelpTag $w
    set pos [lsearch [bind $wh <ButtonPress-3>] DisplayGidHelpMenu]
    if { $pos != -1 } {
	incr pos 2
	set text [lindex [bind $wh <ButtonPress-3>] $pos]
    } else {
	set text "There is no help for this item"
    }
    DisplayGidHelp $wh $text menu $x $y
}

proc PickHelp { w } {

    set w [winfo toplevel $w]
    AddHelpTagFirst $w
    bind Help <ButtonPress-1> "EndPickHelp $w %W %X %Y; break"
    bind Help <ButtonRelease-1> "break"
}

proc CreateJumpButton { GDN w col {dir left}} {
  global GIDDEFAULT GidPriv
  
  upvar \#0 $GDN GidData
  
  set hp $w.hp
  set jb $w.jb
  
  set m  $jb.m
  
  if { ![info exist GidPriv(OPENGIF)] } {
    set GidPriv(OPENGIF) [image create photo -file $GIDDEFAULT/bitmaps/note.gif]
  }
  
  button $hp -image [imagefrom questionarrow.gif] \
      -relief flat -bd 1 -highlightthickness 0 \
      -takefocus 0 -command "PickHelp $hp"
  ChangeToNewLook $hp
  menubutton $jb -image $GidPriv(OPENGIF) -highlightthickness 0 \
      -menu $m -und 0 -direction $dir -bd 1 -relief flat
  menu $m -postcommand "FillJumpMenu $GDN" -bd 1 -activeborderwidth 1
  ChangeToNewLook $jb
  grid $hp -row 0 -column $col -sticky "snew"
  incr col
  grid $jb -row 0 -column $col -sticky "snew"
  
  set GidData(JUMPBUTTON) $jb
  set GidData(HELPBUTTON) $hp
  
  GidHelp $jb [_ "Open other data option using this window"]
  
  list $hp $jb
}

proc DWDataUnits { } {
    if { [.central.s info unitssystems] && [ModUnitWin::Init .gid.dataunits] } {
	ModUnitWin::Show
    } else {
	WarnWin [_ "There are not units defined"]
    }
}

proc test { } {
    #global GidData

    option add *font [font create -family Helvetica -size 12]

#    DWCondWindow /home/jsperez/GID/bin/problemtypes/omega3.gid/omega3.cnd
#    DWCondWindow
#     DWMatWindow /home/jsperez/GID/bin/problemtypes/omega3.gid/omega3.mat
    DWMatWindow
#    DWCondWindow /home/ramsan/bin/tester.gid/tester.cnd
#      DWProblemDataWindow /home/jsperez/GID/bin/problemtypes/omega3.gid/omega3.prb
#      DWProblemDataWindow
#      DWIntervalDataWindow /home/jsperez/GID/bin/problemtypes/omega3.gid/omega3.prb
#      DWIntervalDataWindow

#    DWCondWindow /home/ramsan/bin/problemtypes/old/omega3.gid/omega3.cnd
#      DWCondWindow /home/ramsan/bin/tester.gid/tester.cnd
#      DWProblemDataWindow /home/ramsan/bin/omega3.gid/omega3.prb
}

#----------------------DataWindows ALONE---------------------------
if { $DataWindowsRunningAlone == 1 } {
    #test
} 
#-----------------------------------------------------------------

# ------------- UTILES ------------


proc FloatMessage { w mes } {
    if [winfo exist $w] {
	return
    }
    label $w -text $mes -relief ridge
    place $w -x 0 -rely 1 -in [winfo parent $w] -anchor sw
    tkwait visibility $w
    FlashLabel 0 0 $w
}

proc FlashLabel { num black w } {
    if ![winfo exists $w] {
	return
    }
    incr num
    if $black {
	$w conf -fg black
	set black 0
    } else {
	$w conf -fg white
	set black 1
    }
    if { $num < 10 } {
	after 200 FlashLabel $num $black $w
    } else {
	destroy $w
    }
}


# ----------------- User functions -----------------

# Procedure GidAddUserDataOptions --
#
#    Add a new entry to the data menu of GiD.
#
# Arguments:
#    L   --> Label of the option. In order to add a separadtr entry
#            it must be passed the value "---"
#    A   --> script to execute when the option is selected
#    W   --> Position of the option:
#                an integer or end to indicate the last position in the menu.
#                end is the default value if you omite this argument.
#    Acc --> Acceleration key combination.
#
#
# Results:
#

proc GidAddUserDataOptions { L {A ""} {W end} {Acc ""} } {
    global gidUserDataOptions

    if { $L == "---" } {
	lappend gidUserDataOptions $W
    } else {
	if ![regexp {^(end|[0-9]+)$} $W] {
	    WindowMessage "Error: Argument position in GidAddUserDataOptions should be an integer or end."
	    return
	}
	lappend gidUserDataOptions [list $L $A $W $Acc]
    }

    # fuerzo redibujar el menu de datos.

    set GidPriv(POSTDATA) 1
}

# Creates a submenu
# action will be converted into a postcommand, substituting %W for the menu name

proc GidAddUserDataOptionsMenu { L {A ""} {W end} } {
    global gidUserDataOptions

    if ![regexp {^(end|[0-9]+)$} $W] {
	WindowMessage "Error: Argument position in GidAddUserDataOptionsMenu should be an integer or end."
	return
    }
    lappend gidUserDataOptions [list $L $A $W "" menu]

    # fuerzo redibujar el menu de datos.

    set GidPriv(POSTDATA) 1
}

# Procedimiento GidChangeDataLabel --
#
#    Modifica el texto de las opciones de datos de GiD:
#        - Conditions, Materials, Problem Data, Interval Data,...
#
# Argumentos:
#    GidLabel --> Texto clave en ingles (no traducirlo) que puede ser una de las opciones:
#        "Problem type" "Data units" "Interval" "Local axes" "Conditions" "Materials"
#         "Interval Data" "Problem Data"

#    NewLabel --> Nuevo texto de la opción, se asume que ya viene traducido
#                 desde el problemtype
#
# Resultados:
#

proc GidChangeDataLabel { GidLabel NewLabel {Singular ""} } {
  global gidDataLabels
  
  if { $NewLabel == "" } {
    catch { 
      unset gidDataLabels($GidLabel) 
    }
  } else {
    set gidDataLabels($GidLabel) $NewLabel
    if { $Singular == "" } {
      set gidDataLabels($GidLabel,singular) [DWMakeSingular $NewLabel]
    } else {
      set gidDataLabels($GidLabel,singular) $Singular
    }
  }
  set GidPriv(POSTDATA) 1
}

proc GidShowBook { class {book ""} {show 1} } {
  global gidDataBooksHidden
  
  set lclass [array names gidDataBooksHidden]
  if { [set idx [lsearch $lclass $class*]] == -1 } {
    WindowMessage "Data class $class not found in GidShowBook"
    return
  }
  set class [lindex $lclass $idx]
  set lbook [.central.s info $class BOOKS]
  if { $book == "" } {
    if { $show == "0" } {
      set gidDataBooksHidden($class) $lbook
    } else {
      set gidDataBooksHidden($class) {}
    }
  } else {
    if { [set idx [lsearch -exact $lbook $book]] == -1 } {
      WindowMessage "Book $book not found in GidShowBook"
      return
    }
    
    set rbook [lindex $lbook $idx]
    
    set idx [lsearch -exact $gidDataBooksHidden($class) $rbook]
    if { $show == "0" } {
      if { $idx == -1 } {
	lappend gidDataBooksHidden($class) $rbook
      }
    } elseif { $idx != -1 } {
      set gidDataBooksHidden($class) [lreplace $gidDataBooksHidden($class) $idx $idx]
    }
  }
}

proc DWFindBookOrdinal { Class Book } {

    set BooksList [.central.s info $Class BOOKS]
    
    if { ![llength $BooksList] } {
	if { $Book == "Default" } {
	    return 1
	}
	return 0
    } else {
	set idx [lsearch $BooksList $Book]
	if { $idx == -1 } {
	    return 0
	}
	return [expr $idx/2+1]

    }
}

# Procedure GidOpenConditions --
#
#    Open de conditions window for a specific book.
#
# Arguments:
#    Book --> Book's name. If you omit this argument the default will
#        be used
#
# Results:
#

proc GidOpenConditions { {Book "Default"} } {
    set bord [DWFindBookOrdinal conditions $Book]
    if $bord {
	set GDN [DWCondWindow $Book $bord]
    } else {
	WindowMessage "GidOpenConditions: Book $Book not found in Conditions"
	set GDN ""
    }
    return $GDN
}

# Procedure GidOpenMaterials --
#
#    Open de materials window for a specific book.
#
# Arguments:
#    Book --> Book's name. If you omit this argument the default will
#        be used
#
# Results:
#

proc GidOpenMaterials { {Book "Default"} } {
    set bord [DWFindBookOrdinal materials $Book]
    if $bord {
	DWMatWindow $Book $bord
    } else {
	WindowMessage "Book $Book not found in Materials"
    }
}

# Procedure GidOpenIntervals --
#
#    Open de intervals window for a specific book.
#
# Arguments:
#    Book --> Book's name. If you omit this argument the default will
#        be used
#
# Results:
#

proc GidOpenIntervals { {Book "Default"} } {
    set bord [DWFindBookOrdinal intvdata $Book]
    if $bord {
	DWIntervalDataWindow $Book $bord
    } else {
	WindowMessage "Book $Book not found in Interval Data"
    }
}

# Procedure GidOpenProblemData --
#
#    Open the problem data window for a specific book.
#
# Arguments:
#    Book --> Book's name. If you omit this argument the default will
#        be used
#
# Results:
#

proc GidOpenProblemData { {Book "Default"} } {
    set bord [DWFindBookOrdinal gendata $Book]

    if $bord {
	DWProblemDataWindow $Book $bord
    } else {
	WindowMessage "Book $Book not found in Problem Data"
    }
}

# -------------------------------------------------------------------
#  Procedure DWLocalSetValue:
#   
#      Modifca una QUESTION perteneciente a un "conjunto de datos" 
#      abiertos identificados por {GDN STRUCT}. Le asigna el nuevo 
#      valor VALUE y cambia el estado si este se especifica.
#      STATE: normal, hidden, diabled
#
# -------------------------------------------------------------------

proc DWLocalSetValue { GDN STRUCT QUESTION VALUE {STATE ""}} {
  upvar \#0 $GDN GidData
  
  if { [catch {set ifld $GidData($STRUCT,LABEL,$QUESTION)}] } {
    set ifld [LabelField $GDN $STRUCT $QUESTION]
  }
  if { $ifld == -1 } {
    error "Invalid question access in DWSetValue for : $QUESTION"
  } else {
    if {$STATE eq ""} {
      set GidData($STRUCT,VALUE,$ifld) $VALUE
    } else {
      array set action {
	normal   DepActionRESTORE
	hidden   DepActionHIDE
	disabled DepActionSET
      }
      # no state checking!!!
      eval $action($state) $GDN $STRUCT $ifld $VALUE
    }
  }
}

# -------------------------------------------------------------------
#  Procedure DWLocalGetValue:
#   
#      Obtiene el valor asociado a una QUESTION perteneciente a un 
#     "conjunto de datos" abiertos identificados por {GDN STRUCT}.
#
# -------------------------------------------------------------------

proc DWLocalGetValue { GDN STRUCT QUESTION } {
    upvar \#0 $GDN GidData

    if { [catch {set ifld $GidData($STRUCT,LABEL,$QUESTION)}] } {
	set ifld [LabelField $GDN $STRUCT $QUESTION]
    }
    if { $ifld == -1 } {
	error "Invalid question access in DWGetValue for : $QUESTION"
    } else {
	return $GidData($STRUCT,VALUE,$ifld)
    }
}

# ------------------------------------------------------------------------------
# DWGetBook --
#
#  Returns the book name associated to this GDN.
# ------------------------------------------------------------------------------

proc DWGetBook { GDN } {
  upvar \#0 $GDN GidData
  
  set GidData(BOOK)
}

# ------------------------------------------------------------------------------
# DWGetTopLevel --
#
#  Return the widget path of the toplevel window associated to this GDN.
# ------------------------------------------------------------------------------

proc DWGetTopLevel { GDN } {
  upvar \#0 $GDN GidData

  set GidData(WINDOW)
}

# ------------------------------------------------------------------------------
# DWGetStruct --
#
#   Used to retrieve the STRUCT argument needed in functions like DWLocalGetValue
#   As you may think this is not necesary if we modify DWLocalGetValue but as this
#   proc is called in olders prbtypes we should keep it for backward compatibility. 
# ------------------------------------------------------------------------------
proc DWGetStruct { GDN } {
  upvar \#0 $GDN GidData

  $GidData(TYPEFUNC) $GDN
}

namespace eval DataBehaviour {
  variable data
  variable properties

  array set properties {
    materials {assign draw unassign impexp new modify delete}
    geomlist {points lines surfaces volumes}
    meshlist {elements}
    materials,cmds {show disable hide geomlist meshlist}
  }
}

proc DataBehaviour::GetMaterialsOpts { } {
  variable properties
  
  set properties(materials)
}

proc DataBehaviour::GetEntityList { what } {
  variable properties

  set properties($what)
}

proc DataBehaviour::IsValidProperty {data_t prop} {
  variable properties

  if {$data_t ne "materials"} {
    error [_ "DataBehaviour only implemented on materials and %s was requested" $data_t]
  }
  expr [lsearch $properties($data_t) $prop] != -1
}

proc DataBehaviour::HumanizeList { items } {
  if {[set ll [llength $items]]<=1} {
    return [lindex $items 0]
  }
  set result {}
  foreach i $items {
    incr ll -1
    if {$ll > 1} {
      append result "${i},"
    } elseif {$ll == 1} {
      append result "${i} or "
    }
  }
  append result [lindex $items end]
}

proc DataBehaviour::ProcessEntityList { key entities } {
  variable properties

  set idx 0
  set elist $properties($key)
  foreach e  $elist {
    set list_map($e) 0
    set list_index($idx) $e
    incr idx
  }
  foreach e_ $entities {
    set e [string tolower $e_]
    if {[lsearch $elist $e]==-1} {
      error [_ "invalid entity type '%s' in %s: sould be '%s'" $e_ $key [HumanizeList $elist]]
    }
    set list_map($e) 1
  }
  set result [list]
  foreach i [array names list_index] {
    set e $list_index($i)
    if {$list_map($e)} {
      lappend result $e
    }
  }
  set result
}

proc DataBehaviour::Conditions {name args} {
  error "DataBehaviour not implemented on Conditions"
}

proc DataBehaviour::Materials {isbook name args} {
  variable data
  variable properties

  set key [expr {$isbook?"bookmat":"material"}]
  if {[llength $args]==1} {
    set tprop [lindex $args 0]
    set cmd query
  } else {
    foreach {cmd_ tprop} $args break
    set cmd [string tolower $cmd_]
    if {[lsearch $properties(materials,cmds) $cmd]==-1} {
      error [_ "invalid cmd '%s' in DataBehaviour::Materials: should be '%s'" $cmd [HumanizeList $properties(materials,cmds)]]
    }
    set assign [expr {$cmd eq "meshlist" || $cmd eq "geomlist"}]
  }
  set result [list]
  if {$cmd eq "query"} {
    foreach p_ $tprop {
      set p [string tolower $p_]
      set assign [expr {$p eq "meshlist" || $p eq "geomlist"}]
      if {$assign || [IsValidProperty materials $p]} {
        lappend result $p [expr {[info exist data($key,$name,$p)]?\
                                     $data($key,$name,$p):\
                                     "default"}]
      } else {
        set tmplist $properties(materials)
        lappend tmplist "geomlist" "meshlist"
        error [_ "invalid property '%s' in DataBehaviour::Materials: should be '%s'" $p_ [HumanizeList $tmplist]]
      }
    }
  } elseif {$assign} {
    set data($key,$name,$cmd) [ProcessEntityList $cmd $tprop]
  } else {
    # enable or disable comands
    foreach p_ $tprop {
      set p [string tolower $p_]
      if {[IsValidProperty materials $p]} {
        set data($key,$name,$p) $cmd
      } else {
        error [_ "invalid property '%s' in DataBehaviour::Materials: should be '%s'" $p_ [HumanizeList $properties(materials)]]
      }
    }
  }
  set result
}

# -----------------------------------------------------------------------------
# DataBehaviour::Condition --
#
# -----------------------------------------------------------------------------

proc DataBehaviour::Condition { name args} {
  variable data

  set ll [llength $args]
  if {$ll == 1} {
    set cmd query
    set tprop [lindex $args 0]
  } else {
    foreach {cmd_ tprop} $args break
    set cmd [string tolower $cmd_]
    if {$cmd ne "enable" && $cmd ne "disable"} {
      error [_ "invalid cmd '%s' in DataBehaviour::Conditions: should be 'enable or disable'" $cmd_]
    }
  }
  set result [list]
  set lprop {visible draw unassign}
  foreach p_ $tprop {
    set p [string tolower $p_]
    if {[lsearch $lprop $p]==-1} {
      error [_ "invalid property '%s' in DataBehaviour::Conditions: should be '%s'" $p_ [HumanizeList $lprop]]
    }
    if {$cmd eq "query"} {
      lappend result $p [expr {[info exist data(condition,$name,$p)]?\
                                         $data(condition,$name,$p):"default"}]
    } else {
      set data(condition,$name,$p) $cmd
    }
  }
  set result
}

# -----------------------------------------------------------------------------
# GiD_DataBehaviour --
#
#   This command controls properties of data windows for materials and
#   conditions (not currently implemented). For materials we can modify 
#   the behaviour of assign, draw, unassign, impexp, new, modify and delete.
#   We can also specify the entity type list in assign option throught the 
#   cmds geomlist and meshlist.
#
#   Syntax:
#
#     GiD_DataBehaviour data_class name ?cmd? proplist
#
#     data_class could be: "material" if we want to modify the behaviour of a
#     particular material if whole book must be modified the data_class should
#     take the value "materials". Depending on the value of data_class name
#     takes the value of a material's name or a book's name. Argument cmd can
#     take one of the values: show, hide, disable, geomlist and meshlist.
#     Argument proplist is a list of options or entity type. When cmd is show,
#     hide or disable then proplist could a subset of {assign draw unassign
#     impexp new modify delete}. The command show make the option visible,
#     if the value is hide then the option is not visible and when the value is
#     disable then the option is visible but unavailable. When cmd if geomlist
#     then then property list can take a subset of {points lines surfaces volumes}
#     and define the entities that can get the material assigned when in geometry
#     mode, if the value of cmd is meshlist the proplist can take the value
#     elements (only elements can gets a material assigned in mesh mode). 
#
#   Examples:
#
#     GiD_DataBehaviour materials Table geomlist {surfaces volumes}
#     GiD_DataBehaviour materials Solid hide {delete impexp}  
#
#  Note: GiD_DataBehaviour is only implemented for material and books of materials.
# -----------------------------------------------------------------------------

proc GiD_DataBehaviour {data_t name args} {
  if {[set ll [llength $args]]>2 || $ll==0} {
    error [_ "wrong # of arguments: should be 'GiD_DataBehaviour data_class name ?cmd? proplist'"]
  }
  if {$name eq ""} {
    error [_ "invalid book name '%s': should be not empty" $name]  
  }
  set data_t_ [string toupper $data_t]
  if {$data_t_ eq "CONDITIONS"} {
    eval DataBehaviour::Conditions [list $name] $args
  } elseif {$data_t_ eq "MATERIALS"} {
    eval DataBehaviour::Materials 1 [list $name] $args
  } elseif {$data_t_ eq "MATERIAL"} {
    eval DataBehaviour::Materials 0 [list $name] $args
  } else {
    error [_ "invalid DataBehaviour request on unknown data type '%s': should be 'condition, conditions, material or materials'" $data_t]
  }
}

# -----------------------------------------------------------------------------
# GiD_ConditionBehaviour --
#
#   This command controls properties of conditions not defined in .cnd file.
#   The properties are : visible, draw and unassign.
#
#   GiD_ConditionBehaviour condname [property | cmd property]
#
#   cmd could be enable or disable.
#
#   examples
#
#     GiD_ConditionBehaviour Line-Constraints disable visible
#
#   when querying the properties you can provide a list of properties and
#   the result is the state for each property. The return value is a list of pairs
#   name value, like this:
#
#              {visible disable draw default unassign default}
#
#   the value "default" means that nothing has being set for this property.
#
#  Note: draw and unassign can be set or query but 
#
# -----------------------------------------------------------------------------

proc GiD_ConditionBehaviour {name args} {
  set ll [llength $args]
  if {$ll < 1 || $ll > 2} {
    error [_ "wrong # of arguments: should be 'GiD_ConditionBehaviour name \[property | cmd property\]'"]
  }
  eval DataBehaviour::Condition [list $name] $args
}