/****************************************************************************
** Copyright (c) 2016, Fougue SAS <https://www.fougue.pro>
** SPDX-License-Identifier: BSD-2-Clause
****************************************************************************/

#pragma once

#include "../base/property_builtins.h"
#include "../base/property_value_conversion.h"

namespace Mayo {

// Stores the UI state of the main application widgets
class AppUiState {
public:
    using Variant = PropertyValueConversion::Variant;
    using MapType = PropertyValueConversion::VariantMap;

    using key_type = MapType::key_type;
    using mapped_type = MapType::mapped_type;
    using value_type = MapType::value_type;

    using iterator = MapType::iterator;
    using const_iterator = MapType::const_iterator;

    bool empty() const { return m_map.empty(); }
    std::size_t size() const { return m_map.size(); }

    iterator begin() { return m_map.begin(); }
    iterator end() { return m_map.end(); }
    const_iterator begin() const { return m_map.begin(); }
    const_iterator end() const { return m_map.end(); }

    const_iterator cbegin() const { return m_map.cbegin(); }
    const_iterator cend() const { return m_map.cend(); }

    const Variant* find(std::string_view key) const;
    const Variant& get(std::string_view key) const;
    void set(std::string_view key, Variant value);

    // Serializes AppUiState object into a compact binary blob
    //
    // The resulting byte array can later be restored using fromBlob(). The serialization format is
    // implementation-defined and intended for internal persistence only
    // The generated blob is not guaranteed to be stable across incompatible application versions
    static std::vector<uint8_t> toBlob(const AppUiState& state);

    // Restores the AppUiState object previously serialized with toBlob()
    //
    // Parameter `blob` must contain binary data generated by toBlob().
    // If deserialization succeeds, the reconstructed state is returned and `ok` is set to true
    // If deserialization fails, an empty AppUiState object is returned and `ok` is set to false
    static AppUiState fromBlob(gsl::span<const uint8_t> blob, bool* ok = nullptr);

private:
    MapType m_map;
};

using PropertyAppUiState = GenericProperty<AppUiState>;

} // namespace Mayo
