/**
 * Author: dkanus
 * Home repo: https://www.insultplayers.ru/git/AcediaFramework/AcediaCore
 * License: GPL
 * Copyright 2024 Anton Tarasenko
 *------------------------------------------------------------------------------
 * 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 Entity extends AcediaObject
    abstract;

/// Describes a "blueprint" for creating a brand new entity.
struct Template {
    /// A type field that new entity will have.
    ///
    /// For vanilla Killing Floor classes this will coincide with `class` name.
    var public Text type;
    /// Set of tags that will be associated with new entity.
    ///
    /// Can be used to mark intended purpose of a corresponding entity.
    /// For instance, weapons might be tagged as "main", "secondary", or "offhand", while enemies
    /// could be categorized as "trash", "minor", "tough", "brutal" or "boss".
    var public array<Text> tags;
    /// A list of components that the new entity will initially possess, each defining specific
    /// functionalities or properties, such as health, position, or abilities.
    var public array<Component> components;
};

/// Record entity's type.
///
/// `none` means no type is set.
/// Should only be accessible through this class. When returning its value or receiving tags from/to
/// the user, an independent copy must be made.
var protected Text type;

/// Set of tags associated with this entity.
///
/// Should not contain `none`s. Every `Text` item in the array should only be accessible through
/// this class. When returning an array or receiving tags from/to the user, an independent copy must
/// be made.
var protected array<Text> tags;

/// Returns a copy of the type of the current instance, or `none` if no type is set.
public function Text GetType() {
    if (type == none) {
        return none;
    }
    return type.Copy();
}

/// Sets the type of the current instance to a copy of `newType`, or `none` if `newType` is `none`.
public function SetType(BaseText newType) {
    if (newType == none) {
        type = none;
    } else {
        type = newType.Copy();
    }
}

/// Retrieves all tags associated with the instance and returns them as an array.
///
/// The result is guaranteed to contain no `none`s.
public function array<Text> GetTags() {
    local int i;
    local array<Text> result;

    i = 0;
    while (i < tags.length) {
        // Check for `none` just in case someone messed up a variable that is only the `protected`
        if (tags[i] == none) {
            tags.Remove(i, 1);
        } else {
            result[result.length] = tags[i].Copy();
            i += 1;
        }
    }
    return result;
}

/// Clears existing set of tags and sets new tags based on `newTags`, copying
// each tag that is not `none`.
public function SetTags(array<Text> newTags) {
    local int i;

    _.memory.FreeMany(tags);
    tags.length = 0;
    for (i = 0; i < newTags.length; i += 1) {
        if (newTags[i] != none) {
            tags[tags.length] = newTags[i].Copy();
        }
    }
}

defaultproperties {
}