#!/bin/sh
#CordalError  -*- TCL -*- Created: ramsan Mar-2000, Modified: ramsan Mar-2000

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

set CordalErrorRunningAlone 0
catch {
    if {$argv0 == [info script] } {
	set CordalErrorRunningAlone 1
	set tcl_interactive 0
	set tk_strictMotif 1
	wm withdraw .

	if { [catch { set GIDDEFAULT $env(GIDDEFAULT)}]!=1 } {
	    set GIDDEFAULTTCL $GIDDEFAULT
	    catch { set GIDDEFAULTTCL $env(GIDDEFAULTTCL) }
	    set auto_path "$GIDDEFAULTTCL"
	    source $GIDDEFAULTTCL/init.tcl
	    source $GIDDEFAULTTCL/tk.tcl
	}
    }
}

#  LOOK AT THE END OF THE FILE !!!
#-------------------------------------------------------------------

proc RedrawArc { canvas } {
    global CEPriv 

    if { ![winfo exists $canvas] } { return }

    if { "$CEPriv(radius)" == "" } { return }

    set width [winfo width $canvas]
    if { $width < 10 } { set width [winfo reqwidth $canvas] }
    set height [winfo height $canvas]
    if { $height < 10 } { set height [winfo reqheight $canvas] }

#    if { $CEPriv(radius)!="Inf." &&  ( $CEPriv(radius) < 0 || $CEPriv(radius) >= 1e5 ) } { 
#	set CEPriv(radius) Inf. 
#    }
    set r $CEPriv(radius)

    if { $CEPriv(length) < 0 || $CEPriv(length) > 1e5 } { set CEPriv(length) 10 }
    set l $CEPriv(length)
    if { $CEPriv(cordalerror) < 0 || $CEPriv(cordalerror) > 1e5 } {
	set CEPriv(cordalerror) .1
    }
    set CE $CEPriv(cordalerror)

    if { $r == "Inf." } {
	set NE 1
    } else {
	set size [expr 2.0*sqrt(2*$r*$CE-$CE*$CE)]
	if { $size == 0 } { 
	    set NE 1
	} else { set NE [expr int($l/$size)] }
	
	if { $NE < 1 } { set NE 1 }
    }
    set CEPriv(numelems) "Mesh elements: $NE"

    if { $r != "Inf." } {
	set f [expr double($width)/$l]
	
	set x1 [expr $width/2-$f*$r]
	set x2 [expr $width/2+$f*$r]
	
	set y1 40
	set y2 [expr 40+$f*(2*$r)]
	
	set angle [expr 0.9*180.0/3.1416*$l/$r]
	if { $angle > 360 } { set angle 359 }

	$canvas delete temp
	set start [expr 90-$angle/2]
	$canvas create arc $x1 $y1 $x2 $y2 -outline red -start $start \
		-extent $angle -width 2 -style arc -tags temp
	$canvas create line [expr $width/2] 150 [expr $width/2] 42 -arrow last \
		-fill red -tags temp
	$canvas create line [expr $width/2-10] 150 [expr $width/2+10] 150 \
		-fill red -tags temp
	
	set cx [expr ($x1+$x2)/2.0]
	set cy [expr ($y1+$y2)/2.0]
	set rd [expr $f*$r]
	
	if { $NE <= 50 } {
	    for { set i 0 } { $i <= $NE } { incr i } {
		set a [expr $i*$angle/$NE]
		set x [expr $cx+$rd*cos(($a+$start)*3.1416/180.0)]
		set y [expr $cy-$rd*sin(($a+$start)*3.1416/180.0)]
		if { $a > 0 } {
		    $canvas create line $xold $yold $x $y -fill black \
			    -tags temp
		    
		}
		$canvas create oval [expr $x-2] [expr $y-2]  [expr $x+2] \
			[expr $y+2] \
			-fill black -tags temp
		set xold $x
		set yold $y
	    }
	}
    } else {
	$canvas delete temp
	$canvas create line 10 42 [expr $width-20] 42 -fill black \
		-tags temp
	$canvas create oval 8 40 12 44 -fill black -tags temp
	$canvas create oval [expr $width-20-2] 40  [expr $width-20+2] \
		44 -fill black -tags temp	
	$canvas create line [expr $width/2] 150 [expr $width/2] 42 -arrow last \
		-fill red -tags temp
	$canvas create line [expr $width/2-10] 150 [expr $width/2+10] 150 \
		-fill red -tags temp
    }

    #$canvas coords $CEPriv(radiuspos) [expr $width/2+10] 95
    $canvas coords radpos [expr $width/2+10] 95
}


