#pragma once

#include <spider/runtime/reel/InstrReel.hpp>

namespace spider {

    /**
     * Implements an instruction reel.
     */
    class InstrReelFixed : public InstrReel {
    private:
        u8* _mem;
        u64 _size;

    public:

        InstrReelFixed(u64 length);

        InstrReelFixed(const u8* data, u64 length);

        InstrReelFixed(const InstrReelFixed& copy);

        InstrReelFixed(InstrReelFixed&& move) noexcept;

        virtual ~InstrReelFixed();

    public:

        InstrReelFixed& operator=(const InstrReelFixed& copy);

        InstrReelFixed& operator=(InstrReelFixed&& move) noexcept;

    public:

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u8 readU8(u64 ip) override;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u16 readU16(u64 ip) override;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u32 readU32(u64 ip) override;

        /**
         * Obtains a byte of data at
         * the specific location.
         * Reindexing may occur, continous access
         * may incurr in less penalties.
         */
        virtual u64 readU64(u64 ip) override;
        
        /**
         * Reads a range of data, and
         * outputs it.
         */
        virtual void readRange(u64 ip, u8* out, u64 length) override;

        /**
         * Current size of the instructions.
         */
        virtual u64 size() override;

    public:

        void writeU8(u64 ip, u8 dat);

        void writeU16(u64 ip, u16 dat);

        void writeU32(u64 ip, u32 dat);

        void writeU64(u64 ip, u64 dat);

        void resize(u64 new_size);

    };

}
