# -----------------------------------------------------------------
# --- file:        automap
# --- date:        11 Jun. 2000
# --- revised by:  $Author: moth $
# --- revised on:  $Date: 2001/09/24 12:08:32 $
# --- author:      Selim Issever
# --- email:       selim@issever.de
# --- mud name:    Basternae 2
# --- mud ip/port: basternae.org 6666
# --- mud base:    diku
# --- comments:    This scriptfile sets up aliases and actions
# ---              such that the map will automatically build,
# ---              while scouting thrue the mud.
# ---
# ---              Turn on automapping:  automap on
# ---              Turn off automapping: automap off
# ---              Toggle automapping:   automap 
# ---              
# ---              Please take care, that a map exists.
# ---              This script does not automatically detect doors,
# ---              though it should be possible.
# -----------------------------------------------------------------

# To configure for your mud, change this proc.  Currently, it's
# looking for lines like  "Exits: north south up"

::proc _automap_test_exit {direction line} {
    ::variable _automap
    ::set l {[[:<:]]}	;# left side of word
    ::set r {[[:>:]]}   ;# right side of word
    ::return [::regexp "^Exits: .*$l$direction$r" $line]
}

######################################################################
#     Variable _automap will keep the needed stat information
::variable       _automap 
::set            _automap(elc)    black
::set            _automap(elt)    2
::set            _automap(scale)  1
::smm::gui::set   automap         0  
::catch {::smm::gui::addrow smmutil}
::catch {::smm::gui::addcheckbutton smmutil automap "automap " automap _automap}
# TODO: add gui elements for color [elc], thickness [elt] and scale.

# --- The procedure 'automap' will turn on/off automapping
#     The procedure take one argument, which will be -1,
#     if not provided.
#     If the argument is '1' or '0' automapping will be turned
#     on or off, every other value will toggle.
::proc automap {{sw -1}} {
    ::switch -- $sw {
	0 { _automap_off }
	1 { _automap_on }
	default { 
	    ::switch -- [::smm::gui::get automap] {
		0 { _automap_on }
		1 { _automap_off }
	    }
	}
    }
}
::proc _automap {} {
    automap [::smm::gui::get automap]
}
::proc automap_scale {scale} {
    ::variable _automap
    ::if {0 < [::expr 0 + $scale]} {
    	# if we get here, scale is a positive number
	_automap_showme "Changing automap room distance from $_automap(scale) to $scale"
	::set _automap(scale) $scale
    }
}
::proc automap_elt {elt} {
    ::variable _automap
    ::if {0 < [::expr 0 + $elt]} {
    	# if we get here, elt is a positive number
	_automap_showme "Changing automap line thickness from $_automap(elt) to $elt"
	::set _automap(elt) $elt
    }
}
::proc automap_elc {elc} {
    ::variable _automap
    _automap_showme "Changing automap color from $_automap(elc) to $elc"
    ::set _automap(elc) $elc
}


# --- helpers
::proc _automap_on {} {
    ::smm::gui::set automap 1 
    ::smm::option devmode 1
    ::smm::action::set _automapper 5
    _automap_showme "Automapping: ON!"
}
::proc _automap_off {} {
    ::smm::gui::set automap 0
    ::smm::action::unset _automapper
    _automap_showme "Automapping: OFF"
}
::proc _automap_showme {text} {
    ::smm::showme $text {FGred BGyellow FNbold}
    ::smm::showme "\n"
}


::proc _automap_exit {dir cmd map lev x y} {
    ::variable _automap
    ::smm::map::zoom setexit $dir $cmd $map $lev $x $y $x $y \
	0 {} {} $_automap(elt) $_automap(elc)
}

# --- action procedures
::proc _automapper {line} {
    # first check, if the room exists, if yes don't change it
    ::set n [::smm::map::get playername]
    ::set l [::smm::map::get playerlevel]
    ::set x [::smm::map::get playerx]
    ::set y [::smm::map::get playery]
    ::if {![::smm::map::exists room $n $l $x $y]} {
	::variable _automap
	::set d $_automap(scale)

	::if {[_automap_test_exit north $line]} {
	    _automap_exit nc north {} {} $x [::expr $y + $d]
	}
	::if {[_automap_test_exit south $line]} {
	    _automap_exit sc south {} {} $x [::expr $y - $d]
	}
	::if {[_automap_test_exit west $line]} {
	    _automap_exit cw west {} {} [::expr $x - $d] $y
	}
	::if {[_automap_test_exit east $line]} {
	    _automap_exit ce east {} {} [::expr $x + $d] $y
	}
	::if {[_automap_test_exit northwest $line]} {
	    _automap_exit nw northwest {} {} [::expr $x - $d] [::expr $y + $d]
	}
	::if {[_automap_test_exit northeast $line]} {
	    _automap_exit ne northeast {} {} [::expr $x + $d] [::expr $y + $d]
	}
	::if {[_automap_test_exit southwest $line]} {
	    _automap_exit sw southwest {} {} [::expr $x - $d] [::expr $y - $d]
	}
	::if {[_automap_test_exit southeast $line]} {
	    _automap_exit se southeast {} {} [::expr $x + $d] [::expr $y - $d]
	}
	::if {[_automap_test_exit up $line]} {
	    _automap_exit uo up $n [::expr $l + 1] $x $y
	}
	::if {[_automap_test_exit down $line]} {
	    _automap_exit do down $n [::expr $l - 1] $x $y
	}
    }
    # let other code look at this line, too..
    ::return 0
}


# requirements for new and improved automapper:
# [1] need user callback to implement mud-specific identification of
# room name, description
# [2] advanced: need mechanisms for dealing with getting lost.  Basic
# mechanism: need user callback or gui mechanism to be able
# to indicate unknown position.
# [3] need display mechanisms: toggle description area on/off: toggles
# for room description, room notes (manually entered), toggle saying room
# isn't unique
# [4] need a strategy for dealing with conflicting rooms at same position
# -- Selim suggests just finding a nearby empty square and using that
# [5] need to be able to toggle automapping.
# [6] for automapping, need to be able to tell when we move
#     movement commands [automatically recognize room's movement commands?]
#     teleportation/summoning/etc. [mud specific recognition]
#     flee/escape
#     until then, change of room without knowing exit should turn off automap
#         optional: until we know where we are
#     provide user callback to let user specify exit or absence of exit?
#    
# [7] support for conditional exits.  These will play hell with potential
# optimizations of speedwalk, but precomputed paths across map can still
# be used as bounds on length [maybe have an upper bound, with no conditionals
# active and a lower-bound with all conditionals active].
#     [*] conditional exit UIF: basic: allow user to enter name of condition
#     and give user checkbox for each significant condition
