namespace Chippy.Emulator
{
  public class Memory
  {
    private readonly byte[] _data;
    private readonly Stack<ushort> _stack;

    public Memory(byte[] data, Stack<ushort> stack)
    {
      _data = data;
      _stack = stack;
    }

    public byte Read(int location)
    {
      return _data[location];
    }

    public ushort PopStack()
    {
      return _stack.Pop();
    }

    public void PushStack(ushort value)
    {
      _stack.Push(value);
    }

    public void Write(int location, byte value)
    {
      _data[location] = value;
    }

    public void Reset()
    {
      _stack.Clear();

      for (var index = 0; index < _data.Length; index++)
      {
        _data[index] = 0;
      }

      byte[] _fonts =
      {
        0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
        0x20, 0x60, 0x20, 0x20, 0x70, // 1
        0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
        0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
        0x90, 0x90, 0xF0, 0x10, 0x10, // 4
        0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
        0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
        0xF0, 0x10, 0x20, 0x40, 0x40, // 7
        0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
        0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
        0xF0, 0x90, 0xF0, 0x90, 0x90, // A
        0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
        0xF0, 0x80, 0x80, 0x80, 0xF0, // C
        0xE0, 0x90, 0x90, 0x90, 0xE0, // D
        0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
        0xF0, 0x80, 0xF0, 0x80, 0x80  // F
      };

      _fonts.CopyTo(_data, 0x00);
    }

    public void LoadRom(byte[] rom, int index)
    {
      rom.CopyTo(_data, index);
    }
  }
}
