/**
 *      Main and only Acedia mutator. Used for providing access to mutator
 *  events' calls and detecting server travel.
 *      Copyright   2020-2023 Anton Tarasenko
 *                  2023 Shtoyan
 *------------------------------------------------------------------------------
 * This file is part of Acedia.
 *
 * Acedia 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, version 3 of the License, or
 * (at your option) any later version.
 *
 * Acedia 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 Acedia.  If not, see <https://www.gnu.org/licenses/>.
 */
class AcediaLauncherMut extends Mutator;

//  Acedia's reference to a `Global` object.
var private Global _;

//  Responsible for setting up Acedia's game modes in current voting system
var private VotingHandlerAdapter votingAdapter;

var Mutator_OnMutate_Signal             onMutateSignal;
var Mutator_OnModifyLogin_Signal        onModifyLoginSignal;
var Mutator_OnCheckReplacement_Signal   onCheckReplacementSignal;

simulated function PreBeginPlay()
{
    local StartUp startUpActor;

    _ = class'Global'.static.GetInstance();
    if (level.netMode == NM_DedicatedServer)
    {
        foreach AllActors(class'StartUp', startUpActor)
        {
            votingAdapter = startUpActor.GetVotingHandlerAdapter();
            startUpActor.Destroy();
            break;
        }
        if (votingAdapter != none) {
            votingAdapter.InjectIntoVotingHandler();
        }
        SetupMutatorSignals();
    }
    else {
        class'ClientLevelCore'.static.CreateLevelCore(self);
    }
}

function ServerTraveling(string URL, bool bItems)
{
    if (votingAdapter != none)
    {
        votingAdapter.PrepareForServerTravel();
        votingAdapter.RestoreVotingHandlerConfigBackup();
        _.memory.Free(votingAdapter);
        votingAdapter = none;
    }
    _.environment.ShutDown();
    if (nextMutator != none) {
    	nextMutator.ServerTraveling(URL, bItems);
    }
    Destroy();
}

//  Fetches and sets up signals that `Mutator` needs to provide
private function SetupMutatorSignals()
{
    local ServerUnrealService service;

    service = ServerUnrealService(class'ServerUnrealService'.static.Require());
    onMutateSignal              = Mutator_OnMutate_Signal(
        service.GetSignal(class'Mutator_OnMutate_Signal'));
    onModifyLoginSignal         = Mutator_OnModifyLogin_Signal(
        service.GetSignal(class'Mutator_OnModifyLogin_Signal'));
    onCheckReplacementSignal    = Mutator_OnCheckReplacement_Signal(
        service.GetSignal(class'Mutator_OnCheckReplacement_Signal'));
}

function bool CheckReplacement(Actor other, out byte isSuperRelevant)
{
    if (onCheckReplacementSignal != none) {
        return onCheckReplacementSignal.Emit(other, isSuperRelevant);
    }
    return true;
}

function Mutate(string command, PlayerController sendingController)
{
    if (onMutateSignal != none) {
        onMutateSignal.Emit(command, sendingController);
    }
    super.Mutate(command, sendingController);
}

function ModifyLogin(out string portal, out string options)
{
    if (onModifyLoginSignal != none) {
        onModifyLoginSignal.Emit(portal, options);
    }
    super.ModifyLogin(portal, options);
}

defaultproperties
{
    remoteRole      = ROLE_SimulatedProxy
    bAlwaysRelevant = true
    //  Mutator description
    GroupName       = "Package loader"
    FriendlyName    = "Acedia loader"
    Description     = "Launcher for Acedia packages"
}