proc CECLoseTest { w but } {
    global CEPriv GIDDEFAULT

    grid rowconf $w 4 -weight 0
    $but conf -bitmap @[file join $GIDDEFAULT bitmaps downdoublearrow] \
	    -command "CEOpenTest $w $but"
    grid remove $w.ftest
    #destroy $w.ftest
}

proc CEEndSelLine { w } {
    global GidPriv CEPriv

    set ne $CEPriv(numelems) 
    $w.ftest.c.numelems conf -textvar CEPriv(numelems) 
    set CEPriv(numelems) $ne

    $w.ftest.line conf -command "CESelLine $w" -image $GidPriv(image_line.gif)

    foreach i [trace vinfo GidPriv(selection)] {
	trace vdelete GidPriv(selection) [lindex $i 0] [lindex $i 1] 
    }

    set num [lindex [lindex $GidPriv(selection) 0] 1]
    set nnum ""
    regexp {[0-9]*} $num nnum
    if { $nnum != "" } {
	set retval [.central.s info list_entities -more Lines $nnum]
	regexp {Length=[ ]*([0-9.]*)[ ]*Radius=([0-9.]*)} $retval {} l r
	set CEPriv(length) $l
       
      if { $r < 0 || $r >= 1e5  } { 
        set CEPriv(radius) Inf.
      } else {
  	  set CEPriv(radius) $r
      }
	raise $w
    }
}

proc CESelLine { w } {
    global GidPriv
    
    if { [trace vinfo GidPriv(selection)] != "" } { return }

    $w.ftest.c.numelems conf -textvar "" 
    $w.ftest.c.numelems conf -text [_ "Select one line of the model"]
    
    .central.s process SelectEntities JustOne Lines
    
    $w.ftest.line conf -command ".central.s process escape escape escape " \
	    -image $GidPriv(image_line-bw.gif)
    trace var GidPriv(selection) w "CEEndSelLine $w ;#"
}

proc CEOpenTest { w but} {
    global CEPriv GIDDEFAULT GidPriv

    wm geom $w ""
    grid rowconf $w 4 -weight 1
    $but conf -bitmap @[file join $GIDDEFAULT bitmaps updoublearrow] \
		-command "CECLoseTest $w $but"

    grid $w.ftest

#	if { ![winfo exists $w.ftest] } {
#	  frame $w.ftest
#	  grid $w.ftest -row 4 -column 1 -columnspan 2 -sticky nsew
#	}

    if { ![winfo exists $w.ftest.c] } {

	canvas $w.ftest.c -bd 2 -relief groove -height 200 -takefocus 0

	grid $w.ftest.c -sticky ewns -row 1 -column 1
	grid columnconf $w.ftest 1 -weight 1
	grid rowconf $w.ftest 1 -weight 1
	if { ![info exist GidPriv(image_line.gif)] } {
	    set GidPriv(image_line.gif) [ image create photo -file \
		    $GIDDEFAULT/bitmaps/line.gif]
	}
	if { ![info exist GidPriv(image_line-bw.gif)] } {
	    set GidPriv(image_line-bw.gif) [ image create photo -file \
		    $GIDDEFAULT/bitmaps/line.gif -palette 2]
	}
	button $w.ftest.line -image $GidPriv(image_line.gif) \
		-command "CESelLine $w"
	place $w.ftest.line -in $w.ftest.c -anchor se -relx 1 -rely 1 \
		-x -4 -y -4
  	GidHelp $w.ftest.line [_ "A line can be selected to obtain its length and\
  		curvature radius"]

	frame $w.ftest.c.length
	label $w.ftest.c.length.l -text [_ "Length:"]
	entry $w.ftest.c.length.e -textvar CEPriv(length) -width 9
	pack $w.ftest.c.length.l $w.ftest.c.length.e -side left

	set CEPriv(length) 10

	frame $w.ftest.c.radius
	label $w.ftest.c.radius.l -text [_ "Radius:"]
	entry $w.ftest.c.radius.e -textvar CEPriv(radius) -width 9
	pack $w.ftest.c.radius.l $w.ftest.c.radius.e -side left
	set CEPriv(radius) 12

	label $w.ftest.c.numelems -textvar CEPriv(numelems) -relief ridge -bd 2 \
		-width 30 -anchor w
	place $w.ftest.c.numelems -in $w.ftest.c -anchor sw -relx 0 -rely 1 \
		-x +4 -y -5
	set CEPriv(numelems) "Mesh elements: "

	$w.ftest.c create window 20 10 -window $w.ftest.c.length -anchor nw
	set CEPriv(radiuspos) [$w.ftest.c create window 30 10 \
		-window $w.ftest.c.radius -anchor w -tags radpos]

	GidHelp $w.ftest.c [_ "This graphical window is used to test the\
		cordal error.\nGiven a length of the line, its radius and\
		the cordal error, it calculates approximately the number of\
		elements that will be meshed over it.\n\
		The length and radius can be selected from a line in the model."]


	trace var CEPriv(length) w "RedrawArc $w.ftest.c;#"
	trace var CEPriv(radius) w "RedrawArc $w.ftest.c;#"
	trace var CEPriv(cordalerror) w "RedrawArc $w.ftest.c;#"
    }


    RedrawArc $w.ftest.c

}

