class a_WeaponManager extends a_ActorBase
  config(HideMutWeapons);

// when exit save weapon list as "CurrentWeaponList"

// clean me on destroy!!!
var() KFPlayerController kfpc;
var() HideMutInteraction interaction;

var() config bool bUseVanillaManagement;
var() config bool bFastWeaponChanging;

// server preset basic support
struct serverPreset
{
  var string gameMode;
  var string weaponPreset;
  var string serverName;
  var bool bUseVanillaManagement;
};
var() config array<serverPreset> serverPresets;

var() array<string> weaponGroup1;
var() array<string> weaponGroup2;
var() array<string> weaponGroup3;
var() array<string> weaponGroup4;
var() array<string> weaponGroup5;
var() array<string> weaponGroup6;
var() array<string> weaponGroup7;
var() array<string> weaponGroup8;
var() array<string> weaponGroup9;
var() array<string> allUsedWeapons;


// self cleanup, coz simple Destroy aint enough
function Termination()
{
  // remove all refs
  kfpc = none;
  interaction = none;
  clearAllGroups();

  super.Termination();
}


event postBeginPlay()
{
  super.postBeginPlay();

  forEach allObjects(class'HideMutInteraction', interaction)
    break;

  loadWeaponList("CurrentWeaponList");

  if (serverPresets.length > 0)
    checkGameType();
}


final protected function checkGameType()
{
  local GameReplicationInfo tempGri;
  local int i;
  local bool highestPriority;
  local bool newBUseVanillaManagement;
  local bool bFoundMatchingPreset;
  local string newPreset;

  foreach allActors(class'GameReplicationInfo', tempGri)
  {
    for (i = 0; i < serverPresets.length; i++)
    {
      if (tempGri.gameClass == serverPresets[i].gameMode)
      {
        // if server name is defined, this preset has higher priority (highestPriority = true)
        if (serverPresets[i].serverName != "")
        {
          if (inStr(caps(tempGri.serverName), caps(serverPresets[i].serverName)) != -1)
          {
            newBUseVanillaManagement = serverPresets[i].bUseVanillaManagement;

            if (serverPresets[i].weaponPreset != "")
              newPreset = serverPresets[i].weaponPreset;

            highestPriority = true;
            bFoundMatchingPreset = true;
          }
        }
        // if we found preset matching gameType and server name, we should skip presets without server name
        else if (!highestPriority)
        {
          newBUseVanillaManagement = serverPresets[i].bUseVanillaManagement;

          if (serverPresets[i].weaponPreset != "")
            newPreset = serverPresets[i].weaponPreset;

          bFoundMatchingPreset = true;
        }
      }
    }
  }

  if (bFoundMatchingPreset)
  {
    bUseVanillaManagement = newBUseVanillaManagement;
    if (newPreset != "")
      loadWeaponList(newPreset);
  }
}


simulated function saveWeaponList(string listName)
{
  local list_WeaponManager new_WeaponList;

  new_WeaponList = new(none, listName) class'list_WeaponManager';
  new_WeaponList.clearConfig();

  new_WeaponList.weaponGroup1 = weaponGroup1;
  new_WeaponList.weaponGroup2 = weaponGroup2;
  new_WeaponList.weaponGroup3 = weaponGroup3;
  new_WeaponList.weaponGroup4 = weaponGroup4;
  new_WeaponList.weaponGroup5 = weaponGroup5;
  new_WeaponList.weaponGroup6 = weaponGroup6;
  new_WeaponList.weaponGroup7 = weaponGroup7;
  new_WeaponList.weaponGroup8 = weaponGroup8;

  new_WeaponList.saveConfig();
}


simulated function loadWeaponList(string listName)
{
  local list_WeaponManager new_WeaponList;

  clearAllGroups();

  new_WeaponList = new(none, listName) class'list_WeaponManager';

  weaponGroup1 = new_WeaponList.weaponGroup1;
  weaponGroup2 = new_WeaponList.weaponGroup2;
  weaponGroup3 = new_WeaponList.weaponGroup3;
  weaponGroup4 = new_WeaponList.weaponGroup4;
  weaponGroup5 = new_WeaponList.weaponGroup5;
  weaponGroup6 = new_WeaponList.weaponGroup6;
  weaponGroup7 = new_WeaponList.weaponGroup7;
  weaponGroup8 = new_WeaponList.weaponGroup8;
  updateUnusedWeapons();
}


