class PlayerControllerArray extends Actor;

var array<KFPlayerController> playerControllersArray;
var string                    pcArrayNames;
var string                    pcArrayNamesUnfound;
var bool                      isNamesPlural; //for example "name1"=0; "name1, name2"=1; "All players"=1

var KFPlayerController        admin;

var KFPlayerController        currentPlayer;
var int                       currentPlayerNumber;

function private clean()
{
  if(playerControllersArray.length > 0)
    playerControllersArray.remove(0, playerControllersArray.length);
  pcArrayNames = "";
  pcArrayNamesUnfound = "";
  isNamesPlural = false;
  currentPlayer = none;
  currentPlayerNumber = 0;
}

function bool findPlayers(string inputNames)
{
  //iteration things
  local Controller c;
  local KFPlayerController kfpc;
  local int i;

  local array<string> nicknames;
  local array<int> ids;
  local array<byte> nicknamesFound; //yes, it should be "bool", but it doesn't work, ffs

  //buffer values
  local string idsString;
  local array<string> idsStringSplitted;

  clean();

  switch(inputNames)
  {
    case "":
      playerControllersArray[0] = admin;
      pcArrayNames = admin.playerReplicationInfo.playerName;
      break;

		case "all":
		case "ingame":
      for(c = level.controllerList; c != none; c = c.nextController)
      {
        kfpc = KFPlayerController(c);
        if(kfpc != none)
          if(kfpc.playerReplicationInfo != none)
            if(!kfpc.playerReplicationInfo.bOnlySpectator)
            {
              playerControllersArray[playerControllersArray.length] = kfpc;
            }
      }
      pcArrayNames = "All players";
      isNamesPlural = true;
      break;

    case "specs":
    case "spectators":
      for(c = level.controllerList; c != none; c = c.nextController)
      {
        kfpc = KFPlayerController(c);
        if(kfpc != none)
          if(kfpc.playerReplicationInfo != none)
            if(kfpc.playerReplicationInfo.bOnlySpectator)
            {
              playerControllersArray[playerControllersArray.length] = kfpc;
            }
      }
      pcArrayNames = "All spectators";
      isNamesPlural = true;
      break;

    case "everybody":
      for(c = level.controllerList; c != none; c = c.nextController)
      {
        kfpc = KFPlayerController(c);
        if(kfpc != none)
          playerControllersArray[playerControllersArray.length] = kfpc;
      }
      pcArrayNames = "Everybody (including spectators)";
      break;

    default:
      //filling array with nicknames which should be found
      split(caps(inputNames), ",", nicknames);

      //filling array with IDs
      for(i = nicknames.length - 1; i >= 0 ; i--)
      {
        //removing void names
        if(nicknames[i] == "")
          nicknames.remove(i, 1);

        if(left(caps(nicknames[i]), 3) == "ID:")
        {
          idsString = repl(nicknames[i], "ID", "")$idsString;
          nicknames.remove(i, 1);
        }
      }
      if(idsString != "")
      {
        split(idsString, ":", idsStringSplitted);

        for(i = 0; i < idsStringSplitted.length; i++)
        {
          //avoiding wrong typed IDs (with chars) and WebAdmin
          if(int(idsStringSplitted[i]) > 0)
            ids[ids.length] = int(idsStringSplitted[i]);
        }

        //DEBUG//////////////////////////////////////////
        /*
                  admin.teamMessage(none, "DEBUG INFORMATION (DETELE THIS BLOCK LATER)", 'AdminPlus');
                  admin.teamMessage(none, "  IDs:", 'AdminPlus');
                  for(i = 0; i < ids.length; i++)
                  {
                    admin.teamMessage(none, "    "$string(ids[i]), 'AdminPlus');
                  }
                  admin.teamMessage(none, "  NICKNAMES:", 'AdminPlus');
                  for(i = 0; i < nicknames.length; i++)
                  {
                    admin.teamMessage(none, "    "$nicknames[i], 'AdminPlus');
                  }
        */
        /////////////////////////////////////////////////
      }

      //just create array with the same length and fill it with 'false'
      nicknamesFound[nicknames.length - 1] = 0;

      //finding players
      for(c = level.controllerList; c != none; c = c.nextController)
      {
        kfpc = KFPlayerController(c);
        if(kfpc != none)
          if(kfpc.playerReplicationInfo != none)
          {
            //find player with nickname
            for(i = 0; i < nicknames.length; i++)
              if(inStr(caps(kfpc.playerReplicationInfo.playerName), nicknames[i]) >= 0)
              {
                if(!isPlayerInArray(kfpc))
                {
                  playerControllersArray[playerControllersArray.length] = kfpc;
                  if(playerControllersArray.length == 1)
                    pcArrayNames = kfpc.playerReplicationInfo.playerName;
                  else
                    pcArrayNames = pcArrayNames$","@kfpc.playerReplicationInfo.playerName;


                  //player with this nickaname was found
                  nicknamesFound[i] = 1;
                }

                //continue; (shouldn't do it, it will affect 'pcArrayNamesUnfound')
                //i.e. for example (it's player NikC- and input string was "ni, ik, john, nikc")
                //so 'ni', 'ik', and 'nikc' should be all checked as found (not just 'ni')
              }

            //find player with ID
            for(i = 0; i < ids.length; i++)
              if(kfpc.playerReplicationInfo.playerId == ids[i])
              {
                if(!isPlayerInArray(kfpc))
                {
                  playerControllersArray[playerControllersArray.length] = kfpc;
                  if(playerControllersArray.length == 1)
                    pcArrayNames = kfpc.playerReplicationInfo.playerName;
                  else
                    pcArrayNames = pcArrayNames $ "," @ kfpc.playerReplicationInfo.playerName;
                }

                continue;
              }
          }
      }

      for(i = 0; i < nicknames.length; i++)
      {
        if(nicknamesFound[i] == 0)
        {
          if(pcArrayNamesUnfound == "")
            pcArrayNamesUnfound = nicknames[i];
          else
            pcArrayNamesUnfound = pcArrayNamesUnfound $ ", " $ nicknames[i];
        }
      }

      if(playerControllersArray.length > 1)
        isNamesPlural = true;
  }

  if(playerControllersArray.length == 0)
    return false;

  return true;
}

