proc MeshErrors { filename } {
    global MeshErrorsPriv
    set MeshErrorsPriv(FileName) $filename 
    if [catch {set archivo [open $filename r]} f] {
	WarnWinText [_ "Error: Cannot open %1\$s: %2\$s" $filename $f]
        return
    }
    #store file data in MeshErrorsPriv
    set NLines 0
    set NSurfs 0
    set NVols 0
    set CauseLine "--"
    set CauseSurf "--"
    set CauseVol "--"
    while { ![ eof $archivo ] } {
	gets $archivo aa	
	if { $aa == {[Error_Meshing_Line]} } {
	    set MeshErrorsPriv(ErrLine,$NLines,Cause) $CauseLine
	    gets $archivo aa
            set Num 0
	    regexp {Number:[ ]*([0-9]+)} $aa {} Num
	    set MeshErrorsPriv(ErrLine,$NLines,Num) $Num
	    incr NLines
	    gets $archivo aa	
	} elseif { $aa == {[Error_Meshing_Surface]} } {
	    set MeshErrorsPriv(ErrSurf,$NSurfs,Cause) $CauseSurf
	    gets $archivo aa
	    set Num 0
	    regexp {Number:[ ]*([0-9]+)} $aa {} Num
	    set MeshErrorsPriv(ErrSurf,$NSurfs,Num) $Num
	    incr NSurfs
	    gets $archivo aa	
	} elseif { $aa == {[Error_Meshing_Volume]} } {
	    set MeshErrorsPriv(ErrVol,$NVols,Cause) $CauseVol
	    gets $archivo aa
	    set Num 0
	    regexp {Number:[ ]*([0-9]+)} $aa {} Num
	    set MeshErrorsPriv(ErrVol,$NVols,Num) $Num
	    incr NVols
	    gets $archivo aa	
	} elseif { $aa == {[Error_AdvancingFront3D]} } {	   
	    gets $archivo aa
	    regexp {Description:[ ]*(.*)} $aa {} CauseVol
	    gets $archivo aa
	    set x "Unknown"
	    set y "Unknown"
	    set z "Unknown"
	    regexp {NearPoint:[ ]*([0-9.+eE-]+)[ ]*([0-9.+eE-]+)[ ]*([0-9.+eE-]+)} $aa {} x y z
	    set MeshErrorsPriv(ErrVol,$NVols,x) $x
	    set MeshErrorsPriv(ErrVol,$NVols,y) $y
	    set MeshErrorsPriv(ErrVol,$NVols,z) $z
	    gets $archivo aa
	    gets $archivo aa
	    gets $archivo aa
	} elseif { $aa == {[Error_AdvancingFront2D]} } {	   
	    gets $archivo aa
	    regexp {Description:[ ]*(.*)} $aa {} CauseSurf
	    gets $archivo aa
	    set x "Unknown"
	    set y "Unknown"
	    set z "Unknown"
	    regexp {NearPoint:[ ]*([0-9.+eE-]+)[ ]*([0-9.+eE-]+)[ ]*([0-9.+eE-]+)} $aa {} x y z
	    set MeshErrorsPriv(ErrSurf,$NSurfs,x) $x
	    set MeshErrorsPriv(ErrSurf,$NSurfs,y) $y
	    set MeshErrorsPriv(ErrSurf,$NSurfs,z) $z
	    gets $archivo aa
	    gets $archivo aa
	    gets $archivo aa
	}
    }   
    close $archivo
    set MeshErrorsPriv(ErrLine,NumErr) $NLines
    set MeshErrorsPriv(ErrSurf,NumErr) $NSurfs
    set MeshErrorsPriv(ErrVol,NumErr) $NVols

    CreateWindowErrorMesh ".gid.mesherrors"
}

