/**
  * Retrieves the next assignee in the given project's round robin queue.
  *
  * @access  public
  * @param   integer $prj_id The project ID
  * @return  integer The assignee's user ID
  */
 function getNextAssignee($prj_id)
 {
     // get the full list of users for the given project
     list($blackout_start, $blackout_end, $users) = Round_Robin::getUsersByProject($prj_id);
     if (count($users) == 0) {
         return 0;
     } else {
         $user_ids = array_keys($users);
         $next_usr_id = 0;
         foreach ($users as $usr_id => $details) {
             if ($details['is_next']) {
                 $next_usr_id = $usr_id;
                 break;
             }
         }
         // if no user is currently set as the 'next' assignee,
         // then just get the first one in the list
         if (empty($next_usr_id)) {
             $next_usr_id = $user_ids[0];
         }
         // counter to keep the number of times we found an invalid user
         $ignored_users = 0;
         // check the blackout hours
         do {
             $user = new Date(Date_API::getCurrentUnixTimestampGMT());
             $user->convertTZById($users[$next_usr_id]['timezone']);
             list($today, $tomorrow) = Round_Robin::getBlackoutDates(&$user, $blackout_start, $blackout_end);
             $first = new Date($today . ' ' . $blackout_start);
             $first->setTZById($users[$next_usr_id]['timezone']);
             $second = new Date($tomorrow . ' ' . $blackout_end);
             $second->setTZById($users[$next_usr_id]['timezone']);
             if (Date::compare($first, $user) == -1 && Date::compare($user, $second) == -1) {
                 $ignored_users++;
                 $current_index = array_search($next_usr_id, $user_ids);
                 // if we reached the end of the list of users and none of them
                 // was a valid one, then just select the first one
                 // however, we want to complete at least one full iteration over the list of users
                 // that is, if we didn't start checking the users in the beginning of the list,
                 // then do another run over the users just in case
                 if ($ignored_users >= count($user_ids) && $current_index == count($user_ids) - 1) {
                     $assignee = $user_ids[0];
                     break;
                 }
                 // if we reached the end of the list, and we still didn't find an user,
                 // then go back to the beginning of the list one last time
                 if ($current_index == count($user_ids) - 1) {
                     $current_index = 0;
                     $next_usr_id = $user_ids[++$current_index];
                     $found = 0;
                     continue;
                 }
                 $next_usr_id = $user_ids[++$current_index];
                 $found = 0;
             } else {
                 $assignee = $next_usr_id;
                 $found = 1;
             }
         } while (!$found);
         // mark the next user in the list as the 'next' assignment
         $assignee_index = array_search($assignee, $user_ids);
         if ($assignee_index == count($user_ids) - 1) {
             $next_assignee = $user_ids[0];
         } else {
             $next_assignee = $user_ids[++$assignee_index];
         }
         Round_Robin::markNextAssignee($prj_id, $next_assignee);
         return $assignee;
     }
 }