proc CEprocessinfo {} {
    global CEPriv

    set minsize $CEPriv(minmeshsize)
    if { $minsize == "Automatic" } {
	set minsize [expr $CEPriv(maxmeshsize)/500.0]
    }
    .central.s process escape escape escape escape Meshing AssignSizes \
	    ByCordalError $minsize $CEPriv(maxmeshsize) \
	    $CEPriv(cordalerror) escape
}

proc CEprocessinfoCS {} {
    global CEPriv

    set minsize $CEPriv(minmeshsize)
    if { $minsize == "Automatic" } {
	set minsize [expr $CEPriv(maxmeshsize)/500.0]
    }

    if { !$CEPriv(bygeometry) && !$CEPriv(correctsizes) } {
	WarnWin [_ "No action has been performed. Check one or more options to proceed"]
	return
    }

    if { $CEPriv(bygeometry) } {
	.central.s process escape escape escape escape Meshing AssignSizes \
		ByGeometry $minsize $CEPriv(maxmeshsize) escape
    }
    if { $CEPriv(correctsizes) } {
	.central.s process escape escape escape escape Meshing AssignSizes \
		CorrectSizes $CEPriv(maxmeshsize) escape
    }
}

proc CEGiveSizeFromBBox { bbox } {

    set bbox [lindex $bbox 0]
    set err [catch {expr {abs([lindex $bbox 0]-[lindex $bbox 1])}} l1]
    if { $err } { set l1 1 }
    set err [catch {expr {abs([lindex $bbox 2]-[lindex $bbox 3])}} l2]
    if { $err } { set l2 1 }
    set err [catch {expr {abs([lindex $bbox 4]-[lindex $bbox 5])}} l3]
    if { $err } { set l3 1 }

    set retval [expr ($l1+$l2+$l3)/30.0]
    if { $retval == 0 } { 
	return 10 
    } else {return [format "%g" $retval] }
}

