using System.IO;

namespace MyNes.Core
{
    [BoardInfo("11-in-1", 51)]
    internal class Mapper051 : Board
    {
    	private int bank;

    	private int mode = 1;

    	private int offset;

    	internal override void HardReset()
    	{
    		base.HardReset();
    		bank = 0;
    		mode = 1;
    		offset = 0;
    	}

    	internal override void WritePRG(ref ushort address, ref byte data)
    	{
    		switch (address & 0xE000)
    		{
    		case 32768:
    		case 57344:
    			bank = data & 0xF;
    			UpdateBanks();
    			break;
    		case 49152:
    			bank = data & 0xF;
    			mode = ((data >> 3) & 2) | (mode & 1);
    			UpdateBanks();
    			break;
    		}
    	}

    	internal override void WriteSRM(ref ushort address, ref byte data)
    	{
    		mode = ((data >> 3) & 2) | ((data >> 1) & 1);
    		UpdateBanks();
    	}

    	private void UpdateBanks()
    	{
    		offset = 0;
    		if ((mode & 1) == 1)
    		{
    			Switch32KPRG(bank, PRGArea.Area8000);
    			offset = 35;
    		}
    		else
    		{
    			Switch08KPRG((bank << 1) | (mode >> 1), PRGArea.Area8000);
    			Switch08KPRG((bank << 1) | 7, PRGArea.Area8000);
    			offset = 47;
    		}
    		Switch08KPRG(offset | (bank << 2), PRGArea.Area6000);
    		Switch01KNMTFromMirroring((mode == 3) ? Mirroring.Horz : Mirroring.Vert);
    	}

    	internal override void WriteStateData(ref BinaryWriter stream)
    	{
    		base.WriteStateData(ref stream);
    		stream.Write(bank);
    		stream.Write(mode);
    		stream.Write(offset);
    	}

    	internal override void ReadStateData(ref BinaryReader stream)
    	{
    		base.ReadStateData(ref stream);
    		bank = stream.ReadInt32();
    		mode = stream.ReadInt32();
    		offset = stream.ReadInt32();
    	}
    }
}