using System;
using System.Collections.Generic;
using System.Text;

namespace everdrive3x.Rom
{
    class N64Rom : RomInterface
    {

        const byte SELECT_MODE_NO = 0xff;
        public const String ROM_TYPE_Z64 = "Z64";
        public const String ROM_TYPE_V64 = "V64";
        byte[] bin_data;
        byte[] config;
        String rom_type;
        String rom_name;
        int declarated_size;
        String platform;

        public N64Rom(byte[] src, int offset, int len)
        {
            rom_type = getRomType(src, offset);
            if (rom_type == null)
            {
                throw new Exception("non n64 rom format");
            }

            bin_data = new byte[len];

            System.Array.Copy(src, offset, bin_data, 0, len);
            if (rom_type.EndsWith(ROM_TYPE_V64))
            {
                flipBytes(bin_data);
            }
            platform = Hardware.PlatformList.NAME_N64;
            config = new byte[1];
            config[0] = 0xff;
            rom_name = Misc.DataTool.getHeaderString(bin_data , 32, 20);
        }

        void flipBytes(byte[] src)
        {
            for (int i = 0; i < src.Length; i += 2)
            {
                byte buff = src[i];
                src[i] = src[i + 1];
                src[i + 1] = buff;
             }
        }

        void loadRom(byte[] src, int offset, int len)
        {
        }

        public static String getRomType(byte[] src, int offset)
        {

            int[] head_a = { 0x37, 0x80, 0x40, 0x12 };
            int[] head_b = { 0x80, 0x37, 0x12, 0x40 };


            for (int i = 0; i < head_a.Length; i++)
            {
                if (head_a[i] != (src[i + offset]))
                {
                    break;
                }
                if (i == head_a.Length - 1)
                {
                    return ROM_TYPE_V64;
                }
            }

            for (int i = 0; i < head_b.Length; i++)
            {
                if (head_b[i] != (src[i + offset]))
                {
                    break;
                }
                if (i == head_b.Length - 1)
                {
                    return ROM_TYPE_Z64;
                }
            }

            return null;
        }



        public byte[] BinData
        {
            get { return bin_data; }
        }

        public byte[] Config
        {
            get { return config; }
        }

        public String Name
        {
            get { return rom_name; }
        }

        public String Platform
        {
            get { return platform; }
        }



        public String RomType
        {
            get { return rom_type; }
        }

        public int DeclaratedSize
        {
            get { return declarated_size; }
        }
        public String Region
        {
            get { return "" + (char)bin_data[62]; }
            set{}
        }
    }
}