function private bool isPlayerInArray(KFPlayerController inKfpc)
{
  local int i;

  for(i = 0; i < playerControllersArray.length; i++)
    if(playerControllersArray[i] == inKfpc)
      return true;

  return false;
}

function bool nextPlayer()
{
  if(playerControllersArray.length == 0)
    return false;

  //first cycle in "while(pca.nextPlayer){}" so "pca.currentPlayer()" will return 1st player
  if(currentPlayer == none && currentPlayerNumber == 0)
  {
    currentPlayer = playerControllersArray[0];
    return true;
  }

  if((currentPlayerNumber + 1) < playerControllersArray.length)
  {
    currentPlayerNumber++;
    currentPlayer = playerControllersArray[currentPlayerNumber];
    return true;
  }
  else
  {
    currentPlayer = none;
    return false;
  }
}

function KFPlayerController getCurrentPlayer()
{
  return currentPlayer;
}

function string getCurrentPlayerName()
{
  if(currentPlayer != none)
    if(currentPlayer.playerReplicationInfo != none)
      return class'Helper'.static.ParsePlayerName(currentPlayer);
}

function string getNames()
{
  return pcArrayNames;
}

function bool hasUnfoundPlayers()
{
  return pcArrayNamesUnfound != "";
}

function string getNamesUnfound()
{
  return pcArrayNamesUnfound;
}

function bool isPluralForm()
{
  return isNamesPlural;
}

function bool applyFilter(string filter)
{
  local int i;
  local bool bFilterApplied;

  //applying the filter:

  switch(filter)
  {
  case "hasPawn":
    for(i = playerControllersArray.length - 1; i >= 0; i--)
      if(playerControllersArray[i] == none || playerControllersArray[i].pawn == none)
      {
        playerControllersArray.remove(i, 1);
        bFilterApplied = true;
      }
    break;

  case "isSpectator":
    for(i = playerControllersArray.length - 1; i >= 0; i--)
      if(playerControllersArray[i] == none || playerControllersArray[i].playerReplicationInfo == none ||
         !playerControllersArray[i].playerReplicationInfo.bOnlySpectator)
      {
          playerControllersArray.remove(i, 1);
          bFilterApplied = true;
      }
    break;

  case "isInGame":
    for(i = playerControllersArray.length - 1; i >= 0; i--)
      if(playerControllersArray[i] == none || playerControllersArray[i].playerReplicationInfo == none ||
         playerControllersArray[i].playerReplicationInfo.bOnlySpectator)
      {
          playerControllersArray.remove(i, 1);
          bFilterApplied = true;
      }
    break;
  }

  if(!bFilterApplied)
    return playerControllersArray.length > 0;


  //
  //In case at least one player was deleted from player list
  //all information has to be refreshed
  //

  //reset
  currentPlayer = none;
  currentPlayerNumber = 0;

  //refreshing "pcArrayNames":

  pcArrayNames = "";

  for(i = 0; i < playerControllersArray.length; i++)
  {
    if(pcArrayNames == "")
      pcArrayNames = playerControllersArray[i].playerReplicationInfo.playerName;
    else
      pcArrayNames = pcArrayNames $ "," @ playerControllersArray[i].playerReplicationInfo.playerName;
  }

  if(playerControllersArray.length == 0)
    return false;

  //refreshing "isNamesPlural":

  isNamesPlural = playerControllersArray.length > 1;

  return true;
}

defaultproperties
{
  bHidden=true
}