proc CEBeginCorrectSizes { { w .gid.correctsizes } } {
    global CEPriv GIDDEFAULT

    if { ![winfo exists $w] } {
	InitWindow $w [_ "Correct meshing sizes"] CorrectSizesWindowGeom "" "" 1
	
    set retval [lindex [.central.s info Project] 11]
    set bbox [.central.s info layers -bbox]
    set calcsize [CEGiveSizeFromBBox $bbox]
    if { ![info exists CEPriv(maxmeshsize)] || $CEPriv(maxmeshsize) == "" } {
		if { $retval != "NONE" } {
			set CEPriv(maxmeshsize) $retval
		} else {
			set CEPriv(maxmeshsize) $calcsize
		}
    }

	label $w.l2 -text [_ "Maximum meshing size:"]
	entry $w.c2 -textvariable CEPriv(maxmeshsize)
	
	GidHelp "$w.l2 $w.c2" [_ "Typically, it is the meshing size that will be used\
		later as default for meshing."]

	label $w.l3 -text [_ "Minimum meshing size:"]
	combobox $w.c3 -editable 1 -textvariable CEPriv(minmeshsize)

	if { ![info exist CEPriv(minmeshsize)] || $CEPriv(minmeshsize) == "" } {
		set CEPriv(minmeshsize) Automatic
		$w.c3 add Automatic
	} else {
		$w.c3 add $CEPriv(minmeshsize)
		if { [string compare $CEPriv(minmeshsize) "Automatic"] } {
			$w.c3 add Automatic
		}
	}	

	GidHelp "$w.l3 $w.c3" [_ "The algorithm will not assign any size smaller\
		than this to any geometrical entity."]

	if { ![info exists CEPriv(bygeometry)] } {
	    set CEPriv(bygeometry) 1
	}
	checkbutton $w.ce1 -text [_ "By geometry"] -variable CEPriv(bygeometry)

	if { ![info exists CEPriv(correctsizes)] } {
	    set CEPriv(correctsizes) 1
	}
	checkbutton $w.ce2 -text [_ "Correct incompatible sizes"] \
		-variable CEPriv(correctsizes)
	
	GidHelp "$w.ce1" [_ "Option 'By geometry' assign smaller meshing sizes\
		to details in geometry.\nNote: Option 'Correct meshing sizes'\
		in Preferences perform both actions automatically."]

	GidHelp "$w.ce2" [_ "Option 'Correct incompatible sizes' compares close\
		geometrical entities and change its sizes to make them\
		compatible.\nNote: Option 'Correct meshing sizes'\
		in Preferences perform both actions automatically."]


	frame $w.buts -relief ridge -bd 2
	button $w.buts.ok -text [_ "OK"] -width 6 -command \
		"CEprocessinfoCS ; destroy $w " -und 0
	button $w.buts.cancel -text [_ "Cancel"] -command "destroy $w"  -width 6 \
		 -und 0

	bind $w <Alt-o> "$w.buts.ok invoke"
	bind $w <Alt-c> "$w.buts.cancel invoke"
	bind $w.c2 <Return> "$w.buts.ok invoke"
	#bind $w.c3 <Return> "$w.buts.ok invoke"
	bind $w <Escape> "$w.buts.cancel invoke"

	bind $w.c2 <FocusIn> {
	    %W sel from 0
	    %W sel to end
	    %W icursor end
	}
	bind $w.c2 <FocusOut> { %W sel clear }

	bind $w.c3 <FocusIn> {
	    %W sel from 0
	    %W sel to end
	    %W icursor end
	}
	bind $w.c3 <FocusOut> { %W sel clear }

	grid $w.buts.ok -row 1 -column 1
	grid $w.buts.cancel -row 1 -column 2

	grid $w.l2 -row 1 -column 1  -sticky e
	grid $w.c2 -row 1 -column 2 -sticky ew
	
	grid $w.l3 -row 2 -column 1  -sticky e -pady 2
	grid $w.c3 -row 2 -column 2 -sticky ew
	
	grid $w.ce1 -row 3 -column 1  -sticky w -columnspan 2 -pady 2
	grid $w.ce2 -row 4 -column 1 -sticky  w -columnspan 2

 	grid $w.buts -row 5 -column 1 -columnspan 2 -sticky ew

    }

    focus $w.c2
    $w.c2 sel from 0
    $w.c2 sel to end
    $w.c2 icursor end

}