simulated function deleteWeaponList(string listName)
{
  local list_WeaponManager new_WeaponList;

  new_WeaponList = new(none, listName) class'list_WeaponManager';

  new_WeaponList.clearConfig();
}


final function hide_getWeapon(byte groupNumber)
{
  local Inventory inv;
  local int i, currentWeapon;
  local array<string> loc_weaponGroup;

  if (kfpc.pawn == none || kfpc.pawn.inventory == none)
    return;

  switch (groupNumber)
  {
    case 1:
      loc_weaponGroup = weaponGroup1;
      break;
    case 2:
      loc_weaponGroup = weaponGroup2;
      break;
    case 3:
      loc_weaponGroup = weaponGroup3;
      break;
    case 4:
      loc_weaponGroup = weaponGroup4;
      break;
    case 5:
      loc_weaponGroup = weaponGroup5;
      break;
    case 6:
      loc_weaponGroup = weaponGroup6;
      break;
    case 7:
      loc_weaponGroup = weaponGroup7;
      break;
    case 8:
      loc_weaponGroup = weaponGroup8;
      break;
    case 9:
      loc_weaponGroup = weaponGroup9;
      break;
    // fallback
    default:
      loc_weaponGroup = weaponGroup1;
  }

  if (loc_weaponGroup.length == 0)
    return;

  currentWeapon = -1;

  for (i = 0; i < loc_weaponGroup.length; i++)
  {
    if (string(kfpc.pawn.weapon.class) ~= loc_weaponGroup[i])
    {
      currentWeapon = i;
      break;
    }
  }

  if (currentWeapon < loc_weaponGroup.length - 1)
  {
    for (i = currentWeapon + 1; i < loc_weaponGroup.length; i++)
    {
      for (inv = kfpc.pawn.inventory; inv != none; inv = inv.inventory)
      {
        if (string(inv.class) ~= loc_weaponGroup[i])
        {
          kfpc.pawn.pendingWeapon = Weapon(inv);
          if (bFastWeaponChanging)
            kfpc.pawn.changedWeapon();
          else
            kfpc.pawn.weapon.putDown();
            return;
        }
      }
    }
  }

  for (i = 0; i < currentWeapon; i++)
  {
    for (inv = kfpc.pawn.inventory; inv != none; inv = inv.inventory)
    {
      if (string(inv.class) ~= loc_weaponGroup[i])
      {
        kfpc.pawn.pendingWeapon = Weapon(inv);
        if(bFastWeaponChanging)
          kfpc.pawn.changedWeapon();
        else
          kfpc.pawn.weapon.putDown();
        return;
      }
    }
  }
  return;
}


// quickest way to self heal
simulated function reallyQuickHeal()
{
  local Inventory inv;
  local Weapon oldWeapon;

  if (kfpc == none || kfpc.pawn == none || kfpc.pawn.inventory == none)
    return;

  for (inv = kfpc.pawn.inventory; inv != none; inv = inv.inventory)
  {
    if (ClassIsChildOf(inv.class, class'Syringe'))
    {
      oldWeapon = kfpc.pawn.weapon;
      kfpc.pawn.pendingWeapon = Weapon(inv);
      kfpc.pawn.changedWeapon();
      // Syringe(kfpc.pawn.weapon).HackClientStartFire();
      Syringe(kfpc.pawn.weapon).serverStartFire(1);
      kfpc.pawn.pendingWeapon = oldWeapon;
      // kfpc.pawn.changedWeapon();
      kfpc.pawn.weapon.putDown();
    }
  }
}