proc CreateWindowErrorMesh { { w ".gid.mesherrors" } } {
    global MeshErrorsPriv
    InitWindow $w [_ "MeshErrors"] MeshErrorsWindowGeom
    frame $w.fup
    frame $w.fup.fs
    frame $w.fup.fv
    
    set NSurfs $MeshErrorsPriv(ErrSurf,NumErr)
    set NVols $MeshErrorsPriv(ErrVol,NumErr)
    set func "optionbar $w.fup.opt"
    if { $NSurfs > 0 && $NVols > 0} {	
	lappend func "Surfaces $w.fup.fs {}"
	lappend func "Volumes $w.fup.fv {}"
    } elseif { $NSurfs > 0 } {
	lappend func "Surfaces $w.fup.fs {}"
    } elseif { $NVols > 0 } {
	lappend func "Volumes $w.fup.fv {}"
    }
    eval $func
    
    grid $w.fup -sticky nsew 
    pack $w.fup.opt -fill both -expand yes -side top
    update idletasks

    #grid $w.fup -sticky nsew 
    #grid $w.fup.opt -sticky nsew -padx 5 -pady 5
    #update idletasks
    #grid columnconf $w.fup 0 -weight 1
    #grid rowconfigure $w.fup 0 -weight 1
   
    CreateWidgetsFrame $w.fup.fs ErrSurf 
    CreateWidgetsFrame $w.fup.fv ErrVol

    #lower buttons
    set def_back [$w cget -background]
    frame $w.frmButtons -bg [CCColorActivo $def_back]
    button $w.frmButtons.btnclose -text [_ "Close"] \
	    -command "destroy $w" \
	    -underline 0 -width 6
    
    grid $w.frmButtons -sticky ews -columnspan 7
    grid $w.frmButtons.btnclose -padx 5 -pady 6
    grid columnconf $w 0 -weight 1
    grid rowconfigure $w 0 -weight 1

    focus $w.frmButtons.btnclose
    bind $w <Alt-c> "tkButtonInvoke $w.frmButtons.btnclose"
    bind $w <Escape> "tkButtonInvoke $w.frmButtons.btnclose"

    wm minsize $w 160 200

    update idletasks

    #fill values
    $w.fup.fs.lbl configure -text [_ "%s wrong surfaces" $NSurfs]
    $w.fup.fs.frtxt.t del 0 end
    $w.fup.fs.frtxt.t insert end "Num       Description"
    for {set i 0} {$i < $NSurfs } {incr i} {
        set buf "$MeshErrorsPriv(ErrSurf,$i,Num)   "
	append buf "$MeshErrorsPriv(ErrSurf,$i,Cause)"
	$w.fup.fs.frtxt.t insert end $buf
    }
    bind $w.fup.fs.frtxt.t <Double-Button-1> "[list SignalSelected $w.fup.fs.frtxt.t ErrSurf NearPoint]"
    
    $w.fup.fv.lbl configure -text "$NVols [_ "wrong volumes"]" 
    $w.fup.fv.frtxt.t del 0 end
    $w.fup.fv.frtxt.t insert end "Num       Description"
    for {set i 0} {$i < $NVols } {incr i} {
	set buf "$MeshErrorsPriv(ErrVol,$i,Num)    "
	append buf "$MeshErrorsPriv(ErrVol,$i,Cause)"
	$w.fup.fv.frtxt.t insert end $buf
    }
    bind $w.fup.fv.frtxt.t <Double-Button-1> "[list SignalSelected $w.fup.fv.frtxt.t ErrVol NearPoint]"
}


proc SignalSelected { w type NumOrNearPoint } {
    global MeshErrorsPriv
    set i [expr [$w curselection]-1]
    
    if { $i < 0  || $i >= $MeshErrorsPriv($type,NumErr) } return
  
    set iNumEnt $MeshErrorsPriv($type,$i,Num)
    #.central.s process escape escape escape escape redraw
    if { $type == "ErrSurf" } {
	if { $NumOrNearPoint == "NearPoint" } {
	    if { [info exists MeshErrorsPriv($type,$i,x)] } {
		set x $MeshErrorsPriv($type,$i,x)
		set y $MeshErrorsPriv($type,$i,y)
		set z $MeshErrorsPriv($type,$i,z)
	    } else {
		set x Unknown
	    }
	    if { $x == "Unknown" } {
		WarnWinText [_ "Unknown point near the problematic shape"]
	    } else {
		.central.s process escape escape escape escape utilities\
			signalentities points FNoJoin $x $y $z
	    }
	} else {
	    .central.s process escape escape escape escape utilities\
		    signalentities surfaces $iNumEnt
	}
    } else {
	#type == "ErrVol"
	if { $NumOrNearPoint == "NearPoint" } {
	    set x $MeshErrorsPriv($type,$i,x)
	    set y $MeshErrorsPriv($type,$i,y)
	    set z $MeshErrorsPriv($type,$i,z)
	    if { $x == "Unknown" } {
		WarnWinText [_ "Unknown point near the problematic shape"]
	    } else {
		.central.s process escape escape escape escape utilities\
			signalentities points FNoJoin $x $y $z
	    }
	} else {
	    .central.s process escape escape escape escape utilities\
		    signalentities volumes $iNumEnt
	}
    }
}


