#pragma once
#include "instruction_map.hpp"
#include <iostream>
#include <vector>

 /** This builder scan bytecode and create instruction to map */
class InstructionScanner
{
protected:
	InstructionMap::shared_ptr m_map;
	MemoryAddress m_start_address;
	MemoryAddress m_current;
public:
	/** scanner needs start address of instructions.*/
	InstructionScanner(MemoryAddress start_address);
	InstructionScanner(MemoryAddress start_address, MemoryAddress end_address);
	/** read stream and build instruction map.*/
	void read(std::istream& is);
	/** convert vector<Byte> to stream, then read the stream.*/
	void readByteVector(std::vector<unsigned char>& bytes);
	/** get scanned instruction map.*/
	InstructionMap::shared_ptr getMap()const;
	/** add instruction to map, and increment current address.*/
	Instruction::shared_ptr createInstruction(unsigned char byte);
};

class InstructionPostScanner : public InstructionScanner
{
public:
	/** for adding. */
	InstructionPostScanner(InstructionMap::shared_ptr map, MemoryAddress address);
	/** read three bytes and add instruction to given map.*/
	void readThreeBytes(Byte opcode, Byte low, Byte high);
};
