
# wall struct, as described in the FAQ-World
struct wall {
  start
  end
  texture
  freg
  breg
  xscale
  yscale
  xphase
  yphase
}

proc UpdateWallTexture { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set wall($wnum) [lreplace $wall($wnum) 2 2 $default(texture)]
	}
    }
}


proc UpdateWallRegion { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set wall($wnum) [lreplace $wall($wnum) 3 4 \
			     $default(freg) $default(breg)]
	}
    }
}

proc UpdateWallScales { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set wall($wnum) [lreplace $wall($wnum) 5 6 \
			     $default(xscale) $default(yscale)]
	}
    }
}

proc UpdateWallPhases { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set wall($wnum) [lreplace $wall($wnum) 7 8 \
			     $default(xphase) $default(yphase)]
	}
    }
}

proc DrawWall { canvas wnum } {
    global scale vertex wall
    set v1 [lindex $wall($wnum) 0]
    set v2 [lindex $wall($wnum) 1]
    $canvas create line \
	[expr [lindex $vertex($v1) 0]*$scale] \
	[expr [lindex $vertex($v1) 1]*$scale] \
	[expr [lindex $vertex($v2) 0]*$scale] \
	[expr [lindex $vertex($v2) 1]*$scale] \
	-fill blue \
	-arrow last \
	-tags "[format w%d $wnum] wall"
    $canvas raise vertex
}


proc CreateWall { canvas v1 v2 tname rback rfore xs ys xp yp } {
    global vertex scale wall windex p1 p2
    set wall($windex) [list $v1 $v2 $tname $rback $rfore $xs $ys $xp $yp]
    lappend p1($v1) $windex
    lappend p2($v2) $windex
    DrawWall $canvas $windex
    incr windex
}

proc DeleteWall { canvas } {
    global vertex scale wall windex p1 p2
    global selection
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    $canvas delete [lindex $tags 0]
	    set wnum [GetNumber [lindex $tags 0]]
	    set v1 [lindex $wall($wnum) 0]
	    set v2 [lindex $wall($wnum) 1]
	    lvarpop p1($v1) [lsearch $p1($v1) $wnum]
	    lvarpop p2($v2) [lsearch $p2($v2) $wnum]
	    incr windex -1
	    for { set i $wnum } { $i<$windex } { incr i } {
		set wall($i) $wall([expr $i+1])
		set w [format w%d [expr $i+1]]
		set tags [$canvas gettags $w]
		$canvas itemconf $w \
		    -tags [lreplace $tags 0 0 [format w%d $i]]
	    }
	    unset wall([expr $windex])
	}
    }
}

proc ConnectPoints { canvas } {
    global vfirst vprev cline default
    set tags [$canvas gettags [$canvas find withtag current]]
    if { "[lindex $tags 1]"=="vertex" } {
	set vnum [string range [lindex $tags 0] 1 end]
	if { ![info exists vfirst] } {
	    set vfirst [lindex $tags 0]
	    set vprev $vfirst
	    set coords [$canvas coords $vprev]
	    set x1 [expr [lindex $coords 0]+3]
	    set y1 [expr [lindex $coords 1]+3]
	    set cline [$canvas create line $x1 $y1 $x1 $y1 \
			   -tags connect]
	    bind $canvas <Motion> "ConnectDrag $canvas %x %y"
	} else {
	    $canvas delete connect
	    set vnext [lindex $tags 0]
	    CreateWall $canvas \
		[GetNumber $vprev] \
		[GetNumber $vnext] \
		$default(texture) \
		$default(freg) $default(breg) \
		$default(xscale) $default(yscale) \
                $default(xphase) $default(yphase)
	    if { "$vnext"=="$vfirst" } {
		unset vfirst
		unset vprev
		follow_mouse .edit.canvas 1
	    } else {
		set vprev $vnext
		set coords [$canvas coords $vprev]
		set x1 [expr [lindex $coords 0]+3]
		set y1 [expr [lindex $coords 1]+3]
		set cline [$canvas create line $x1 $y1 $x1 $y1 \
			   -tags connect]
		bind $canvas <Motion> "ConnectDrag $canvas %x %y"
	    }
	}
    }
}

proc ConnectDrag { canvas x y } {
    set coords [$canvas coords connect]
    $canvas coords connect [lindex $coords 0] [lindex $coords 1] \
	[$canvas canvasx $x] [$canvas canvasy $y]
    $canvas raise connect
    $canvas raise vertex
}

