#include "make_table.hpp"

#include <fstream>
#include <iostream>
#include <string>

void write_table(std::string filename, const std::array<Chip_vol, 256>& table);
void write_table(std::string filename, const std::array<int, 256>& table);

int main()
{
    // https://web.archive.org/web/20180306212012/http://forum.tslabs.info/viewtopic.php?f=6&t=539
    constexpr std::array<int, 16> ay_levels = {
        0x0000, //0
        0x028f, //1
        0x03b3, //2
        0x0564, //3
        0x07dc, //4
        0x0ba9, //5
        0x1083, //6
        0x1b7c, //7
        0x2068, //8
        0x347a, //9
        0x4ace, //10
        0x5f72, //11
        0x7e16, //12
        0xa2a4, //13
        0xce3a, //14
        0xffff  //15
    };

    constexpr std::array<int, 16> ym_levels = {
        0x0000, //0
        0x01fa, //1
        0x0393, //2
        0x0520, //3
        0x079a, //4
        0x0a57, //5
        0x0eef, //6
        0x13e9, //7
        0x1c70, //8
        0x2603, //9
        0x3628, //10
        0x47f6, //11
        0x6682, //12
        0x88d0, //13
        0xc20c, //14
        0xffff  //15
    };

    // std::cout << "Generating AY table (weighted)..." << std::endl;
    // write_table("ay_table_weighted.asm", *best_table(ay_levels, 0, 0, true));

    // std::cout << "Generating YM table (weighted)..." << std::endl;
    // write_table("ym_table_weighted.asm", *best_table(ym_levels, 0, 0, true));

    // std::cout << "Generating AY table (unweighted)..." << std::endl;
    // write_table("ay_table_unweighted.asm", *best_table(ay_levels, 0, 0, false));

    // std::cout << "Generating YM table (unweighted)..." << std::endl;
    // write_table("ym_table_unweighted.asm", *best_table(ym_levels, 0, 0, false));

    std::cout << "Generating AY table..." << std::endl;
    write_table("ay_table.asm", *best_table(ay_levels, 0, std::get<15>(ay_levels) * 3, false));

    std::cout << "Generating YM table..." << std::endl;
    write_table("ym_table.asm", *best_table(ym_levels, 0, std::get<15>(ym_levels) * 3, false));

    std::cout << "Generating AY table (4 bit)..." << std::endl;
    write_table("ay_table_4bit.asm", *best_table_4bit(ay_levels, 0, std::get<15>(ay_levels)));

    std::cout << "Generating YM table (4 bit)..." << std::endl;
    write_table("ym_table_4bit.asm", *best_table_4bit(ym_levels, 0, std::get<15>(ym_levels)));

    // std::cout << "Press a key..." << std::endl;
    // std::string s;
    // std::cin >> s;
}

void write_table(std::string filename, const std::array<Chip_vol, 256>& table)
{
    std::fstream fs;

    fs.open(filename, std::ios::out);

    for (int chan {0}; chan != 3; ++chan)
    {
        for (int i {0}; i != 256; ++i)
        {
            if (!(i % 8))
                fs << "db ";

            fs << (table.at(i).at(chan) | 0xa0); // set bits ready for output

            if ((i + 1) % 8)
                fs << ", ";
            else
                fs << '\n';
        }

        fs << '\n';
    }
}

void write_table(std::string filename, const std::array<int, 256>& table)
{
    std::fstream fs;

    fs.open(filename, std::ios::out);

    for (int i {0}; i != 256; ++i)
    {
        if (!(i % 8))
            fs << "db ";

        fs << (table.at(i) | 0xa0); // set bits ready for output

        if ((i + 1) % 8)
            fs << ", ";
        else
            fs << '\n';
    }

    fs << '\n';
}