proc CEBegin { { w .gid.cordalerror } } {
    global CEPriv GIDDEFAULT
    
    if { ![winfo exists $w] } {
	InitWindow $w [_ "Asign sizes by cordal error"] CordalErrorWindowGeom "" "" 1
	
	if { ![info exists CEPriv(cordalerror)] || $CEPriv(cordalerror) == "" } { 
	  set CEPriv(cordalerror) 0.1 
      }

    set retval [lindex [.central.s info Project] 11]
    set bbox [.central.s info layers -bbox]
    set calcsize [CEGiveSizeFromBBox $bbox]
    if { ![info exists CEPriv(maxmeshsize)] || $CEPriv(maxmeshsize) == "" } {
		if { $retval != "NONE" } {
			set CEPriv(maxmeshsize) $retval
		} else {
			set CEPriv(maxmeshsize) $calcsize
		}
    }

	label $w.l1 -text [_ "Cordal Error:"]
	entry $w.c1 -textvariable CEPriv(cordalerror)
		
	GidHelp "$w.l1 $w.c1" [_ "Smaller cordal errors will asign smaller sizes to\
		entities with high curvature"]

	label $w.l2 -text [_ "Maximum meshing size:"]
	entry $w.c2 -textvariable CEPriv(maxmeshsize)
	
	GidHelp "$w.l2 $w.c2" [_ "Typically, it is the meshing size that will be used\
		later as default for meshing."]

	label $w.l3 -text [_ "Minimum meshing size:"]
	combobox $w.c3 -editable 1 -textvariable CEPriv(minmeshsize)

	if { ![info exist CEPriv(minmeshsize)] || $CEPriv(minmeshsize) == "" } {
		set CEPriv(minmeshsize) Automatic
		$w.c3 add Automatic
	} else {
		$w.c3 add $CEPriv(minmeshsize)
		if { [string compare $CEPriv(minmeshsize) "Automatic"] } {
			$w.c3 add Automatic
		}
	}
	
	
	GidHelp "$w.l3 $w.c3" [_ "The algorithm will not assign any size smaller\
		than this to any geometrical entity."]

	frame $w.ftest

	frame $w.buts -relief ridge -bd 2	
	button $w.buts.ok -text [_ "OK"] -width 6 -command \
		"CEprocessinfo ; destroy $w" -und 0
	button $w.buts.cancel -text [_ "Cancel"] -command "destroy $w"  -width 6 \
		 -und 0

	button $w.buts.test -bitmap @[file join $GIDDEFAULT bitmaps \
		downdoublearrow] -command "CEOpenTest $w $w.buts.test"

	bind $w <Alt-o> "$w.buts.ok invoke"
	bind $w <Alt-c> "$w.buts.cancel invoke"
	bind $w.c1 <Return> "$w.buts.ok invoke"
	bind $w.c2 <Return> "$w.buts.ok invoke"
	#bind $w.c3 <Return> "$w.buts.ok invoke"
	bind $w <Escape> "$w.buts.cancel invoke"

	bind $w.c1 <FocusIn> {
	    %W sel from 0
	    %W sel to end
	    %W icursor end
	}
	bind $w.c1 <FocusOut> { %W sel clear }
	bind $w.c2 <FocusIn> {
	    %W sel from 0
	    %W sel to end
	    %W icursor end
	}
	bind $w.c2 <FocusOut> { %W sel clear }
	bind $w.c3 <FocusIn> {
	    %W sel from 0
	    %W sel to end
	    %W icursor end
	}
	bind $w.c3 <FocusOut> { %W sel clear }

	GidHelp $w.buts.test [_ "A graphical window to test the cordal\
		error is given"]

	grid $w.buts.ok -row 1 -column 1
	grid $w.buts.cancel -row 1 -column 2
	place $w.buts.test -in $w.buts -relx 1 -rely 1 -anchor se

	grid $w.l1 -row 1 -column 1 -sticky e  -pady 2
	grid $w.c1 -row 1 -column 2 -sticky ew
	
	grid $w.l2 -row 2 -column 1  -sticky e
	grid $w.c2 -row 2 -column 2 -sticky ew
	
	grid $w.l3 -row 3 -column 1  -sticky e -pady 2
	grid $w.c3 -row 3 -column 2 -sticky ew
	
	grid $w.ftest -row 4 -column 1 -columnspan 2 -sticky nsew
	grid $w.buts -row 5 -column 1 -columnspan 2 -sticky ew
	
	grid columnconf $w 2 -weight 1
	

    }

    focus $w.c1
    $w.c1 sel from 0
    $w.c1 sel to end
    $w.c1 icursor end

}

#----------------------CORDALERROR ALONE---------------------------
if { $CordalErrorRunningAlone == 1 } {
    CEBegin .cordalerror
} 
#-----------------------------------------------------------------