simulated function fullReset()
{
  local KFLevelRules kflr;

  clearAllGroups();

  foreach kfpc.dynamicActors(class'KFLevelRules', kflr)
  {
    break;
  }

  if (kflr == none)
  {
    kfpc.clientMessage("Can't access KFLevelRules. You are probably not in game.");
    return;
  }

  parseItemForSale(kflr.mediItemForSale);
  parseItemForSale(kflr.suppItemForSale);
  parseItemForSale(kflr.shrpItemForSale);
  parseItemForSale(kflr.commItemForSale);
  parseItemForSale(kflr.bersItemForSale);
  parseItemForSale(kflr.fireItemForSale);
  parseItemForSale(kflr.demoItemForSale);
  parseItemForSale(kflr.neutItemForSale);
  // hardcode big nono
  weaponGroup5[weaponGroup5.length] = "KFmod.Syringe";
  weaponGroup5[weaponGroup5.length] = "KFmod.Welder";
  updateUnusedWeapons();

  prioritySortGroup(weaponGroup1);
  prioritySortGroup(weaponGroup2);
  prioritySortGroup(weaponGroup3);
  prioritySortGroup(weaponGroup4);
}


simulated function basicCleaning()
{
  local Inventory inv;
  local array<class<Pickup> > inventoryWeapons;

  clearAllGroups();

  if (kfpc.pawn.inventory == none)
  {
    kfpc.clientMessage("This function requires you inventory.(Needs Pawn)");
    return;
  }

  for (inv = kfpc.pawn.inventory; inv != none; inv = inv.inventory)
  {
    if (KFWeapon(inv) != none)
    {
      inventoryWeapons[inventoryWeapons.length] = KFWeapon(inv).pickupClass;
    }
  }

  parseItemForSale(inventoryWeapons);
  updateUnusedWeapons();
}


simulated function fullCleaning()
{
  clearAllGroups();
  updateUnusedWeapons();
}


// part of fullReset()
simulated function parseItemForSale(array<class<Pickup> > itemForSale)
{
  local int i;
  local class<KFWeapon> tempKFWeapon;

  for (i = 0; i < itemForSale.length; i++)
  {
    tempKFWeapon = class<KFWeapon>(itemForSale[i].default.inventoryType);
    // failsafe
    if (tempKFWeapon == none)
      continue;

    if (tempKFWeapon.default.inventoryGroup == 1)
    {
      weaponGroup1[weaponGroup1.length] = string(tempKFWeapon);
      continue;
    }
    if (tempKFWeapon.default.inventoryGroup == 2)
    {
      weaponGroup2[weaponGroup2.length] = string(tempKFWeapon);
      continue;
    }
    if (tempKFWeapon.default.inventoryGroup == 3)
    {
      weaponGroup3[weaponGroup3.length] = string(tempKFWeapon);
      continue;
    }
    if (tempKFWeapon.default.inventoryGroup == 4)
    {
      weaponGroup4[weaponGroup4.length] = string(tempKFWeapon);
      continue;
    }
    if (tempKFWeapon.default.inventoryGroup == 5)
    {
      weaponGroup5[weaponGroup5.length] = string(tempKFWeapon);
      continue;
    }
  }
}


// part of fullReset()
simulated function prioritySortGroup(out array<string> weaponGroup)
{
  local int i,j;
  local string tempString;
  local class<KFWeapon> tempKFWeapon1, tempKFWeapon2;

  for (i = 0; i < weaponGroup.length; i++)
  {
    for (j = i; j < weaponGroup.length; j++)
    {
      tempKFWeapon1 = class<KFWeapon>(dynamicLoadObject(weaponGroup[i], class'Class', true));
      tempKFWeapon2 = class<KFWeapon>(dynamicLoadObject(weaponGroup[j], class'Class', true));
      if (tempKFWeapon1.default.priority < tempKFWeapon2.default.priority)
      {
        tempString = weaponGroup[i];
        weaponGroup[i] = weaponGroup[j];
        weaponGroup[j] = tempString;
      }
    }
  }
}


