--- chess.module.orig	2009-11-21 19:25:14.000000000 +0100
+++ chess.module	2009-11-26 20:41:42.000000000 +0100
@@ -32,6 +32,22 @@ define('CHESS_KING', 4);   // pieces: ki
 define('CHESS_PAWN', 5);   // pieces: pawn
 
 /**
+ * Implementation of hook_views_api().
+ *
+ * This tells drupal that there is Views integration file named 
+ * module-name.views.inc - uncomment to use!
+ */
+/*
+function chess_views_api() {
+  // Note that you can include 'path' in this array so that your views.inc 
+  // file can be stored in a different location.
+  return array(
+    'api' => 2.0
+  );
+}
+*/
+
+/**
  * Given a character representing a chess piece, return a numerical value to be stored in the database,
  * and vice versa...
  */
@@ -123,7 +139,17 @@ function chess_form(&$node, $form_state)
   $type = node_get_types('type', $node);
 
   // Need a list of all users, to allow the players to be chosen
-  $result = db_query("SELECT uid, name FROM {users} WHERE uid > 0 AND status = 1");
+  $result = db_query("
+    SELECT 
+      uid, 
+      name 
+    FROM 
+      {users} 
+    WHERE 
+      (uid > 0) 
+    AND 
+      (status = 1)
+    ");
 
   $users = array();
   while ($user = db_fetch_array($result)) {
@@ -186,7 +212,15 @@ function chess_form(&$node, $form_state)
  * TODO: EDIT HOOK UPDATE TO TAKE ACCOUNT OF PGN INPUT?
  */
 function chess_insert($node) {
-  db_query("INSERT INTO {chess} (nid, vid, user_white, user_black) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->white, $node->black);
+  db_query("
+    INSERT INTO 
+      {chess} (
+        nid, 
+        vid, 
+        user_white, 
+        user_black) 
+    VALUES (%d, %d, %d, %d)
+    ", $node->nid, $node->vid, $node->white, $node->black);
 
   $starting_chess_state = 'rd nd bd qd kd bd nd rd pd pd pd pd pd pd pd pd zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz zz pl pl pl pl pl pl pl pl rl nl bl ql kl bl nl rl';
   $starting_player = CHESS_LIGHT;
@@ -197,14 +231,25 @@ function chess_insert($node) {
     // decode the PGN, and change the values for $starting_chess_state, $starting_plater,
     // and $check (should never start a game in mate, but if it's in the standard, want to check for it.
     drupal_set_message($node->PGN_code);
-    /*	$result = PGN_decode($node->PGN_code);
- 	$starting_chess_state = $result[0];
- 	$starting_player = $result[1];
- 	$check = $result[2];
- 	$checkmate = $result[3];*/
-  }
-
-  db_query("INSERT INTO {chess_info} (game_id, user_white, user_black, current_board_state, next_move, check_, checkmate) VALUES (%d, %d, %d, '%s', '%s', %d, %d)", $node->nid, $node->white, $node->black, $starting_chess_state, $starting_player, $check, $checkmate);
+    /*  $result = PGN_decode($node->PGN_code);
+   $starting_chess_state = $result[0];
+   $starting_player = $result[1];
+   $check = $result[2];
+   $checkmate = $result[3];*/
+  }
+
+  db_query("
+    INSERT INTO 
+      {chess_info} (
+        game_id, 
+        user_white, 
+        user_black, 
+        current_board_state, 
+        next_move, 
+        check_, 
+        checkmate) 
+    VALUES (%d, %d, %d, '%s', '%s', %d, %d)
+    ", $node->nid, $node->white, $node->black, $starting_chess_state, $starting_player, $check, $checkmate);
 
 }
 
@@ -227,8 +272,22 @@ function chess_update($node) {
     chess_insert($node);
   }
   else {
-    db_query("UPDATE {chess} SET user_white = %d, user_black = %d  WHERE vid = %d", $node->white, $node->black, $node->vid);
-    db_query("UPDATE {chess_info} SET user_white = %d, user_black = %d", $node->white, $node->black);
+    db_query("
+      UPDATE 
+        {chess} 
+      SET 
+        user_white = %d, 
+        user_black = %d  
+      WHERE 
+        vid = %d
+      ", $node->white, $node->black, $node->vid);
+    db_query("
+      UPDATE 
+        {chess_info} 
+      SET 
+        user_white = %d, 
+        user_black = %d
+      ", $node->white, $node->black);
   }
 }
 
@@ -254,40 +313,73 @@ function chess_load($node) {
  */
 function chess_view($node, $teaser = FALSE, $page = FALSE) {
   global $user;
-  if (!$teaser) {
-    // Use Drupal's default node view.
-    $node = node_prepare($node, $teaser);
-
-    // Add The two players to the node view
-    $node->content['players'] = array(
-      '#value' => theme('chess_players', $node),
-      '#weight' => -4,
-    );
+  drupal_add_css(drupal_get_path('module', 'chess') . '/chess.css');
+  // Use Drupal's default node view.
+  $node = node_prepare($node, $teaser);
+  
+  // Add The two players to the node view
+  $node->content['players'] = array(
+    '#value' => theme('chess_players', $node),
+    '#weight' => -4,
+  );
 
-    if ($game_info = db_fetch_array(db_query("SELECT * FROM {chess_info} where game_id = %d", $node->nid))) {
-      // convert the result set into an array
+  // In the full-view ...
+  if (!$teaser) {
+    // Get the info about the current game
+    $game_info = db_fetch_array(db_query("
+      SELECT 
+        * 
+      FROM 
+        {chess_info} 
+      WHERE 
+        game_id = %d
+      ", $node->nid));
+    
+    // If we successfully got a game-info ...
+    if ($game_info) {
 
+      // Convert the result set into an array
       $next_move = $game_info['next_move'];
-      // check if the current user is in the array of player ids for this game
-      if ($user->uid == $game_info['user_white'])  {
 
-        if ($next_move == CHESS_LIGHT) {
-          $node->content['move_form'] = array('#value' => drupal_get_form('move_entry_form', $node, $game_info), '#weight' => 5, );
-        }
+      // Check whether to display move-form
+      if ((
+        ($user->uid == $game_info['user_white']) 
+        && 
+        ($next_move == CHESS_LIGHT)
+        ) 
+      || (
+        ($user->uid == $game_info['user_black']) 
+        && 
+        ($next_move == CHESS_DARK)
+        ))
+      {
+        $node->content['move_form'] = array(
+          '#value' => drupal_get_form('move_entry_form', $node, $game_info), 
+          '#weight' => 5
+        );
       }
-      if ($user->uid == $game_info['user_black']) {
-        if ($next_move == CHESS_DARK) {
-          $node->content['move_form'] = array('#value' => drupal_get_form('move_entry_form', $node, $game_info), '#weight' => 5, );
+      // Not showing move-form, so check for undo-form
+      elseif ($game_info['number_of_moves'] > 0) {
+        $user_black = $
+        // check if the last move was made by the current user
+        $last_mover = ($next_move == CHESS_LIGHT) ? $game_info['user_black'] : $game_info['user_white'];
+        if ($last_mover == $viewer) {
+          // allow the user to edit there last move...
+          $node->content['move_edit'] = array(
+            '#value' => drupal_get_form('move_undo_form', $node->nid), 
+            '#weight' => 6
+          );
         }
       }
+      // Finally, add the board itself
+      $node->content['chessboard'] = array(
+        '#value' => drupal_get_form('chessboard_form', $node, $game_info), 
+        '#weight' => 7, 
+      );
     }
   }
-  elseif ($teaser) {
-    // Use Drupal's default node view.
-    $node = node_prepare($node, $teaser);
-  }
   return $node;
-}
+} // chess_view
 
 /**
  * Implementation of hook_theme().
@@ -298,33 +390,53 @@ function chess_theme() {
   );
 }
 
-
 function theme_chess_players($node) {
   // discover player's names....
   $names = players_names($node);
 
   // whose move is next?
-  $next_to_move = db_result(db_query("SELECT next_move FROM {chess_info} WHERE game_id = %d", $node->nid));
+  $next_to_move = db_result(db_query("
+    SELECT 
+      next_move 
+    FROM 
+      {chess_info} 
+    WHERE 
+      game_id = %d
+    ", $node->nid));
 
   // output split in case I want to add anything after players names with regard to whose move it is... could also add
   // a div around the next to move player for theming purposes...
   $output = '<div class="chess-players"><strong>White:</strong> '. check_plain($names['0']);
   $output .= '<br />'.'<strong>Black:</strong> '. check_plain($names['1']);
-  $output .= '</div>	';
+  $output .= '</div>  ';
 
   if ($next_to_move == CHESS_LIGHT) {
-    $output .= "<h2>White to move</h2>";
+    $output .= "<h2>" . check_plain($names['0']);
   }
   else {
-    $output .= "<h2>Black to move</h2>";
+    $output .= "<h2>" . check_plain($names['1']);
   }
-  $output .= "<br />";
+  $output .= " to move</h2><br />";
   return $output;
 }
 
 function players_names($node) {
-  $names['0'] = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $node->user_white));
-  $names['1'] = db_result(db_query("SELECT name FROM {users} WHERE uid = %d", $node->user_black));
+  $names['0'] = db_result(db_query("
+    SELECT 
+      name 
+    FROM 
+      {users} 
+    WHERE 
+      uid = %d
+    ", $node->user_white));
+  $names['1'] = db_result(db_query("
+    SELECT 
+      name 
+    FROM 
+      {users} 
+    WHERE 
+      uid = %d
+    ", $node->user_black));
   return $names;
 }
 
@@ -369,46 +481,284 @@ function chess_admin_settings() {
 
   $form['chess_pieces_directory'] = array(
     '#type' => 'textfield',
-    '#title' => t('Chose the directory where chess pieces are located.'),
+    '#title' => t('Chess-Directory'),
     '#default_value' => variable_get('chess_pieces_directory', $chess_pieces_default_directory),
-    '#description' => t('Starts at this root: ') . $base_root . $base_path,
+    '#description' => t('Chose the directory where chess pieces are located. Starts at this root: ') . $base_root . $base_path,
+    '#required' => TRUE,
+  );
+  $form['allow_move_editing'] = array(
+    '#type' => 'select',
+    '#title' => t('Allow Undo'),
+    '#options' => array('TRUE' => t('True'), 'FALSE' => t('False')),
+    '#default_value' => variable_get('allow_move_editing', 'TRUE'),
+    '#description' => t('Allow a player to take back his last move (provided the other player has not made a move yet).'),
     '#required' => TRUE,
   );
-  $form['chess_width'] = array(
+  
+  // Fieldset for the random chess game block
+  $form['block'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Chessboard (Block)'),
+    '#collapsible' => TRUE, 
+    '#collapsed' => FALSE
+  );
+  $form['block']['chess_width_block'] = array(
     '#type' => 'textfield',
-    '#title' => t('Set the width of the chess pieces in pixels.'),
+    '#title' => t('Field-Width (Block)'),
     '#default_value' => variable_get('chess_width', '20'),
-    '#description' => t('The default value is 20 pixels, but you may need to change it for different themes'),
+    '#description' => t('Set the width of the chess pieces in pixels when viewing the block. The default value is 20 pixels, but you may need to change it for different themes.'),
     '#required' => TRUE,
   );
-  $form['chess_height'] = array(
+  $form['block']['chess_height_block'] = array(
     '#type' => 'textfield',
-    '#title' => t('Set the height of the chess pieces in pixels.'),
+    '#title' => t('Field-Height (Block)'),
     '#default_value' => variable_get('chess_height', '20'),
-    '#description' => t('The default value is 20 pixels, but you may need to change it for different themes'),
+    '#description' => t('Set the height of the chess pieces in pixels when viewing the block. The default value is 20 pixels, but you may need to change it for different themes.'),
     '#required' => TRUE,
   );
-  $form['number_previous_moves'] = array(
+  $form['block']['number_previous_moves_block'] = array(
     '#type' => 'textfield',
-    '#title' => t('Choose the number of previous moves to display in the secondary chess block'),
-    '#default_value' => variable_get('number_previous_moves', '5'),
-    '#description' => t('The default value is 5, but it\'s up to you'),
+    '#title' => t('Number of Previous Moves (Block)'),
+    '#default_value' => variable_get('number_previous_moves_block', '3'),
+    '#description' => t('Choose the number of previous moves to display in the random game block. Use 0 for all and -1 for non at all. The default value is 3, but it\'s up to you.'),
     '#required' => TRUE,
   );
-  $form['allow_move_editing'] = array(
-    '#type' => 'select',
-    '#title' => t('Allow a user to edit the last move they entered'),
-    '#options' => array('TRUE' => t('True'), 'FALSE' => t('False')),
-    '#default_value' => variable_get('allow_move_editing', 'TRUE'),
-    '#description' => t('Allow a player to edit his last move (provided the other player has not made a move)'),
+
+  // Fieldset for the node-display
+  $form['node'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Chessboard (Node)'),
+    '#collapsible' => TRUE, 
+    '#collapsed' => FALSE
+  );
+  $form['node']['chess_width_node'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Field-Width (Node)'),
+    '#default_value' => variable_get('chess_width_node', '44'),
+    '#description' => t('Set the width of the chess pieces in pixels to use when viewing the node. The default value is 44 pixels, but you may need to change it for different themes'),
+    '#required' => TRUE,
+  );
+  $form['node']['chess_height_node'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Field-Height (Node)'),
+    '#default_value' => variable_get('chess_height_node', '44'),
+    '#description' => t('Set the height of the chess pieces in pixels to use when viewing the node. The default value is 44 pixels, but you may need to change it for different themes'),
+    '#required' => TRUE,
+  );
+  $form['node']['number_previous_moves_node'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Number of Previous Moves (Node)'),
+    '#default_value' => variable_get('number_previous_moves_node', '20'),
+    '#description' => t('Choose the number of previous moves to display when viewing the node. Use 0 for all and -1 for non at all. The default value is 20, but it\'s up to you'),
     '#required' => TRUE,
   );
 
   $form['array_filter'] = array('#type' => 'hidden');
 
   return system_settings_form($form);
+} // chess_admin_settings
+
+/**
+ * Define the form for showing the board
+ */
+function chessboard_form($form_state, $node, $game_info) {
+  $generated_code = '';
+  $form['board'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Chessboard'),
+  );
+  $board_state = $game_info['current_board_state'];
+  // Get settings for the layout
+  $width = variable_get('chess_width_node', '44');
+  $height = variable_get('chess_height_node', '44');
+  $number_previous_moves = variable_get('number_previous_moves_node', '0');
+  // generate the code for the board
+  $generated_code .= '<div class="chess-board-with-recent">';
+  $generated_code .= '<div class="chess-board-with-recent-subcontainer">';
+  $generated_code .= generate_html_board($node->nid, $board_state, $width, $height);
+  // generate the code for the last moves
+  if ($number_previous_moves > -1) {
+    $generated_code .= '<div class="chess-recent-moves">';
+    $generated_code .= '<b>' . t('Last moves') . ':</b><br />';
+    $generated_code .= generate_html_last_moves($node->nid, $number_previous_moves);
+    $generated_code .= '</div>';
+  }
+  // Close the div for chess-board-with-recent
+  $generated_code .= '</div></div>';
+  // set the generated code as the content of the form
+  $form['board']['board_code'] = array(
+    '#type' => 'markup', 
+    '#value' => $generated_code
+  );
+  return $form;
+} // chessboard_form
+
+/**
+ *  Generate the HTML-code representing a random game
+ *
+ *  returns a string with the HTML-code
+ */
+function generate_html_random_game () {
+  $generated_code = '';
+  
+  // Get all accessible published chess-games
+  $all_chess_games = db_query(db_rewrite_sql("
+    SELECT
+      c.nid
+    FROM
+      {chess} c
+    JOIN
+      {node} n
+    ON
+      n.nid = c.nid
+    WHERE
+      n.status = 1"
+  ));
+  
+  // Get an array with just the nids
+  while ($game_to_check = db_fetch_array($all_chess_games)) { 
+    $accessible_games[] = $game_to_check['nid'];
+  }
+
+  // Choose a game and generate the HTML-code for it
+  if ($accessible_games) {
+    // Choose a game randomly
+    $random_game_number = rand(0,(count($accessible_games) - 1));
+    $nid = $accessible_games[$random_game_number];
+    // Fetch the board for the choosen game
+    $board_layout = db_fetch_array(db_query("
+      SELECT 
+        current_board_state 
+      FROM 
+        {chess_info} 
+      WHERE 
+        game_id = %d
+      ", $nid));
+
+    if (!empty($board_layout)) { 
+      $board_layout = $board_layout['current_board_state'];
+
+      // Get settings for the layout
+      $width = variable_get('chess_width_block', '20');
+      $height = variable_get('chess_height_block', '20');
+
+      // decode the board state and print based on that.
+      $generated_code .= generate_html_board($nid, $board_layout, $width, $height);
+
+      // Add the recent moves below the board
+      $number_previous_moves = variable_get('number_previous_moves_block', '3');
+      $generated_code .= generate_html_last_moves($nid, $number_previous_moves);
+    }
+    // We got an empty board, this is an error condition
+    else {
+      $generated_code = t('Error: The randomly choosen game was empty.');
+    }
+  }
+  // If there are no accessible games, return an empty block
+  else {
+    $generated_code = '';
+  }
+  return $generated_code;
 }
 
+
+/**
+ *  Generate the HTML-code representing the n last moves
+ *
+ * @param $nid The nid of the node for which to get the moves
+ * @param $number_previous_moves The number of moves to include
+ * 
+ * For $number_previous_moves 0 stands for unlimited
+ *
+ *  returns a string with the HTML-code
+ */
+function generate_html_last_moves ($nid, $number_previous_moves) {
+  $lastmoves_html_code = '';
+  // If $number_previous_moves is 0 we are supposed to fetch all
+  if ($number_previous_moves == 0) {
+    // Query all moves
+    $previous_moves = db_query("
+      SELECT 
+        * 
+      FROM 
+        {chess_games} 
+      WHERE 
+        game_id = %d 
+      ORDER BY 
+        move_number DESC
+      ", $nid);
+    
+  } else {
+    // Query the moves, limited to the number of moves we want to show
+    $previous_moves = db_query_range("
+      SELECT 
+        * 
+      FROM 
+        {chess_games} 
+      WHERE 
+        game_id = %d 
+      ORDER BY 
+        move_number DESC
+      ", $nid, 0, $number_previous_moves);
+    
+  }
+  // Compose the HTML-code
+  while ($move_row = db_fetch_array($previous_moves)) {
+    $lastmoves_html_code .= ($move_row['colour'] == CHESS_LIGHT) ? "White: " : "Black: ";
+    $lastmoves_html_code .= chess_piece_index($move_row['piece']);
+    $lastmoves_html_code .= chr(96 + $move_row['move_from_column']);  // an ascii character
+    $lastmoves_html_code .= $move_row['move_from_row'];
+    $lastmoves_html_code .= chr(96 +$move_row['move_to_column']);
+    $lastmoves_html_code .= $move_row['move_to_row'];
+    $lastmoves_html_code .= "<br />";
+  }
+  // Return the composed code
+  return $lastmoves_html_code;
+} // generate_html_last_moves
+
+function generate_html_outstanding_moves () {
+  $generated_code = '';
+  // Get all games where the current user is up for the next move
+  global $user;
+  $result = db_query("
+    SELECT 
+      ci.game_id, 
+      n.title 
+    FROM 
+      {chess_info} ci 
+    JOIN 
+      {node} n 
+    ON 
+      n.nid = ci.game_id 
+    WHERE 
+      (
+        (ci.user_white = %d AND ci.next_move = 0) 
+        OR 
+        (ci.user_black = %d AND ci.next_move = 1)
+      )
+      AND
+      (ci.checkmate = 0);
+    ", $user->uid, $user->uid);
+
+  // For each of those games, add a link
+  $game_info = array();
+  while ($game_info = db_fetch_array($result)) {
+    // If block is empty, initialise it and its html-list
+    if ($generated_code == '') {
+      $generated_code .= t('Your turn:');
+      $generated_code .= '<ul class="menu">';
+    }
+    // Add the link to the game
+    $generated_code .= '<li class="leaf"><a href="' . $base_root . '/?q=de/node/' . $game_info['game_id'] . '">' . $game_info['title'] . '</a></li>';
+  }
+  
+  // Add closure for the HTML-list if block not empty
+  if (!$generated_code == '') {
+      $generated_code .= '</ul>';
+  }
+  return $generated_code;
+} // generate_html_outstanding_moves
+
 /**
  * Define the form for entering a move.
  */
@@ -416,7 +766,7 @@ function move_entry_form($form_state, $n
 
   $form['move'] = array(
     '#type' => 'fieldset',
-    '#title' => t('Move'),
+    '#title' => t('Your Move'),
   );
   $form['move']['nid'] = array(
     '#type' => 'value',
@@ -503,7 +853,14 @@ function move_entry_form($form_state, $n
 function move_entry_form_submit($form, &$form_state) {
 
   $nid = $form_state['values']['nid'];  // node id - this references all chess game info
-  $result = db_query("SELECT * FROM {chess_info} WHERE game_id = %d", $nid);
+  $result = db_query("
+    SELECT 
+      * 
+    FROM 
+      {chess_info} 
+    WHERE 
+      game_id = %d
+    ", $nid);
   $game = db_fetch_array($result);
 
   global $user;
@@ -516,13 +873,14 @@ function move_entry_form_submit($form, &
     $next_mover = -1; // impossible to match uid
   }
 
-  if ($next_mover == $viewer) {  // MGN: This check doesn't appear to be necessary, though I am not sure why...
-
   // entry is allowed
+  if ($next_mover == $viewer) {  // MGN: This check doesn't appear to be necessary, though I am not sure why...
 
+    // Determine the number of this move
     $move_number = $game['number_of_moves'];
     $move_number++;
 
+    // Set up variables according to mover
     if ($game['next_move'] == CHESS_LIGHT) {
       $next_move = 'd';
       $db_next_move = CHESS_DARK;
@@ -532,17 +890,19 @@ function move_entry_form_submit($form, &
       $db_next_move = CHESS_LIGHT;
     }
 
+    // Update board state
     $current_board_state = $game['current_board_state'];
-    // update board state
 
+    // Get the from/to co-ordinates
     $column_from = (int)convert_co_ordinate($form_state['values']['piece_column_from']);
     $column_to = (int)convert_co_ordinate($form_state['values']['piece_column_to']);
-
     $row_from_co_ord = 8 - (int)$form_state['values']['piece_row_from'];
     $row_to_co_ord = 8 - (int)$form_state['values']['piece_row_to'];
 
-    // 3 chars per square =>
-    // equation below will give the start reference for the character being moved
+    // $board is the grid of all fields as a string with 
+    // zz rl pd pl ... => 3 chars per square (including the whitespace)
+    // Equation below will give the start reference for the character being moved
+    // in the grid of the board
     $blank_board_from_square = ( ($row_from_co_ord * 8) + $column_from - 1) * 3;
 
     $piece_code = drupal_substr($current_board_state, $blank_board_from_square, 2);
@@ -561,7 +921,7 @@ function move_entry_form_submit($form, &
     $new_piece_position = ( ($row_to_co_ord * 8) + $column_to - 1) * 3;
     $whats_in_the_location_being_moved_to = drupal_substr($current_board_state_1, $new_piece_position, 2);
 
-    if (legal_move($piece, $colour, $current_board_state_1, $column_from, $row_from_co_ord, $column_to, $row_to_co_ord)==1) {
+    if (legal_move($nid, $piece, $colour, $current_board_state_1, $column_from, $row_from_co_ord, $column_to, $row_to_co_ord)==1) {
       switch ($whats_in_the_location_being_moved_to) {
         case 'zz':
           $captured_piece = 0;
@@ -577,16 +937,78 @@ function move_entry_form_submit($form, &
       drupal_set_message(t('That is not a legal move.'));
       return;
     }
+
+    // Check if its a king moving to check if he's castling
+    if ($piece == 'k') {
+      // Calc the movement-delta
+      $delta_column = $column_from - $column_to;
+      // Has the king moved two fields? -> castle
+      if (abs($delta_column) == 2) {
+        // Determine the from/to-coordinates for the moving rook
+        // We can determine the affected rook by the color + movement-direction
+
+        // White king and rook are on row 1
+        if ($colour == 'l') {
+          $castle_row = 7;
+        // Black king and rook are on row 8
+        } else {
+          $castle_row = 0;
+        }
+        // If king moving right ...
+        if ($delta_column == -2) {
+          $castle_column_from = 8;
+          $castle_column_to = 6;
+        // If moving left ...
+        } elseif ($delta_column == 2) {
+          $castle_column_from = 1;
+          $castle_column_to = 4;
+        }
+
+        // Calc the grid-positions
+        $grid_position_from = (($castle_row * 8) + $castle_column_from - 1) * 3;
+        $grid_position_to = (($castle_row * 8) + $castle_column_to - 1) * 3;
+        
+        // Set the from- and to-fields in the new board-state
+        $new_board_state = substr_replace($new_board_state, 'zz', $grid_position_from, 2);
+        $new_board_state = substr_replace($new_board_state, ('r' . $colour), $grid_position_to, 2);
+      }  // King doing castle
+    } // King moving
+
+
     // check if a 'check' was selected, or a 'checkmate'
     // currently not working... not sure why
     $check = empty($form_state['values']['extra']['check']) ? 0 : 1;
     $checkmate = empty($form_state['values']['extra']['checkmate']) ? 0 : 1;
 
     // UPDATE THE {chess_info} DB
-    db_query("UPDATE {chess_info} SET current_board_state='%s', next_move=%d, number_of_moves=%d, check_=%d, checkmate=%d WHERE game_id=%d", $new_board_state, $db_next_move, $move_number, $check, $checkmate, $nid);
+    db_query("
+      UPDATE 
+        {chess_info} 
+      SET 
+        current_board_state='%s', 
+        next_move=%d, 
+        number_of_moves=%d, 
+        check_=%d, 
+        checkmate=%d 
+      WHERE 
+        game_id=%d
+      ", $new_board_state, $db_next_move, $move_number, $check, $checkmate, $nid);
 
     // ADD MOVE TO {chess_games} DB
-    db_query("INSERT INTO {chess_games} (game_id, piece, move_number, move_from_column, move_to_column, move_from_row, move_to_row, colour, captured_piece) VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)", $nid, chess_piece_index($piece), $move_number, $column_from, $column_to, (int)$form_state['values']['piece_row_from'], (int)$form_state['values']['piece_row_to'], $game['next_move'], $captured_piece);
+    db_query("
+      INSERT INTO 
+        {chess_games} (
+          game_id, 
+          piece, 
+          move_number, 
+          move_from_column, 
+          move_to_column, 
+          move_from_row, 
+          move_to_row, 
+          colour, 
+          captured_piece) 
+      VALUES (%d, %d, %d, %d, %d, %d, %d, %d, %d)
+      ", $nid, chess_piece_index($piece), $move_number, $column_from, $column_to, (int)$form_state['values']['piece_row_from'], (int)$form_state['values']['piece_row_to'], $game['next_move'], $captured_piece);
 
     drupal_set_message(t('Your move was saved.'));
   }
@@ -603,124 +1025,58 @@ function move_entry_form_submit($form, &
 function chess_block($op = 'list', $delta = 0) {
   switch ($op) {
     case 'list':
-      return _chess_block_list();
+      $block = array();
+      $block[0]['info'] = t('Chess - Outstanding Moves');
+      $block[1]['info'] = t('Chess - Random Chess Game');
+      return $block;
     case 'view':
-      return _chess_block_view($delta);
-  }
-}
-
-/**
- * Get the list of the blocks.
- *
- * @param
- *   none.
- *
- * @return
- *   array containing the title ("info") of the block.
- */
-function _chess_block_list() {
-  $block = array();
-  $block[0]['info'] = t('Chess');
-  $block[1]['info'] = t('Previous Moves');
-  $block[2]['info'] = t('Edit Last Move');
-  return $block;
-}
-
-/**
- * Get the output to be displayed by the block.
- *
- * @param
- *   $delta - integer for the block number.
- *
- * @return
- *   array containing the title ("subject") and content of the block.
- */
-function _chess_block_view($delta) {
-  $block = array();
-
-  switch ($delta) {
-    case 0:
-      $block['subject'] = t('Chess Board');
-
-      if (arg(0) == 'node' && is_numeric(arg(1))) {
-        $nid = arg(1); // current node id (nid)
-        $board_layout = db_fetch_array(db_query("SELECT current_board_state FROM {chess_info} WHERE game_id = %d", $nid));
-        if (!empty($board_layout)) {  // print board surround
-          $block['content'] .= top_surround();
-
-          $board_layout = $board_layout['current_board_state'];
-
-          // decode the board state and print based on that.
-          $block['content'] .= decode_board_layout($board_layout);
-        }
-        else {
-          //$block['content'] = "No Game was found";
-          //drupal_set_message(t('An Error has occured, the board could not be found.'));
-        }
-      }
-      break;
-    case 1:
-      $block['subject'] = t('Previous Moves');
-
-      if (arg(0) == 'node' && is_numeric(arg(1))) {
-        $nid = arg(1); // current node id (nid)
-        $number_previous_moves = variable_get('number_previous_moves', '5');
-
-        $previous_moves = db_query_range("SELECT * FROM {chess_games} WHERE game_id = %d ORDER BY move_number DESC", $nid, 0, $number_previous_moves);
-
-        while ($move_row = db_fetch_array($previous_moves)) {
-          $block['content'] .= ($move_row['colour'] == CHESS_LIGHT) ? "White: " : "Black: ";
-          $block['content'] .= chess_piece_index($move_row['piece']);
-          $block['content'] .= chr(96 + $move_row['move_from_column']);  // an ascii character
-          $block['content'] .= $move_row['move_from_row'];
-          $block['content'] .= chr(96 +$move_row['move_to_column']);
-          $block['content'] .= $move_row['move_to_row'];
-          $block['content'] .= "<br />";
-        }
-      }
-      break;
-    case 2:
-      $move_editing = variable_get('allow_move_editing', 'TRUE');
-      if ($move_editing) {
-        // block to display an edit for the previous move
-        if (arg(0) == 'node' && is_numeric(arg(1))) {
-          $nid = arg(1); // current node id (nid)
-
-          // determine if the user viewing this page is the person who made the last move...
-          global $user;
-          $viewer = $user->uid;
-          $result = db_query("SELECT * FROM {chess_info} WHERE game_id = %d", $nid);
-          $game = db_fetch_array($result);
-          if ($game['number_of_moves'] == 0) {
-            // do not display 'undo move' block, no moves have been made yet.
+      $block = array();
+      // Treat each block seperately
+      switch ($delta) {
+        
+        // The "Outstanding Moves" Block
+        case 0:
+          if ($block['content'] = generate_html_outstanding_moves()) {
+            $block['subject'] = t('Outstanding Chess Moves');
           }
-          else {
-            $last_mover = ($game['next_move'] == CHESS_LIGHT) ? $game['user_black'] : $game['user_white'];
-            if ($last_mover == $viewer) {
-              // allow the user to edit there last move...
-              $block['subject'] = t('Undo Your Previous Move');
-              $block['content'] .= drupal_get_form('move_edit_form', $nid);
-            }
+          break;
+
+        // The "Random Chess Game" Block
+        case 1:
+          // If there are games to show
+          if ($block['content'] = generate_html_random_game()) {
+            // Add the style-sheet
+            drupal_add_css(drupal_get_path('module', 'chess') . '/chess.css');
+            // Set the subject
+            $block['subject'] = t('Random Chess Game');
           }
-        }
+          break;
       }
-      break;
-    }
-
-  return $block;
+      return $block;
+  }
 }
 
-
 /**
  * Define the form for entering a move.
  */
-function move_edit_form(&$form_state, $nid) {
+function move_undo_form(&$form_state, $nid) {
   $form['nodeid'] = array( '#type' => 'hidden', '#value' => $nid);
 
+  $form['move_edit']['header'] = array(
+    '#type' => 'markup',
+    '#value' => '<div class="chess-undo">' . t('You can undo your last move: '),
+  );
+
   $form['move_edit']['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Undo Move'),
   );
+
+  $form['move_edit']['footer'] = array(
+    '#type' => 'markup',
+    '#value' => '</div>',
+  );
+
   return $form;
 }
 
@@ -729,17 +1085,26 @@ function move_edit_form(&$form_state, $n
  * change who's next move
  * save new board state
  */
-function move_edit_form_submit($form, &$form_state) {
+function move_undo_form_submit($form, &$form_state) {
 
   $nid = $form_state['values']['nodeid'];  // node id - this references all chess game info
 
-  // Update {chess_info} table....
-  $result = db_query("SELECT * FROM {chess_info} WHERE game_id = %d", $nid);
+  // Query {chess_info} table....
+  $result = db_query("
+    SELECT 
+      * 
+    FROM 
+      {chess_info} 
+    WHERE 
+      game_id = %d
+    ", $nid);
   $game = db_fetch_array($result);
 
+  // Get info about the current user
   global $user;
   $viewer = $user->uid;
 
+  // Determine if the current user made the last move
   $last_mover = ($game['next_move'] == CHESS_LIGHT) ? $game['user_black'] : $game['user_white'];
   if ($last_mover == $viewer) { // MGN: this check doesn't appear to be necessary, though I am not sure why
     // edit move is permitted...submit form
@@ -756,17 +1121,27 @@ function move_edit_form_submit($form, &$
       $db_next_move = CHESS_LIGHT;
     }
 
-    // update the board state
-    $result = db_query_range("SELECT * FROM {chess_games} WHERE game_id = %d ORDER BY move_number DESC", $nid, 0, 1);
-    $previous_move = db_fetch_array($result);
-
+    // Get the old state
     $current_board_state = $game['current_board_state'];
-
+    
+    // Get the move we are un-doing
+    $result = db_query_range("
+      SELECT 
+        * 
+      FROM 
+        {chess_games} 
+      WHERE 
+        game_id = %d 
+      ORDER BY 
+        move_number DESC
+      ", $nid, 0, 1);
+    $previous_move = db_fetch_array($result);
     $column_from = $previous_move['move_from_column'];
     $column_to = $previous_move['move_to_column'];
     $row_from = 8 - $previous_move['move_from_row'];
     $row_to = 8 - $previous_move['move_to_row'];
-
+    $piececode = $previous_move['piece'];
+    // Calculate position in board-string
     $moved_to = ( ($row_to * 8) + $column_to - 1) * 3;
     /* *****************************************************************
      * $moved_to now contains the position in the board that (the start of it)
@@ -787,7 +1162,7 @@ function move_edit_form_submit($form, &$
     /* *****************************************************************
      * $moved_from contains the position where the piece was moved from.
      * **************************************************************** */
-    $undo_move = chess_piece_index($previous_move['piece']) . $next_move;
+    $undo_move = chess_piece_index($piececode) . $next_move;
     /* *****************************************************************
      * $undo_move contains the piece code and the colour of that piece
      * *****************************************************************/
@@ -798,16 +1173,72 @@ function move_edit_form_submit($form, &$
     $check = 0;
     $checkmate = 0;
 
-    // DELETE THE LINE FROM THE {chess_games} table
-    db_query("DELETE FROM {chess_games} WHERE game_id = %d AND move_number = %d", $nid, ($move_number+1));
+    // Check if the move we are undoing was a castle
+    if ($piececode == CHESS_KING) {
+      // Calc the movement-delta
+      $delta_column = $column_from - $column_to;
+      // Has the king moved two fields? -> castle
+      if (abs($delta_column) == 2) {
+        // Determine the from/to-coordinates for the rook to undo
+        // We can determine the affected rook by the color + movement-direction
+
+        // White king and rook are on row 7
+        if ($next_move == 'l') {
+          $castle_row = 7;
+        // Black king and rook are on row 0
+        } else {
+          $castle_row = 0;
+        }
+        // If king has moved right ...
+        if ($delta_column == -2) {
+          $castle_column_from = 6;
+          $castle_column_to = 8;
+        // If moving left ...
+        } elseif ($delta_column == 2) {
+          $castle_column_from = 4;
+          $castle_column_to = 1;
+        }
 
-    db_query("UPDATE {chess_info} SET current_board_state='%s', next_move=%d, number_of_moves=%d, check_=%d, checkmate=%d WHERE game_id=%d", $old_board_state, $db_next_move, $move_number, $check, $checkmate, $nid);
+        // Calc the grid-positions
+        $grid_position_from = (($castle_row * 8) + $castle_column_from - 1) * 3;
+        $grid_position_to = (($castle_row * 8) + $castle_column_to - 1) * 3;
+        
+        // Set the from- and to-fields in the new board-state
+        $old_board_state = substr_replace($old_board_state, 'zz', $grid_position_from, 2);
+        $old_board_state = substr_replace($old_board_state, ('r' . $next_move), $grid_position_to, 2);
+      }  // King doing castle
+    } // King moving
+
+    // DELETE the line from table {chess_games}
+    db_query("
+      DELETE FROM 
+        {chess_games} 
+      WHERE 
+        game_id = %d 
+      AND 
+        move_number = %d
+      ", $nid, ($move_number+1));
+
+    // ... and UPDATE the line from table {chess_games} with the restored
+    // board-state
+    db_query("
+      UPDATE 
+        {chess_info} 
+      SET 
+        current_board_state='%s', 
+        next_move=%d, 
+        number_of_moves=%d, 
+        check_=%d, 
+        checkmate=%d 
+      WHERE 
+        game_id=%d
+      ", $old_board_state, $db_next_move, $move_number, $check, $checkmate, $nid);
 
+    // Inform the user
     drupal_set_message(t('Your move was undone.'));
   }
+  // the other player has already moved - don't allow the edit!
   else {
-    // the other player has already moved - don't allow the edit!
-
     $last_colour = ($last_mover == $game['user_white']) ? 'White' : 'Black';
     drupal_set_message(t('Sorry, move cannot be edited since %colour has already moved.', array('%colour' => $last_colour)));
   }
@@ -824,108 +1255,184 @@ function convert_co_ordinate($value) {
 }
 
 /**
- * Prints out the column letters on the top of the board... called before anything else.
- *
- */
-function top_surround() {
-  $block_content = '';
-
-  global $base_path;
-  global $base_root;
-
-  $chess_pieces_default_directory = drupal_get_path('module', 'chess') ."/pieces";
-  $chess_directory = $base_root . $base_path . variable_get('chess_pieces_directory', $chess_pieces_default_directory);
-
-  $width = variable_get('chess_width', '20');
-  $height = variable_get('chess_height', '20');
-
-  $htmlbegin = "<img src=\"". $chess_directory ."/surround/";
-  $htmlmid = ".png\" alt=\"";
-  $htmlend = " height=\"". $height ." width=\"". $width ."\"/>";
-
-  $block_content .= $htmlbegin .'blank'. $htmlmid .'chess board'. $htmlend;
-
-  foreach ( $cols = range ('a', 'h') as $col) {
-    $block_content .= $htmlbegin . $col . $htmlmid .'chess board column '. $col . $htmlend;
-  }
-  return $block_content;
-}
-
-/**
- * Call this if a bottom surround is required... last call for block['content']
- */
-function bottom_surround() {
-  // nothing at the moment
-  $block_content = '';
-  return $block_content;
-}
-
-/**
  * Decodes the board layout code and returns the correct layout, ready to be added to the block content (i.e. html for image tiles)
  *
- * $board_code is the encoded layout for the board
- * The following values are allowed: rd, rl, nd, nl, bd, bl, qd, ql, kd, kl, pd, pl, zz
- * Key: r - rook, n - knight, b - bishop, q - queen, k - king, p - pawn
+ * @param $nid The nid (and therefore game_id) of the board to draw
+ * @param $board_code is the encoded layout for the board
+ * @param $width The width in pixels to use for each square
+ * @param $height The height in pixels to use for each square
+ *
+ * The following values are allowed in the field-code: 
+ * rd, rl, nd, nl, bd, bl, qd, ql, kd, kl, pd, pl, zz
+ * ... using the following keys: 
+ * r - rook, n - knight, b - bishop, q - queen, k - king, p - pawn
  * d - dark, l - light
- * zz - empty space
+ * and
+ * zz - for an empty space
+ * 
+ * returns a string containing the generated HTML code
  */
-function decode_board_layout($board_code) {
-  $block_content = '';
-
+function generate_html_board($nid, $board_code, $width, $height) {
+  $generated_html_code = '';
+  $generated_html_code = '<div class="chess-board">';
+  
+  // Compose the path to the images for fields/pieces
   global $base_path;
   global $base_root;
   $chess_pieces_default_directory = drupal_get_path('module', 'chess') ."/pieces";
-
   $chess_directory = $base_root . $base_path . variable_get('chess_pieces_directory', $chess_pieces_default_directory);
-  $width = variable_get('chess_width', '20');
-  $height = variable_get('chess_height', '20');
 
+  // Determine id of current user and if we need to rotate he board
+  $rotate = FALSE;
+  global $user;
+  $viewer = $user->uid;
+  $result = db_query("
+    SELECT 
+      ci.user_black
+    FROM {chess_info} ci 
+    WHERE 
+      (ci.game_id = %d);
+    ", $nid);
+  $game_info = array();
+  if (($game_info = db_fetch_array($result)) && ($game_info['user_black'] == $viewer)) {
+      $rotate = TRUE;
+  }
+  
+  // Get the previous move to set according tags for theming
+  $from_piece_code = 0;
+  $to_piece_code = 0;
+  $result = db_query_range("
+    SELECT * 
+    FROM {chess_games} 
+    WHERE game_id = %d 
+    ORDER BY move_number DESC
+    ", $nid, 0, 1);
+  // If there was a move already determine piece_code for its from and to fields
+  if ($previous_move = db_fetch_array($result)) {
+    $from_column = $previous_move['move_from_column'];
+    $from_row = 8 - $previous_move['move_from_row'];
+    $from_piece_code = (8 * $from_row) - 1 + $from_column;
+    $to_column = $previous_move['move_to_column'];
+    $to_row = 8 - $previous_move['move_to_row'];
+    $to_piece_code = (8 * $to_row) - 1 + $to_column;
+    // If rotate convert the codes accordingly
+    if ($rotate) {
+      $from_piece_code = 63 - $from_piece_code;
+      $to_piece_code = 63 - $to_piece_code;
+    }
+  }
+  
+  // Add the header-letter-row with A .. H for the columns
+  $generated_html_code .= generate_html_board_letterrow($chess_directory, $rotate, $width, $height);
+  
+  // Iterate over all fields ...
   $row = 1;
-  for ($i=0;$i < 64;$i++) {
+  $board_html_code = '';
+  for ($i=0; $i < 64; $i++) {
+    // If at the beginning of a new line, print a row number
     if ($i % 8 == 0) {
-      // print a row number
-      $block_content .= "<br />"; // new line
-      $block_content .= row_numbers($row);
+      // First line? Then just start a new div ...
+      if ($board_html_code == '') {
+        $board_html_code .= '<div class="chess chess-row">';
+      // on following lines we need to clos the div of the row
+      } else {
+        $board_html_code .= '</div><div class="chess chess-row">';
+      }
+      if ($rotate) {
+        $row_number_converted = $row;
+      } else {
+        $row_number_converted = 9 - $row;
+      }
+      $board_html_code .= '<img src="' . $chess_directory . '/surround/'
+        . $row_number_converted . '.png" alt="Row number ' 
+        . $row_number_converted . '" height="' . $height . '" width="' 
+        . $width . '" class="chess"/>';
       $row++;
     }
-    // extract the code for the current board location
-    $piece_code = drupal_substr($board_code, 0, 2);
-    // remove the code just extracted from the string
-    $board_code = drupal_substr($board_code, 3);
-
-    // standard information for each board location/piece
-    $block_content .= "<img src=\"". $chess_directory ."/pieces/Chess_";
-    $block_content .= $piece_code;
-    $block_content .= square_colour($i);
-    $block_content .= "44.png\" alt=";
-    $block_content .= "\"chess\""; // decode chess piece and put a specific text here?
-    $block_content .= "height=\"". $height ."\" width=\"". $width ."\"/>";
-  }
-  return $block_content;
-}
+    
+    // Extract the piece code from the board code taking into account
+    // rotation
+    if ($rotate) {
+      // extract the code for the current board location
+      $piece_code = substr($board_code, strlen($board_code) - 2, 2);
+      // remove the code just extracted from the string
+      $board_code = substr($board_code, 0, strlen($board_code) - 3);
+    } else {
+      // extract the code for the current board location
+      $piece_code = substr($board_code, 0, 2);
+      // remove the code just extracted from the string
+      $board_code = substr($board_code, 3);
+    }
+    
+    // add the image for each field
+    $board_html_code .= '<img'
+      . ' src="' . $chess_directory . '/pieces/Chess_' . $piece_code . square_colour($i) . '44.png"'
+      . ' alt="chess"';
+    if (intval($i) == intval($from_piece_code)) {
+      $board_html_code .= ' class="chess chess-lastmove-from"'
+      . ' height="'. ($height - 2) . '"'
+      . ' width="'. ($width - 2) . '"';
+    } elseif (intval($i) == intval($to_piece_code)) {
+      $board_html_code .= ' class="chess chess-lastmove-to"'
+      . ' height="'. ($height - 2) . '"'
+      . ' width="'. ($width - 2) . '"';
+    } else {
+      $board_html_code .= ' class="chess"'
+      . ' height="'. $height . '"'
+      . ' width="'. $width . '"';
+    }
+    $board_html_code .= ' />';
+  } // End of iteration over fields
+  // End the div for the row left open in the loop
+  $board_html_code .= '</div>';
+  
+  $generated_html_code .= $board_html_code;
+  
+  // Add the footer-row with the letters for the columns
+  $generated_html_code .= generate_html_board_letterrow($chess_directory, $rotate, $width, $height);
+  $generated_html_code .= '</div>';
+  // Return the generated code
+  return $generated_html_code;
+} // generate_html_board
 
 /**
- * Prints out the row numbers
- * $row_number = the row number (quelle surprise!)
- * row numbers count down from 8 to 1
+ * Generate the HTML-Code for the header/footer row of the board
+ * 
+ * @param $rotate Whether to rotate the board (TRUE/FALSE)
+ * @param $width The width in pixels to use for each square
+ * @param $height The height in pixels to use for each square
+ * 
+ * returns a string containing the generated HTML code
  */
-function row_numbers($row_number) {
-  global $base_path;
-  global $base_root;
-  $chess_pieces_default_directory = drupal_get_path('module', 'chess') ."/pieces";
-
-  $chess_directory = $base_root . $base_path . variable_get('chess_pieces_directory', $chess_pieces_default_directory);
-  $width = variable_get('chess_width', '20');
-  $height = variable_get('chess_height', '20');
-
-  $row_number_converted = 9 - $row_number;
-
-  $block_content = "<img src=\"". $chess_directory ."/surround/". $row_number_converted .".png\" alt=\"Row number ". $row_number_converted ."\" height=\"". $height ."\" width=\"". $width ."\"/> ";
-  return $block_content;
-}
+function generate_html_board_letterrow ($chess_directory, $rotate, $width, $height) {
+  $generated_letterrow_code = '';
+  
+  // Define HTML-Code-Parts to use in the loop
+  $htmlbegin = '<img src="' . $chess_directory . '/surround/';
+  $htmlmid = '.png" alt="Chess-Board Column ';
+  $htmlend = '" height="' . $height . '" width="' . $width . '" class="chess" />';
+  
+  // Start the row
+  $generated_letterrow_code .= '<div class="chess chess-row">';
+  // Add the blank image at the beginning of the row
+  $generated_letterrow_code .= $htmlbegin .'blank'. $htmlmid .'Empty Corner'. $htmlend;
+  // Add images for a-h
+  if ($rotate) {
+    foreach ( $cols = range ('h', 'a') as $col) {
+      $generated_letterrow_code .= $htmlbegin . $col . $htmlmid . $col . $htmlend;
+    }
+  } else {
+    foreach ( $cols = range ('a', 'h') as $col) {
+      $generated_letterrow_code .= $htmlbegin . $col . $htmlmid . $col . $htmlend;
+    }
+  }
+  $generated_letterrow_code .= '</div>';
+  return $generated_letterrow_code;
+} // generate_html_board_letterrow
 
 /**
  * Returns whether the square currently being printed is dark or light in colour
+ * 
  * $square_number - the number of the square, the top left starts at 0... i.e.:
  * 0 1 2 3 4 5 6 7
  * 8 9 10 11 12
@@ -946,10 +1453,19 @@ function square_colour($square_number) {
 /**
  *  Determine if a move is allowed or not
  *
- *  returns TRUE if the move is legal, FALSE otherwise
+ * @param $nid The nid (and therefore game_id)
+ * @param $piece The type of the moving piece
+ * @param $colour The colour of the moving piece
+ * @param $board The board state the move takes place in
+ * @param $cf The FROM-column of the move
+ * @param $rf The FROM-row of the move
+ * @param $ct The TO-column of the move
+ * @param $rt THE FROM-column of the move
+ *
+ * returns TRUE if the move is legal, FALSE otherwise
  */
 
-function legal_move($piece, $colour, $board, $cf, $rf, $ct, $rt) {
+function legal_move($nid, $piece, $colour, $board, $cf, $rf, $ct, $rt) {
 
   $rf = 8 - $rf;  //convert back to game coordinates so its easier to think about it - revert later.
   $rt = 8 - $rt;
@@ -1006,7 +1522,7 @@ function legal_move($piece, $colour, $bo
       case 'b':
         $adeltar = abs($deltar);
         $adeltac = abs($deltac);
-        if (($deltac != 0) && ($adeltac == $adeltar)) { // along a diagonal	
+        if (($deltac != 0) && ($adeltac == $adeltar)) { // along a diagonal  
           $dirr = ($deltar > 0) ? 1 : -1;
           $dirc = ($deltac > 0) ? 1 : -1;
           if (clear_path($cf, $rf, $dirc, $dirr, $adeltac - 1, $board)) {
@@ -1017,19 +1533,76 @@ function legal_move($piece, $colour, $bo
       case 'k':
         // TODO: a king cannot move into check .. we will check for this in the main routine, not here.
 
-        // TODO: a king that hasn't moved can castle provided...
-        // The king has not been moved earlier in the game.
-        // The rook that castles has not been moved earlier in the game.
-        // there are no pieces standing between king and rook.
-        // the king is not in check.
-        // The king doesn't move through a square that is attacked by a piece of the opponent.
-        // The king would be in check after castling.
-        // recognize a castle whenever deltac = +/- 2
-
         $adeltar = abs($deltar);
         $adeltac = abs($deltac);
+        // King is allowed to move one field per default
         if ((($adeltar == 1) && ($adeltac == 0)) || (($adeltar == 0) && ($adeltac == 1)) || (($adeltar == 1) && ($adeltac == 1))) {
           return TRUE;
+        // If the king is moving over two columns (and 0 rows) it's doing a castle
+        } elseif (($adeltar == 0) && ($adeltac == 2)) {
+          // DONE: recognize a castle whenever deltac = +/- 2
+          // DONE: a king that hasn't moved can castle provided...
+          // DONE: The king has not been moved earlier in the game.
+          // DONE: The rook that castles has not been moved earlier in the game.
+          // DONE: there are no pieces standing between king and rook.
+          // TODO: the king is not in check.
+          // TODO: The king doesn't move through a square that is attacked by a piece of the opponent.
+          // TODO: The king would be in check after castling.
+          
+          // (1) Check if there is something between the king and the rook
+
+          // If king moving right check path for two fieds
+          if ($deltac == -2) {
+            $path_check_distance = 2;
+          // If king moving left check path for three fields
+          } else {
+            $path_check_distance = 3;
+          }
+          // If path not clear, exit with message
+          if (!(clear_path($nid, $cf, $rf, 1, 0, $path_check_distance, $board))) {
+            drupal_set_message('Castle not allowed - there is something in the way!');
+            return FALSE;
+          }
+
+          // (2) Check that neither the king nor the rook have been moved before
+
+          // If king moving right check rook at column 8
+          if ($deltac == -2) {
+            $rook_check_column = 8;
+          // If king moving left check rook at column 1
+          } else {
+            $rook_check_column = 1;
+          }
+ 
+          // Query not allowed moves
+          $castle_check_not_allowed_moves = db_query_range("
+            SELECT 
+              move_number 
+            FROM 
+              {chess_games} 
+            WHERE 
+              (game_id = %d)
+            AND
+              (colour = %d)
+            AND
+              (
+                (piece = %d)
+              OR
+                (
+                  (piece = %d)
+                AND
+                  (move_from_column = %d)
+                )
+              )
+            ", $nid, $colour, CHESS_KING, CHESS_ROOK, $rook_check_column);
+          // If not allowed moves are found, exit with message
+          if ($not_allowed_moves = db_fetch_array($castle_check_not_allowed_moves)) {
+            drupal_set_message('Castle not allowed - king or rook has been moved already!');
+            return FALSE;
+          }
+          
+          // No obsticles found, so castle is allowed
+          return TRUE;
         }
         break;
       case 'q':
@@ -1062,7 +1635,6 @@ function legal_move($piece, $colour, $bo
  * @param $nstep is the number of steps to try
  * @param $board is the board layout
  *
- * 
  * @return TRUE if the path is clear
  *
  * Note: Coordinates are game coordinates not display coordinates