proc CreateWidgetsFrame { fr type } {
    label $fr.lbl -text [_ "Number of wrong entities:"]
    frame $fr.frtxt
    frame $fr.frbut

    grid $fr.lbl -sticky new -padx 5 -pady 5
    grid $fr.frtxt -sticky nsew -padx 5 -pady 5 -columnspan 7
    grid $fr.frbut -sticky sew -padx 5 -pady 5
    grid rowconf $fr 1 -weight 1
    grid columnconf $fr 0 -weight 1

    scrollbar $fr.frtxt.scrolly -command "$fr.frtxt.t yview" -orient vertical -relief sunken
    scrollbar $fr.frtxt.scrollx -command "$fr.frtxt.t xview" -orient horizontal -relief sunken
    listbox $fr.frtxt.t -font SmallFont -yscrollcommand "$fr.frtxt.scrolly set" \
	    -xscrollcommand "$fr.frtxt.scrollx set" -width 40 -height 5
    
    button $fr.frbut.btnsignal -text [_ "Signal"] -command "[list SignalSelected $fr.frtxt.t $type Num]" \
	    -underline 0 -width 6
    button $fr.frbut.btndetails -text [_ "Details"] -command "Details" \
	    -underline 0 -width 6 -relief flat
   
    grid $fr.frtxt.t -row 0 -column 0 -sticky nsew
    grid $fr.frtxt.scrolly -row 0 -column 1 -sticky ns
    grid $fr.frtxt.scrollx -row 1 -column 0 -sticky ew
    grid rowconf $fr.frtxt 0 -weight 1
    grid columnconf $fr.frtxt 0 -weight 1

    grid $fr.frbut.btnsignal $fr.frbut.btndetails -sticky ew -padx 5 -pady 5 

    #pack $fr

    grid remove $fr.frtxt.scrolly
    grid remove $fr.frtxt.scrollx
    bind $fr.frtxt.t <Configure> "ShowOrHideScroll $fr.frtxt.t $fr.frtxt.scrollx $fr.frtxt.scrolly"
}


#text must be a listbox, text or canvas widget and sx,sy scrollbar widgets
proc ShowOrHideScroll { text sx sy } {
    foreach i "x y" {
	if { ![info exists s${i}] || ![winfo exists [set s${i}]] } { continue }
	foreach "${i}1 ${i}2" [$text ${i}view] break
	
	if { [set ${i}1] == 0 && [set ${i}2] == 1 } {
	    after idle grid remove [set s${i}]
	} else {
	    after idle grid [set s${i}]
	}
    }
}

proc Details { } {    
    global MeshErrorsPriv
    set text ""
    set NSurfs $MeshErrorsPriv(ErrSurf,NumErr)
    if { $NSurfs > 0 } {
	append text "$NSurfs problematic surfaces:"
	for {set i 0} {$i < $MeshErrorsPriv(ErrSurf,NumErr) } {incr i} {
	    append text " $MeshErrorsPriv(ErrSurf,$i,Num)"
	}
	append text "\n"
    }
    set NVols $MeshErrorsPriv(ErrVol,NumErr)
    if { $NVols > 0 } {
	append text "$NVols problematic volumes:"
	for {set i 0} {$i < $MeshErrorsPriv(ErrVol,NumErr) } {incr i} {
	    append text " $MeshErrorsPriv(ErrVol,$i,Num)"
	}
	append text "\n"
    }     
    WarnWinText $text [_ "Problems meshing"]
}
