#pragma once

#include <iostream>
#include <vector>

/** The object of this class read header info from nes file.
   Usage:
	if (argc < 2){
		printHelp();
		return 0;
	}
	ifstream fin(argv[1]);
	iNesHeader header;
	header.read(fin);
	header.display(cout);
	return 0;
*/
class INesHeader
{
public:
	enum Mirroring {
		HORIZONTAL, VERTICAL, 
	};
private:
	enum ConstInt{
		BYTELENGTH=16, FLAG_INDEX=6,
		MIRRORING_BIT=0, BATTERY_BIT=1, TRAINER_BIT=2, FOUR_SCREEN_BIT=3,
	};
	typedef std::vector<unsigned char> ByteSequence;
	ByteSequence byte;
public:
	INesHeader();
	std::vector<unsigned char>& bytecode();
	unsigned mapperNumber()const;
	/** <<query>>: returns true when header signature is not valid.*/
	bool bad()const;
	bool isValid()const;
	/** <<modifier>>: read first BYTELENGTH bytes.*/
	void read(std::istream& is);
	
	bool isVerticalMirroring()const;
	bool isBatteryOn()const;
	bool isTrainerOn()const;
	bool is4Screen()const;
	
	/** total size of PRG-ROMs.*/
	unsigned sizeOfPRG()const;
	/** total size of CHR-ROMs.*/
	unsigned sizeOfCHR()const;
	/** assumed start address of PRG from PRG size.*/
	unsigned startAddress()const;
	void dump(std::ostream& os)const;
private:
	bool isValidSignature()const;
	bool isTailValid()const;
	/** get flag byte bit.*/
	bool flagAt(unsigned index, unsigned bit)const;
};
/***/
class INesHeaderPrinter
{
	
};

