//
//  AudioBusFormat.hpp
//  SwitchboardSDK
//
//  Created by Balázs Kiss on 2022. 05. 19..
//  Copyright © 2022. Synervoz Inc. All rights reserved.
//

#pragma once

#include <switchboard/export.h>
#include <switchboard_core/SwitchboardCore.hpp>

#include <vector>

namespace switchboard {

/**
 * AudioBusFormat class.
 * @brief Describes the format of an AudioBus instance without the need for the audio data.
 * @details Multiple AudioBusFormat instances can be handled by the AudioBusFormatList class.
 */
struct SWITCHBOARDSDK_EXPORT AudioBusFormat {
public:
    /// @brief Sample rate.
    uint sampleRate;

    /// @brief Number of channels.
    uint numberOfChannels;

    /// @brief Number of frames.
    uint numberOfFrames;

    /**
     * @brief Initializes an AudioBusFormat instance with zero values.
     */
    AudioBusFormat();

    /**
     * @brief Initializes an AudioBusFormat instance with the provided values.
     *
     * @param sampleRate The sample rate.
     * @param numberOfChannels The number of channels.
     * @param numberOfFrames The number of frames.
     */
    AudioBusFormat(uint sampleRate, uint numberOfChannels, uint numberOfFrames);

    /**
     * @brief Returns whether the audio bus format is completely defined.
     * @details A bus format is considered set if all of its properties (sample rate, number of channels, and number of frames) are non-zero.
     *
     * @returns True if all properties are set (non zero), false otherwise.
     */
    bool isSet() const;

    /**
     * @brief Resets the audio bus format properties.
     * @details Sets the property values to zero.
     */
    void reset();

    /**
     * @brief Compares two audio bus formats.
     *
     * @param other The other AudioBusFormat instance.
     *
     * @returns True if the two formats are exactly the same, false otherwise.
     */
    bool operator==(const AudioBusFormat& other);

    /**
     * @brief Compares two audio bus formats.
     *
     * @param other The other AudioBusFormat instance.
     *
     * @returns True if the two formats are different, false otherwise.
     */
    bool operator!=(const AudioBusFormat& other);

    /**
     * @brief Matches two AudioBusFormat instances.
     * @details If both bus formats are set, their equality will be checked. If one of them is not set, the unset one will match the set one. If none of them are set, the result value will false.
     *
     * @param busFormat1 The first bus format.
     * @param busFormat2 The second bus format.
     *
     * @returns True if the two bus formats could be matched successfully, false otherwise.
     */
    static bool matchBusFormats(AudioBusFormat& busFormat1, AudioBusFormat& busFormat2);

    /**
     * @brief Returns a string representing the object.
     *
     * @returns A string representing the object.
     */
    std::string toString() const;
};

}
