
# Viewing-related stuff.
# Note: this stuff is NOT loaded into the med version of autohex
#
# Copyright (c) 1993, 1994 Pacific Marketing and Consulting
# Author:  Wayne A. Christopher, wayne@pmac.com
#          Pacific Marketing and Consulting, Berkeley, California

# NOTE - this file must get merged with the ai*environment one at some point

proc setup_graphics_window {} {
    global tdv_default tree_frame normalfont
    global graphics_type black_and_white use_xwindows xwindows_fast
    global tdv_cursor_path autohex_dir guibase_dir use_dbuffer
    global graph_action_var tdv_axes_var tdv_origin_var tdv_directlight_var
    global view_panes edit_frame mess_frame is_win use_control_hotkeys
    global allow_multiple_views tree_on_left after_objects_loaded_cmd
    
    switch $use_xwindows {
	1 { set graphics_type X11 }
	2 { set graphics_type OpenGL }
    }
    if $black_and_white {
	set bgcolor white
    } else {
	set bgcolor black
    }
    
    set pad [expr $is_win * 2]
    
    set view_panes(all_viewers) ""
    
    PanedWindow .v.bot -side bottom -pad $pad -width 6
    grid .v.bot -row 1 -column 0 -sticky news
    
    if [info exists tree_on_left] {
	set tree_frame [.v.bot add -weight 1]
	set vwin1 [.v.bot add -weight 8]
    } else {
	set vwin1 [.v.bot add -weight 8]
	set tree_frame [.v.bot add -weight 1]
    }
    PanedWindow $vwin1.f -side left -pad $pad -width 6
    pack $vwin1.f -side bottom -fill both -expand 1
    
    set vwin [$vwin1.f add -weight 5]
    set emwin [$vwin1.f add -weight 1]
    
    PanedWindow $emwin.f -side bottom -pad $pad -width 6
    pack $emwin.f -side bottom -fill both -expand 1
    
    set editheight [expr int(-[lindex $normalfont 1] * 9.3)] ;# ???
    set editwidth [expr int(-[lindex $normalfont 1] * 35.8)] ;# ???
    
    set mess_frame [$emwin.f add -weight 5]
    set sf [$emwin.f add -weight 5]
    set sfw [ScrolledWindow $sf.f]
    pack $sf.f -fill both -expand 1
    set sfw2 [ScrollableFrame $sfw.f]
    set edit_frame [$sfw2 getframe]
#    puts "$sf configure -width $editwidth -height $editheight"
#    after 1000 $sf configure -width $editwidth -height $editheight
    # this is strange but I can't figure out how else to make this happen ...
    set after_objects_loaded_cmd "$sfw setwidget $sfw2"
    
    # ------------------------
    
    set tdv_default $vwin.one
    set ::tdv_current_viewer $tdv_default
    make_one_graphics_window $tdv_default NULL
    set view_panes(viewer_one) $tdv_default
    
    set tw [winfo width .v]
    $view_panes(viewer_one) configure -width [expr $tw * 0.8]
    pack $view_panes(viewer_one) -fill both -expand 1
    set view_panes(mode) 1
    set view_panes(viewers) $tdv_default
    
    set view_panes(horiz_pane) $vwin.four
    
    # ------------------------
    
    lappend tdv_cursor_path $autohex_dir
    lappend tdv_cursor_path $guibase_dir
    
    tdv_init_shortcuts [info exists use_control_hotkeys]
    
    set graph_action_var 0
    
    foreach v {x y z} {
	global shape_${v}_grid shape_${v}_grid_on
	trace variable shape_${v}_grid w "update_visible_grid; list"
	trace variable shape_${v}_grid_on w "update_visible_grid; list"
    }
    
    tree_init
}

proc update_visible_grid {} {
    global tdv_two_d_grid_incr unit_default
    
    set un $unit_default(length)
    
    set tdv_two_d_grid_incr(all) ""
    foreach v {x y z} {
	global shape_${v}_grid shape_${v}_grid_on
	if [set shape_${v}_grid_on] {
	    lappend tdv_two_d_grid_incr(all) \
		[unit_convert [set shape_${v}_grid] $un 0 0]
	} else {
	    lappend tdv_two_d_grid_incr(all) 0
	}
    }
    tdv_toggle_two_d_grid all
}

