/*****************************************************************************
 * Copyright (c) 2014-2025 OpenRCT2 developers
 *
 * For a complete list of all authors, please refer to contributors.md
 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
 *
 * OpenRCT2 is licensed under the GNU General Public License version 3.
 *****************************************************************************/

#pragma once

#include "../core/IStream.hpp"
#include "../drawing/ImageId.hpp"
#include "../ride/RideEntry.h"
#include "../ride/RideTypes.h"
#include "Object.h"

#include <vector>

enum class RideCategory : uint8_t;

namespace OpenRCT2
{
    class RideObject final : public Object
    {
    private:
        RideObjectEntry _legacyType = {};
        VehicleColourPresetList _presetColours = {};
        std::vector<int8_t> _peepLoadingPositions[OpenRCT2::RCT2::ObjectLimits::kMaxCarTypesPerRideEntry];
        std::vector<std::array<CoordsXY, 3>> _peepLoadingWaypoints[OpenRCT2::RCT2::ObjectLimits::kMaxCarTypesPerRideEntry];

    public:
        static constexpr ObjectType kObjectType = ObjectType::ride;

        void* GetLegacyData() override
        {
            return &_legacyType;
        }
        const RideObjectEntry& GetEntry() const
        {
            return _legacyType;
        }

        void ReadJson(IReadObjectContext* context, json_t& root) override;
        void ReadLegacy(IReadObjectContext* context, OpenRCT2::IStream* stream) override;
        void Load() override;
        void Unload() override;

        void DrawPreview(RenderTarget& rt, int32_t width, int32_t height) const override;

        std::string GetDescription() const;
        std::string GetCapacity() const;
        ImageIndex GetPreviewImage(ride_type_t type);

        void SetRepositoryItem(ObjectRepositoryItem* item) const override;

        static ride_type_t ParseRideType(const std::string& s);

    private:
        void ReadLegacyCar(IReadObjectContext* context, OpenRCT2::IStream* stream, CarEntry* car);

        void ReadJsonVehicleInfo(IReadObjectContext* context, json_t& properties);
        std::vector<CarEntry> ReadJsonCars([[maybe_unused]] IReadObjectContext* context, json_t& jCars);
        CarEntry ReadJsonCar([[maybe_unused]] IReadObjectContext* context, json_t& jCar);
        VehicleColourPresetList ReadJsonCarColours(json_t& jCarColours);
        std::vector<VehicleColour> ReadJsonColourConfiguration(json_t& jColourConfig);

        static uint8_t CalculateNumVerticalFrames(const CarEntry& carEntry);
        static uint8_t CalculateNumHorizontalFrames(const CarEntry& carEntry);

        static bool isRideTypeShopOrFacility(ride_type_t rideType);
        static RideCategory ParseRideCategory(const std::string& s);
        static ShopItem ParseShopItem(const std::string& s);
        static colour_t ParseColour(const std::string& s);

        void ReadLegacySpriteGroups(CarEntry* vehicle, uint16_t spriteGroups);
        uint8_t GetDefaultClearance() const;
    };
} // namespace OpenRCT2
