#pragma once
#include "threads.hpp"
#include <stdio.hpp>

namespace JabyEngine {
    namespace Callback {
        namespace internal {
            static void execute_callback(Thread::Handle thread_handle, uint32_t parm) {
                if(CurrentThread::is_me(MainThread::Handle)) {
                    CurrentThread::replace_with(thread_handle);
                    CurrentThread::force_a0(parm);
                }
                SysCall::ReturnFromException();
            }

            static uint32_t resume_callback(Thread::Handle handle) {
                SysCall::ChangeThread(handle);
                asm("sw $a0, %0" : "=m"(handle));
                return handle;
            }

            namespace VSync {
                static constexpr size_t StackSize = 64;

                extern SysCall::ThreadHandle thread_handle;
                extern uint32_t              stack[StackSize];
                void                         routine();

                static void [[deprecated("Currently not in use")]] execute() {
                    execute_callback(VSync::thread_handle, 0);
                }
            }

            namespace CD {
                static constexpr size_t StackSize = 256;

                extern Thread::Handle thread_handle;
                extern uint32_t       stack[StackSize];
                void                  routine(uint32_t irq);

                static void execute(uint32_t irq) {
                    execute_callback(CD::thread_handle, irq);
                }

                static uint32_t resume() {
                    return resume_callback(MainThread::Handle);
                }
            }
        }
    }
}
