#include <stdint.h>

#include "../core_memory/core_memory_private.h"
#include "sound_alias_private.h"

enum {
    SOUND_ALIAS_FATAL_DROP = 1
};

#define SOUND_ALIAS_DISTANCE_MAX_DEFAULT_SCALE 5.0f

void Com_ValidateSoundAliasParseNode(coduo_sound_alias_parse_node_t *node)
{
    float value;

    if (node->pitchMax < node->pitchMin) {
        value = node->pitchMax;
        node->pitchMax = node->pitchMin;
        node->pitchMin = value;
    }

    if (node->pitchMin <= 0.0f) {
        Com_Error(SOUND_ALIAS_FATAL_DROP,
                  "\x15" "sound alias '%s' has pitch_min %g <= 0\n",
                  node->name, node->pitchMin);
    }

    if (node->volumeMax < node->volumeMin) {
        value = node->volumeMax;
        node->volumeMax = node->volumeMin;
        node->volumeMin = value;
    }

    if (node->volumeMin < 0.0f) {
        Com_Error(SOUND_ALIAS_FATAL_DROP,
                  "\x15" "sound alias '%s' has vol_min < 0\n",
                  node->name, node->volumeMin);
    }

    if (node->distMax == 0.0f) {
        node->distMax = node->distMin *
                        SOUND_ALIAS_DISTANCE_MAX_DEFAULT_SCALE;
    }

    if (node->distMax < node->distMin) {
        Com_Error(SOUND_ALIAS_FATAL_DROP,
                  "\x15" "sound alias '%s' has dist_min %g <= dist_max %g\n",
                  node->name, node->distMin, node->distMax);
    }

    if (node->distMin <= 0.0f) {
        Com_Error(SOUND_ALIAS_FATAL_DROP,
                  "\x15" "sound alias '%s' has dist_min <= 0\n",
                  node->name, node->distMin);
    }
}

coduo_sound_alias_parse_node_t *
Com_CloneSoundAliasParseNode(const coduo_sound_alias_parse_node_t *node)
{
    coduo_sound_alias_parse_node_t *clone;

    clone = Hunk_AllocateTempMemory((size_t)sizeof(*clone));
    *clone = *node;
    clone->next = soundAlias_parseListHead;
    soundAlias_parseListHead = clone;

    return clone;
}

void Com_FinalizeSoundAliasRecord(const coduo_sound_alias_parse_node_t *node,
                                  coduo_sound_alias_t *alias,
                                  const char *name,
                                  const char *file,
                                  const char *subtitle,
                                  int32_t locale)
{
    int bucket;

    alias->name = name;
    alias->file = file;
    alias->subtitle = subtitle;
    alias->soundFileInfo = NULL;
    alias->pickSequence = 0;
    alias->volumeMin = node->volumeMin;
    alias->volumeMax = node->volumeMax;
    alias->pitchMin = node->pitchMin;
    alias->pitchMax = node->pitchMax;
    alias->distMin = node->distMin;
    alias->distMax = node->distMax;
    alias->channel = node->channel;
    alias->type = node->type;
    alias->loop = node->loop;
    alias->isMaster = node->isMaster;
    alias->isSlave = node->isSlave;
    alias->slavePercentage = node->slavePercentage;
    alias->selectionWeight = node->selectionWeight;
    alias->selectorMin = node->selectorMin;
    alias->selectorMax = node->selectorMax;

    bucket = Com_SoundAliasHash(alias->name);
    alias->hashNext = soundAlias_hashTable[locale][bucket];
    soundAlias_hashTable[locale][bucket] = alias;
}