simulated function clearAllGroups()
{
  weaponGroup1.remove(0, weaponGroup1.length);
  weaponGroup2.remove(0, weaponGroup2.length);
  weaponGroup3.remove(0, weaponGroup3.length);
  weaponGroup4.remove(0, weaponGroup4.length);
  weaponGroup5.remove(0, weaponGroup5.length);
  weaponGroup6.remove(0, weaponGroup6.length);
  weaponGroup7.remove(0, weaponGroup7.length);
  weaponGroup8.remove(0, weaponGroup8.length);
  weaponGroup9.remove(0, weaponGroup9.length);
}


simulated function updateUnusedWeapons()
{
  local KFLevelRules kflr;
  local array<class<Pickup> > welderSyringe;

  updateAllUsedWeapons();

  foreach dynamicActors(class'KFLevelRules', kflr)
  {
    break;
  }

  if (kflr == none)
  {
    if (kfpc != none)
      kfpc.clientMessage("Can't access KFLevelRules. You are probably not in game.");
    return;
  }

  weaponGroup9.remove(0, weaponGroup9.length);
  updateUnusedWeapons_Internal(kflr.mediItemForSale);
  updateUnusedWeapons_Internal(kflr.suppItemForSale);
  updateUnusedWeapons_Internal(kflr.shrpItemForSale);
  updateUnusedWeapons_Internal(kflr.commItemForSale);
  updateUnusedWeapons_Internal(kflr.bersItemForSale);
  updateUnusedWeapons_Internal(kflr.fireItemForSale);
  updateUnusedWeapons_Internal(kflr.demoItemForSale);
  updateUnusedWeapons_Internal(kflr.neutItemForSale);
  welderSyringe[welderSyringe.length] = class'SyringePickup';
  welderSyringe[welderSyringe.length] = class'WelderPickup';
  updateUnusedWeapons_Internal(welderSyringe);
  prioritySortGroup(weaponGroup9);
}


simulated function updateUnusedWeapons_Internal(array<class<Pickup> > parsedWeapons)
{
  local int i, j;
  local class<KFWeapon> tempKFWeapon;

  for (i = 0; i < parsedWeapons.length; i++)
  {
    tempKFWeapon = class<KFWeapon>(parsedWeapons[i].default.inventoryType);
    if (tempKFWeapon == none)
      continue;
    if (allUsedWeapons.length == 0)
    {
      weaponGroup9[weaponGroup9.length] = string(tempKFWeapon);
      continue;
    }

    for (j = 0; j < allUsedWeapons.length; j++)
    {
      if (string(tempKFWeapon) == allUsedWeapons[j])
        break;
      if (j == (allUsedWeapons.length - 1))
        weaponGroup9[weaponGroup9.length] = string(tempKFWeapon);
    }
  }
}


simulated function updateAllUsedWeapons()
{
  local int i;

  allUsedWeapons.remove(0, allUsedWeapons.length);

  for (i = 0; i < weaponGroup1.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup1[i];
  }
  for (i = 0; i < weaponGroup2.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup2[i];
  }
  for (i = 0; i < weaponGroup3.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup3[i];
  }
  for (i = 0; i < weaponGroup4.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup4[i];
  }
  for (i = 0; i < weaponGroup5.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup5[i];
  }
  for (i = 0; i < weaponGroup6.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup6[i];
  }
  for (i = 0; i < weaponGroup7.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup7[i];
  }
  for (i = 0; i < weaponGroup8.length; i++)
  {
    allUsedWeapons[allUsedWeapons.length] = weaponGroup8[i];
  }
}


simulated function array<string> getAllPresetNames()
{
  local array<string> names;
  local int i;

  names = getPerObjectNames("HideMutWeapons", string(class'list_WeaponManager'.name));
  for (i = 0; i < names.length; i++)
  {
    if (names[i] ~= "CurrentWeaponList")
    {
      names.remove(i, 1);
    }
  }

  return names;
}

// ============================================================

// are we a variant or no
final protected function bool IsVariantClass(class<Inventory> aInventoryType)
{
  return Left(aInventoryType, 12) ~= "KFMod.Golden" || Left(aInventoryType, 10) ~= "KFMod.Camo" || Left(aInventoryType, 10) ~= "KFMod.Neon";
}

defaultproperties
{
}
