#ifndef STARS_IRDB_Instruction_h
#define STARS_IRDB_Instruction_h

#include <assert.h>

#include "interfaces/abstract/STARSInstruction.h"
#include "interfaces/abstract/STARSInstructionID.h"
#include <libIRDB-core.hpp>

class SMPInstr;

class STARS_IRDB_Instruction_t : public STARS_Instruction_t
{
	public:

		// Constructors and destructors
		STARS_IRDB_Instruction_t(const libIRDB::Instruction_t *insn) 
			: STARS_Instruction_t(insn->GetBaseID()), irdb_insn(insn)
		{ assert(irdb_insn);  }

		STARS_InstructionID_t GetID() { return irdb_insn->GetBaseID(); }

		// Data initialization methods
// jdh: get DISASM structure?  why not done in constructor?
		virtual bool STARS_GetCmd(void) { assert(0); }

		// Get (accessor) methods
// jdh: OK if insn sizes aren't well defined?
		virtual inline uint16_t GetSize(void) const { assert(0); }
		virtual inline uint16_t GetIDAOpcode(void) const { assert(0); }
		virtual STARS_InstructionID_t GetNextInstructionID(void) { assert(0); }
		virtual STARS_InstructionID_t GetTargetInstructionID(void) { assert(0); }

// jdh: what are features?
// what bits are used and what're their meanings?
		virtual inline uint32_t GetInstFeatures(void) const { assert(0); }

// jdh: consider returning by reference?
		virtual STARSOpndTypePtr GetOpnd(std::size_t OpndNum) const { assert(0); }

		// Set (mutator) methods

		// why do instructions need to keep track of this?
		virtual void SetOpUsed(std::size_t OpndNum) {assert(0); } // set the USE bit
		virtual void SetOpNotUsed(std::size_t OpndNum) {assert(0); } // reset the USE bit
		virtual void SetOpDefed(std::size_t OpndNum) {assert(0); } // set the DEF bit
		virtual void SetOpNotDefed(std::size_t OpndNum) {assert(0); } // reset the DEF bit

// jdh: not needed for IRDB?
		virtual void RemoveIDAOp1ForIMUL(void) {assert(0); } // Fix up IDA Pro IMUL instruction by removing operand 1

		// Query methods
		virtual inline bool HasRepeatIfEqualPrefix(void) const {assert(0); }
		virtual inline bool HasRepeatIfNotEqualPrefix(void) const {assert(0); }
		virtual inline bool HasAnyRepeatPrefix(void) const {assert(0); }
		virtual bool OpcodeDefaultsTo64BitOperands(void) const {assert(0); }

		// jdh: vex, etc. insns?  
		virtual bool Has64BitOperands(void) const {assert(0); }
		virtual inline bool Uses64BitAddressing(void) const {assert(0); }
		virtual bool Uses32BitAddressing(void) const {assert(0); }

// jdh: why are these not part of the Opnd class?
		virtual inline bool IsRegOpnd(std::size_t OpndNum) const {assert(0); }
		virtual inline bool IsImmedOpnd(std::size_t OpndNum) const {assert(0); }

// jdh: what does this do?
		virtual inline bool RegOpndMatches(std::size_t OpndNum, uint16_t RegNum) const {assert(0); }
		virtual bool IsUseOpnd(std::size_t OpndNum) const {assert(0); }
		virtual bool IsDefOpnd(std::size_t OpndNum) const {assert(0); }

// jdh: what's this mean?
		virtual bool IsBranchToFarChunk(SMPInstr *CurrInst, STARS_ea_t &TargetAddr) {assert(0); }

		// Operand creation methods


// jdh: do these "make operand" methods create an operand that's somehow linked/related to this instruction,
// or are these generic operand for any instruction.  If generic, we should make them static factory-type methods
// of the operand class.


// jdh: what is a void operand?
		virtual STARSOpndTypePtr MakeVoidOpnd(void) const {assert(0); }
		virtual STARSOpndTypePtr MakeImmediateOpnd(STARS_uval_t value) const {assert(0); }
		virtual STARSOpndTypePtr MakeRegOpnd(uint16_t RegNum) const {assert(0); }
		virtual STARSOpndTypePtr MakeFloatingPointRegOpnd(uint16_t RegNum) const {assert(0); }
		virtual STARSOpndTypePtr MakeMMXRegOpnd(uint16_t RegNum) const {assert(0); }
		virtual STARSOpndTypePtr MakeXMMRegOpnd(uint16_t RegNum) const {assert(0); }
		virtual STARSOpndTypePtr MakeYMMRegOpnd(uint16_t RegNum) const {assert(0); }
		virtual STARSOpndTypePtr MakeMemDisplacementOpnd(uint16_t BaseRegNum, uint16_t IndexRegNum, uint16_t ScaleFactor, STARS_ea_t offset) const {assert(0); }
		virtual STARSOpndTypePtr MakeMemPhraseOpnd(uint16_t BaseRegNum, uint16_t IndexRegNum, uint16_t ScaleFactor) const {assert(0); }

		// Analysis methods

		// useful for other IRDB classes.
		virtual const libIRDB::Instruction_t* GetIRDBInstruction() const { return irdb_insn;}

	private:

		const libIRDB::Instruction_t* irdb_insn;

};

#endif