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

namespace sega_fusion
{
    class Fusion
    {
        byte[] header;
        byte[] rom_data;
        
        const int MAX_NAME_LEN = 32;

        public Fusion(Romset romset)
        {
            Rom[] unsorted;
            Rom[] sorted;
            byte[][] name_list;
            byte[] buff = new byte[2];

            rom_data = new byte[romset.RomsetBinLen];

            unsorted = romset.GetRomset;
            sorted = sortRoms(unsorted);
            name_list = getNameList(unsorted);
            header = getHeader(sorted);

            for (int i = 0; i < unsorted.Length; i++)
            {
                if (unsorted[i].IsLoader)
                {
                    for (int u = 0; u < name_list.Length - 1; u++)
                    {
                        System.Array.Copy(name_list[u + 1], 0, unsorted[i].Binary, 65536 + u * MAX_NAME_LEN, MAX_NAME_LEN);
                    }
                    break;
                }
            }


            int offset = 0;
            for (int i = 0; i < unsorted.Length; i++)
            {
                System.Array.Copy(sorted[i].Binary, 0, rom_data, offset, sorted[i].Binary.Length);
                offset += sorted[i].Binary.Length;
            }


        }



        Rom[] sortRoms(Rom[] src)
        {
            int len = src.Length;
            Rom[] sorted = new Rom[len];
            Rom buff;


            for (int i = 0; i < len; i++)
            {
                sorted[i] = src[i];
                sorted[i].Idx = i;
            }

            for (int i = 1; i < len; )
            {
                if (sorted[i].Binary.Length > sorted[i - 1].Binary.Length)
                {
                    buff = sorted[i];
                    sorted[i] = sorted[i - 1];
                    sorted[i - 1] = buff;
                    i--;
                    if (i < 1) i = 1;
                }
                else { i++; }
  
                
            }

            return sorted;
        }




        byte[] getHeader(Rom[] list)
        {
            byte[] buff = new byte[Romset.BANK_NUM * 2];
            byte[] buff2 = new byte[Romset.BANK_NUM * 2];
            int bank_idx = 0;
            for (int i = 0; i < list.Length; i++)
            {
                buff[i] = (byte)bank_idx;
                buff[i + Romset.BANK_NUM] = (byte)(list[i].Binary.Length / Romset.BANK_LEN);
                bank_idx += list[i].Binary.Length / Romset.BANK_LEN;
            }

            for (int i = 0; i < list.Length; i++)
            {
                buff2[list[i].Idx] = buff[i];
                buff2[list[i].Idx + Romset.BANK_NUM] = buff[i + Romset.BANK_NUM];
            }

            return buff2;
        }

        byte[][] getNameList(Rom[] list)
        {
            byte[][] name_list = new byte[list.Length][];
            for (int i = 0; i < list.Length; i++)
            {
                name_list[i] = list[i].getByteName(MAX_NAME_LEN);
            }
            return name_list;
        }



        public byte[] Header
        {
            get { return header; }
        }

        public byte[] RomData
        {
            get { return rom_data; }
        }


    }
}
