#include "MidiTimeAdapter.h"

#include "BinaryStream.h"
#include "ByteUtils.h"

#include <iostream>
#include <bitset>

int MidiTimeAdapter::ReadEventTimeDelta(std::ifstream* file, int& delta)
{
    unsigned byteCount = 0;
    char c;
    file->get(c);
    byteCount++;

    if(!ByteUtils::MostSignificantBitIsOne(c))
    {
        delta = int(c);
        std::cout << "Time delta final: " << delta << std::endl;
        return byteCount;
    }

    int working_c = c;
    int final_c = 0;
    unsigned count = 0;
    std::cout << "Working " << std::bitset<8>(working_c) << std::endl;
    while(unsigned(working_c >> 7) != 0)
    {
        char corrected = (working_c &= ~(1UL << 7));
        final_c <<= 7;
        final_c |= (corrected << 7*count);
        char file_c;
        file->get(file_c);
        byteCount++;
        working_c = int(file_c);
        std::cout << "Working " << std::bitset<8>(working_c) << std::endl;
        count++;
    }
    std::cout << "Time delta start: " << std::bitset<16>(final_c) << std::endl;
    final_c <<= 7;
    std::cout << "Time delta pre: " << std::bitset<16>(final_c) << std::endl;
    final_c |= (working_c << 7*(count-1));

    delta = int(final_c);
    std::cout << "Time delta final: " << delta << "|" << std::bitset<16>(final_c)<< std::endl;
    return byteCount;
}

int MidiTimeAdapter::ReadTimeDivision(std::ifstream* file, MidiTimeDivision& division)
{
    const auto time_division = BinaryStream::getNextWord(file, false);
    if(!time_division)
    {
        return -1;
    }

    division.mUseFps = ByteUtils::GetWordFirstBit(*time_division);
    if (division.mUseFps)
    {
        const int TOP_7_BITS = 0x7F00; // 0111 1111 - 0000 0000
        division.mFps = ((~(*time_division) & TOP_7_BITS) >> 8) - 1; // Reverse 2complement of next 7 bits
    }

    division.mTicks = ByteUtils::GetWordLastByte(*time_division);
    return 2; // Bytes advanced
}
