#ifndef _RIVE_MAC_UTILS_HPP_
#define _RIVE_MAC_UTILS_HPP_

#include "rive/rive_types.hpp"
#include "rive/span.hpp"
#include <string>

#ifdef RIVE_BUILD_FOR_APPLE

#if defined(RIVE_BUILD_FOR_OSX)
#include <ApplicationServices/ApplicationServices.h>
#elif defined(RIVE_BUILD_FOR_IOS)
#include <CoreFoundation/CoreFoundation.h>
#include <CoreGraphics/CGImage.h>
#endif

template <size_t N, typename T> class AutoSTArray {
    T m_storage[N];
    T* m_ptr;
    const size_t m_count;

public:
    AutoSTArray(size_t n) : m_count(n) {
        m_ptr = m_storage;
        if (n > N) {
            m_ptr = new T[n];
        }
    }
    ~AutoSTArray() {
        if (m_ptr != m_storage) {
            delete[] m_ptr;
        }
    }

    T* data() const { return m_ptr; }

    T& operator[](size_t index) {
        assert(index < m_count);
        return m_ptr[index];
    }
};

constexpr inline uint32_t make_tag(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
    return (a << 24) | (b << 16) | (c << 8) | d;
}

static inline std::string tag2str(uint32_t tag) {
    std::string str = "abcd";
    str[0] = (tag >> 24) & 0xFF;
    str[1] = (tag >> 16) & 0xFF;
    str[2] = (tag >> 8) & 0xFF;
    str[3] = (tag >> 0) & 0xFF;
    return str;
}

template <typename T> class AutoCF {
    T m_obj;

public:
    AutoCF(T obj = nullptr) : m_obj(obj) {}
    AutoCF(const AutoCF& other) {
        if (other.m_obj) {
            CFRetain(other.m_obj);
        }
        m_obj = other.m_obj;
    }
    AutoCF(AutoCF&& other) {
        m_obj = other.m_obj;
        other.m_obj = nullptr;
    }
    ~AutoCF() {
        if (m_obj) {
            CFRelease(m_obj);
        }
    }

    AutoCF& operator=(const AutoCF& other) {
        if (m_obj != other.m_obj) {
            if (other.m_obj) {
                CFRetain(other.m_obj);
            }
            if (m_obj) {
                CFRelease(m_obj);
            }
            m_obj = other.m_obj;
        }
        return *this;
    }

    void reset(T obj) {
        if (obj != m_obj) {
            if (m_obj) {
                CFRelease(m_obj);
            }
            m_obj = obj;
        }
    }

    operator T() const { return m_obj; }
    operator bool() const { return m_obj != nullptr; }
    T get() const { return m_obj; }
};

static inline float find_float(CFDictionaryRef dict, const void* key) {
    auto num = (CFNumberRef)CFDictionaryGetValue(dict, key);
    assert(num);
    float value = 0;
    CFNumberGetValue(num, kCFNumberFloat32Type, &value);
    return value;
}

static inline uint32_t find_u32(CFDictionaryRef dict, const void* key) {
    auto num = (CFNumberRef)CFDictionaryGetValue(dict, key);
    assert(num);
    assert(!CFNumberIsFloatType(num));
    uint32_t value = 0;
    CFNumberGetValue(num, kCFNumberSInt32Type, &value);
    return value;
}

static inline uint32_t number_as_u32(CFNumberRef num) {
    uint32_t value;
    CFNumberGetValue(num, kCFNumberSInt32Type, &value);
    return value;
}

static inline float number_as_float(CFNumberRef num) {
    float value;
    CFNumberGetValue(num, kCFNumberFloat32Type, &value);
    return value;
}

namespace rive {
    AutoCF<CGImageRef> DecodeToCGImage(Span<const uint8_t>);
    AutoCF<CGImageRef> FlipCGImageInY(AutoCF<CGImageRef>);
} // namespace rive

#endif
#endif