proc make_one_graphics_window {win master} {
    global tdv_default tree_frame model_container_root
    global graphics_type black_and_white use_xwindows xwindows_fast
    global tdv_cursor_path autohex_dir guibase_dir use_dbuffer
    global graph_action_var tdv_axes_var tdv_origin_var tdv_directlight_var
    global view_panes tdv_highlight_frame
    global allow_multiple_views tree_on_left
    
    if ![info exists tdv_axes_var(all)] {
	set tdv_axes_var(all) 1
    }
    if ![info exists tdv_origin_var(all)] {
	set tdv_origin_var(all) 1
    }
    if ![info exists tdv_directlight_var(all)] {
	set tdv_directlight_var($win) 1
    }
    switch $use_xwindows {
	1 { set graphics_type X11 }
	2 { set graphics_type OpenGL }
    }
    if {$master != "NULL"} {
	set bgcolor [$master cget -background]
    } elseif $black_and_white {
	set bgcolor white
    } else {
	set bgcolor black
    }
    
    if {$master == "NULL"} {
	set minw [expr int([winfo screenwidth .] * .2)]
    } else {
	set minw 0
    }
    tdv_init $win 100 100 $graphics_type $bgcolor 0 $use_dbuffer 0 $master \
	$minw
    pack $win -expand 1 -fill both
    
    $win configure -zoff 0.001
    if !$xwindows_fast {
	$win configure -xhidden 1 -xgouraud 1
    }
    $win configure -before_draw_func before_draw_func
    
    tdv_dynamics_bindings $win
    tdv_selection_bindings $win
    
    tdv_toggle_origin all
    tdv_toggle_axes $win
    tdv_toggle_track_mouse $win
    
    lappend view_panes(all_viewers) $win
    
    set tdv_highlight_frame($win) [winfo parent $win]
}

proc before_draw_func {} {
    global model_container_root type_visible current_shape
    global coll_current
    
    if [info exists model_container_root] {
	set sh [$model_container_root getval body_shape]
	if {$sh != ""} {
	    set drawr [expr {($current_shape == "") && \
				 (![info exists coll_current] || \
				      ($coll_current == ""))}]
	    $sh before_draw_func $type_visible(names) $drawr
	}
    }
}

proc toggle_view_split_mode {} {
    global view_panes tdv_default tdv_highlight_frame is_win

    foreach f [array names tdv_highlight_frame] {
	# Otherwise we get an annoying red flash
	$tdv_highlight_frame($f) configure -bg #d9d9d9
    }
    switch $view_panes(mode) {
	1 {
	    pack forget $view_panes(horiz_pane)
	    pack $view_panes(viewer_one) -fill both -expand 1
	    
	    set view_panes(viewers) [list $view_panes(viewer_one)]
	    tdv_set_last_viewer_clicked $view_panes(viewer_one)
	    update
	}
	4 {
	    set pad [expr $is_win * 2]
	    set first [expr ![winfo exists $view_panes(horiz_pane)]]
	    if $first {
		PanedWindow $view_panes(horiz_pane) -side bottom \
		    -pad $pad -width 6
		
		set view_panes(vert_pane_left) \
		    [$view_panes(horiz_pane) add].left
		PanedWindow $view_panes(vert_pane_left) -side left \
		    -pad $pad -width 6
		pack $view_panes(vert_pane_left) -expand 1 -fill both
		
		set view_panes(vert_pane_right) \
		    [$view_panes(horiz_pane) add].right
		PanedWindow $view_panes(vert_pane_right) -side left \
		    -pad $pad -width 6
		pack $view_panes(vert_pane_right) -expand 1 -fill both
		
		set view_panes(viewer_left_top) \
		    [$view_panes(vert_pane_left) add].top
		set view_panes(viewer_left_bot) \
		    [$view_panes(vert_pane_left) add].bot
		set view_panes(viewer_right_top) \
		    [$view_panes(vert_pane_right) add].top
		set view_panes(viewer_right_bot) \
		    [$view_panes(vert_pane_right) add].bot
		
		make_one_graphics_window $view_panes(viewer_left_top) \
		    $tdv_default
		make_one_graphics_window $view_panes(viewer_left_bot) \
		    $tdv_default
		make_one_graphics_window $view_panes(viewer_right_top) \
		    $tdv_default
		make_one_graphics_window $view_panes(viewer_right_bot) \
		    $tdv_default
		foreach v {left_top right_top left_bot right_bot} {
		    $view_panes(viewer_$v) configure -active 0
		    pack $view_panes(viewer_$v) -expand 1 -fill both \
			-padx 1 -pady 1
		}
	    }
	    
	    pack forget $view_panes(viewer_one)
	    pack $view_panes(horiz_pane) -fill both -expand 1
	    
	    set view_panes(viewers) [list $view_panes(viewer_left_top) \
					 $view_panes(viewer_left_bot) \
					 $view_panes(viewer_right_top) \
					 $view_panes(viewer_right_bot)]
	    
	    tdv_set_last_viewer_clicked $view_panes(viewer_left_top)
	    
	    update
	    
	    if $first {
		tdv_isoview $view_panes(viewer_left_top)
		tdv_home $view_panes(viewer_left_bot) +y
		tdv_home $view_panes(viewer_right_top) -z
		tdv_home $view_panes(viewer_right_bot) +x
		
		foreach v {left_top right_top left_bot right_bot} {
		    $view_panes(viewer_$v) configure -active 1
		    $view_panes(viewer_$v) redraw
		}
		graph_set_ctrlkey
	    }
	}
    }
}

