#!/usr/bin/tclsh
# OpenVerse Server Program
# Modified by Andy Goth <unununium@openverse.org>
# Now it runs a GothChess room!
# 
#
# Module Name		- GothChess server program
# Current Maintainter 	- Andy Goth <unununium@openverse.org>
# Sourced By		- Command Line Or Client
#
# Copyright (C) 1999 David Gale <cruise@openverse.org>
# For more information visit http://OpenVerse.org/
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
# USA.

# Description of "chess" variables

# chess(initial_time)        - time each player has on his clock when the game starts
# chess(chess_timer_running) - 1 if the timer is ticking or 0 if it is paused
# chess(chess_timer_id)      - the id of the chess_timer proc
# chess(turn)                - which player goes next (0 if the game is stopped)
# chess(startstop_active)    - who requested either a gmae start or a draw
# chess(piece_index)         - the index of the currently selected piece (-1 means no selection)
# chess(anim_timer_count)    - how many anim timers have been used]
# chess(undo_stack)          - an undo stack for checking whether the king is threatened
# chess(promotion)           - index of piece to be promoted (-1 means unavailable)
# chess(en_passant_index)    - index of a piece that can be captured via en passant (-1 means en passant not possible)
# chess(en_passant_x)        - x coordinate of en passant capture zone (-1 means unavailable)
# chess(en_passant_y)        - y coordinate of en passant capture zone (-1 means unavailable)

# chess(board.[x].[y])
#
# A easy way of finding which piece is on a square
# Sort of a cross-reference into the pieces array
#
# Subelements
# -----------
# owner - owner of the piece, either 1 or 2; 0 means empty
# index - index of the piece; -1 means empty

# chess(pieces.[owner].[index])
#
# This array holds the location and status of all the pieces
# Owner is either 1 or 2
# Index is a number from 0 to 15
#
# Subelements
# -----------
# type      - what kind of piece (can be rook, knight, bishop, queen, or king)
# img       - the gif image for the piece
# in_play   - is it on the board or has it been captured?
# x         - x location (on board, 0 - 7; off board, 0 - 3)
# y         - y location (on board, 0 - 7; off board, 0 - 3)
# has_moved - has it moved yet?  (used for castling and pawn jumpstart)

# chess(players.[which])
#
# Which is either 1 or 2
#
# Subelements
# -----------
# sock         - socket
# name         - name
# time         - time remaining on chess counter, in seconds
# is_missing   - has the player disappeared?  (allows him to reconnect)
# num_captured - how many pieces this player captured

global chess MVS

# game_start
#
# Starts a GothChess game
proc game_start {} {
    global chess

    # Setup and show the board
    set chess(players.1.num_captured) 0
    set chess(players.2.num_captured) 0
    delete_all_pieces "all"
    initialize_board
    show_all_pieces "all"

    # Officially start the game
    set chess(turn) 1
    set chess(promotion) -1

    # Maybe start the timer
    if {$chess(initial_time) > 0} {
	reset_chess_timers
	show_chess_timer "all" "all"
	start_chess_timer
    }

    # Indicate which player is up
    show_active_player "all"

    # Put the players on top again
    send_to_all_users "ABOVE $chess(players.1.name)"
    send_to_all_users "ABOVE $chess(players.2.name)"
}

# game_end outcome
#
# Stops a GothChess game (victory conditions in $outcome)
proc game_end {outcome} {
    global MVS chess

    # Stop timers
    if {$chess(chess_timer_running) == 1} {
	stop_chess_timer
    }

    # Fix up the screen
    if {$chess(piece_index) > -1} {
	# Something's selected; clear the selection circle
	if {[expr ($chess(pieces.$chess(turn).$chess(piece_index).x) & 1) ^ ($chess(pieces.$chess(turn).$chess(piece_index).y) & 1)] == 0} {
	    set img "light_default.gif"
	} else {
	    set img "dark_default.gif"
	}
	send_to_user $chess(players.$owner.sock) "IMAGE square_$chess(pieces.$chess(turn).$chess(piece_index).x)_$chess(pieces.$chess(turn).$chess(piece_index).y) [expr $x_old * 60 + 30] [expr $y_old * 60 + 30] $img [file size "$MVS(images)/$img"] 0"
	unset img
    }
    if {$MVS(users) == 2} {
	# If there are now two players, enable the Start Game button
	show_button "all" "start"
    } else {
	# Either one or zero users; disable Start Game
	show_button "all" "start_disabled"
    }
    show_chess_timer "all" "all"

    # Officially end the game
    set chess(turn) 0
    set chess(startstop_active) 0
    set chess(piece_index) -1
    clear_undo_stack
    set chess(promotion) -1
    set chess(en_passant_index) -1
    set chess(en_passant_x) -1
    set chess(en_passant_y) -1
    reset_chess_timers

    # Kill all missing players
    if {$chess(players.1.is_missing) == 1} {
	set chess(players.1.sock) 0
	set chess(players.1.name) ""
	set chess(players.1.is_missing) 0
	set chess(players.1.num_captured) 0
    }
    if {$chess(players.2.is_missing) == 1} {
	set chess(players.2.sock) 0
	set chess(players.2.name) ""
	set chess(players.2.is_missing) 0
	set chess(players.2.num_captured) 0
    }
    show_names "all"
    show_active_player "all"

    unset outcome
}

# end_turn
#
# Ends the current player's turn
proc end_turn {} {
    global chess MVS

    # Update variables
    set chess(turn) [expr 3 - $chess(turn)]

    # Update displays
    show_active_player "all"
}

# Source other modules that GothChess requires
source "misc.tcl"
source "chess_timer.tcl"
source "display.tcl"
source "events.tcl"
source "board.tcl"
source "initialization.tcl"
source "server.tcl"