proc FlipWall { canvas } {
    global selection wall p1 p2
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set v1 [lindex $wall($wnum) 0]
	    set v2 [lindex $wall($wnum) 1]
	    set wall($wnum) [lreplace $wall($wnum) 0 1 $v2 $v1]
	    lvarpop p1($v1) $wnum
	    lvarpop p2($v2) $wnum
	    lappend p1($v2) $wnum
	    lappend p2($v1) $wnum
	    $canvas delete [format w%d $wnum]
	    DrawWall $canvas $wnum
	}
    }
}

proc SplitWall { canvas wnum vnum } {
    global wall p1 p2 default
    set w $wall($wnum)
    set end [lindex $w 1]
    lvarpop p2($end) [lsearch $p2($end) $wnum]
    lappend p2($vnum) $wnum
    set wall($wnum) [lreplace $w 1 1 $vnum]
    $canvas delete [format w%d $wnum]
    DrawWall $canvas $wnum
    CreateWall $canvas $vnum $end \
	$default(texture) \
	$default(freg) $default(breg) \
	$default(xscale) $default(yscale) \
	$default(xphase) $default(yphase)
}

proc WallHeight { w } {
    global region
    set floor [lindex $region([wall-freg $w]) 0]
    set ceil [lindex $region([wall-freg $w]) 1]
    return [expr $ceil-$floor]
}

proc WallVisibleHeight { w } {
    global region
    set fheight [WallHeight $w]
    set floor [lindex $region([wall-breg $w]) 0]
    set ceil [lindex $region([wall-breg $w]) 1]
    set bheight [expr $ceil-$floor]
    if { $fheight>$bheight } {
	return [expr $fheight-$bheight]
    } else {
	return [expr $bheight-$fheight]
    }
}

proc WallLength { w } {
    global vertex
    set x1 [lindex $vertex([wall-start $w]) 0]
    set x2 [lindex $vertex([wall-end $w]) 0]
    set y1 [lindex $vertex([wall-start $w]) 1]
    set y2 [lindex $vertex([wall-end $w]) 1]
    return [expr sqrt(($x2-$x1)*($x2-$x1)+($y2-$y1)*($y2-$y1))]
}

proc WallInfo { win wnum } {
    global vertex wall region
    set w $wall($wnum)
    $win insert insert "Start: [wall-start $w] End: [wall-end $w]\n"
    $win insert insert "Texture: [wall-texture $w]\n"
    $win insert insert "Front: [wall-freg $w] ($region([wall-freg $w]))\n"
    $win insert insert "Back: [wall-breg $w] ($region([wall-breg $w]))\n"
    $win insert insert "xscale: [wall-xscale $w] yscale: [wall-yscale $w]\n"
    $win insert insert "xphase: [wall-xphase $w] yphase: [wall-yphase $w]\n"
    $win insert insert "length: [WallLength $w]\n"
    $win insert insert "height: [WallHeight $w]\n"
    $win insert insert "visible height: [WallVisibleHeight $w]\n"
}


proc SetWallYTile { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set vheight [WallVisibleHeight $wall($wnum)]
	    set wall($wnum) [lreplace $wall($wnum) 6 6 [expr 1.0/$vheight]]
	}
    }
}

proc SetWallXTile { canvas } {
    global selection default wall
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set vheight [WallVisibleHeight $wall($wnum)]
	    set width [WallLength $wall($wnum)]
	    set xscale [expr 1.0/$width]
#	    set xscale [expr $vheight/$width*[wall-yscale $wall($wnum)]]
	    set wall($wnum) [lreplace $wall($wnum) 5 5 $xscale ]
	}
    }
}

proc AlignWallBottom { canvas } {
    global selection default wall region
    if {[info exists selection]} {
	set tags [$canvas gettags $selection]
	if {"[lindex $tags 1]"=="wall"} {
	    set wnum [GetNumber [lindex $tags 0]]
	    set w $wall($wnum)
	    set yoff [expr [lindex $region([wall-freg $w]) 0]*1.0]
	    set height [WallVisibleHeight $w]
	    set wall($wnum) [lreplace $w 8 8 [expr -$yoff*[wall-yscale $w]]]
	}
    }
}