proc orient_home_command {} {
    global tdv_default
    tdv_home $tdv_default
}

proc orient_command {dir} {
    global tdv_default
    tdv_along_axis $tdv_default $dir
}

proc update_type_visible {t} {
    global tdv_default
    global type_visible
    
    switch $t {
	cad_line - cad_point {
	    foreach im [$tdv_default list_with_tag $t] {
		$im configure -visible $type_visible($t)
	    }
	}
	names {
	    model_graph_options_changed 0
	}
	default {
	    set v $type_visible($t)
	    foreach obj [db_list_objects $t] {
		make_visible $obj [expr {$v && [$obj si_value active]}]
		tree_changeactive_object $obj
	    }
	}
    }
}

proc graph_toggle_action {} {
    global graph_action_var action_after_id
    
    if $graph_action_var {
	after 100 graph_after_action
    } elseif [info exists action_after_id] {
	after cancel $action_after_id
	unset action_after_id
    }
}

proc view_toggle_auto_redraw {} {
    # something here
}

proc graph_after_action {} {
    global action_after_id
    
    foreach obj [db_list_objects] {
	set obtype [$obj getval obtype]
	if {[info command app_action_$obtype] != ""} {
	    app_action_$obtype $obj
	}
    }
    set action_after_id [after 100 graph_after_action]
}

proc graph_set_ctrlkey {} {
    global view_panes job_ctrlkey
    
    if {$job_ctrlkey != "Shift"} {
	foreach v $view_panes(viewers) {
	    tdv_selection_bindings2 $v $job_ctrlkey pick \
		anno_select_action anno_move_action anno_release_action
	}
    }
}

proc graphics_loc_command {} {
    global tdv_default view_panes tdv_last_viewer_clicked
    global tdv_waiting_for_click explicit_location_value get_only_endpoints
    global graphics_loc_track_mouse tdv_waiting_for_motion graphics_loc_xy
    global graphics_loc_button_pressed
    
    foreach w $view_panes(all_viewers) {
	bind $w <F9> "set tdv_waiting_for_click($w) F9"
    }
    bind .v <F9> "set tdv_waiting_for_click($tdv_last_viewer_clicked) F9"
    
    if [info exists graphics_loc_track_mouse] {
	set tdv_waiting_for_motion($tdv_default) 1
	tkwait variable tdv_waiting_for_motion
	set cc $tdv_waiting_for_motion($tdv_default)
	unset tdv_waiting_for_motion($tdv_default)
	if {$cc == ""} {
	    return ""
	} else {
	    return [lrange [$tdv_default get_3d_point [lindex $cc 0] \
				[lindex $cc 1] 1] 0 2]
	}
    }
    
    foreach w $view_panes(all_viewers) {
	set tdv_waiting_for_click($w) 1
    }
    tkwait variable tdv_waiting_for_click
    set vv $tdv_last_viewer_clicked
    set cc $tdv_waiting_for_click($vv)
    foreach w $view_panes(all_viewers) {
	unset tdv_waiting_for_click($w)
	bind $w <F9> ""
    }
    bind .v <F9> ""
    switch -- [lindex $cc 0] {
	e       { return [lrange $cc 1 end] }
	1       {
	    set is_inter [expr ![info exists get_only_endpoints]]
	    set pt [lrange [$vv get_3d_point [lindex $cc 1] \
				[lindex $cc 2] $is_inter] 0 2]
	    set explicit_location_value $pt
	    set graphics_loc_xy [lrange $cc 1 2]
	    return $pt
	}
	F9 {
	    bind $tdv_default <F9> "set tdv_waiting_for_click($vv) F9"
	    bind .v <F9> "set tdv_waiting_for_click($vv) F9"
	    tdv_cur $vv dynamics
	    tkwait variable tdv_waiting_for_click
	    tdv_cur $vv pick
	    return [graphics_loc_command]
	}
	default {
	    set graphics_loc_button_pressed [lindex $cc 0]
	    return ""
	}
    }
}

