#include "YoseenStream.h"
#include  "util.h"


CYoseenStream::CYoseenStream() {
    //
    m_alg = strCreate();
    m_algConfig = {};
    m_paletteData = Yoseen_AllocPaletteData(m_paletteCount);

    //
    m_file = NULL;
    m_dataWidth = 0, m_dataHeight = 0, m_dataPixels = 0;
    m_frameBegin = 0, m_frameEnd = 0, m_frameCount = 0;
    m_frameSize = 0, m_frameBeginOffset = 0, m_frame0Offset = 0;
    m_data = NULL;
}
CYoseenStream::~CYoseenStream() {
    strFree(m_alg);
    Yoseen_FreePaletteData(&m_paletteData);

    //
    if (m_file) {
        fclose(m_file);
        m_file = NULL;
    }
    if (m_data) {
        free(m_data);
        m_data = NULL;
    }
}

s32 CYoseenStream::loadStream(const char* fn) {
    if (NULL != m_file) {
        fclose(m_file);
        m_file = NULL;
    }

    s32 ret;
    s64 fileSize;
    bmp_file_header bfh = {};
    m_file = fopen(fn, "rb");
    if (NULL == m_file)return EError_FileOpen;
    ret = fread(&bfh, sizeof(bmp_file_header), 1, m_file);
    if (1 != ret) {
        ret = EError_FileRead; goto error1;
    }
    m_dataWidth = bfh.biHeader.biWidth;
    m_dataHeight = -bfh.biHeader.biHeight;
    m_dataPixels = m_dataWidth * m_dataHeight;
    m_frameSize = 128 + m_dataPixels * 2;

    //
    _fseeki64(m_file, 0, SEEK_END);
    fileSize = _ftelli64(m_file);
    m_frame0Offset = 64 + m_dataPixels * 4 + 1024 + 128;
    m_frameCount = (fileSize - m_frame0Offset) / m_frameSize;
    if (m_frameCount < 0) {
        ret = EError_FileData; goto error1;
    }
    m_frameBegin = -1;
    m_frameEnd = -1;

    //
    if (m_data) {
        free(m_data);
        m_data = NULL;
    }
    m_data = (DataFrameHeader*)malloc(128 + m_dataPixels * 8);
    if (NULL == m_data) { ret = EError_NoMemory; goto error1; }
    return 0;

error1:
    if (m_file) { fclose(m_file); m_file = NULL; }
    return ret;
}

s32 CYoseenStream::findBeginAndEnd() {
    if (NULL == m_file)return EError_InvalidState;
    s32 ret;
    DataFrameHeader dfh = {};
    s32 i;

    s64 offset;

    m_frameBegin = -1;
    m_frameEnd = -1;

    //
    //{
    //    u8* debug_inputData = (u8*)calloc(1, m_frameCount);
    //    for (i = 0; i < m_frameCount; i++) {
    //        offset = m_frame0Offset+ i* m_frameSize;
    //        _fseeki64(m_file, offset, SEEK_SET);
    //        ret = fread(&dfh, 128, 1, m_file);
    //        debug_inputData[i] = dfh.GpioInput0;
    //    }
    //    XDUMP(debug_inputData, m_frameCount, "input.bin");
    //    free(debug_inputData);
    //}

    //find begin
    for (i = 0; i < m_frameCount; i++) {
        offset = m_frame0Offset + i* m_frameSize;
        _fseeki64(m_file, offset, SEEK_SET);
        ret = fread(&dfh, 128, 1, m_file);
        if (0==dfh.GpioInput0) {
            m_frameBegin = i;
            break;
        }
    }

    //find end
    for (i = m_frameCount - 1; i >= 0; i--) {
        offset = m_frame0Offset + i* m_frameSize;
        _fseeki64(m_file, offset, SEEK_SET);
        ret = fread(&dfh, 128, 1, m_file);
        if (0==dfh.GpioInput0) {
            m_frameEnd = i;
            break;
        }
    }

    //
    if (m_frameBegin < m_frameEnd) {
        ret = 0;
    }
    else {
        m_frameBegin = 0;
        m_frameEnd = m_frameCount - 1;
        ret = EError_FileData;
    }
    return ret;
}

s32 CYoseenStream::splitStream(const char* fnPrefix) {
    if (m_frameBegin < 0)return EError_InvalidState;

    s32 ret, i;
    s64 offset;
    s32 frameCount = 0;
    char fn[256];
    bgra* palette = m_paletteData[xxxpalette_IronBow].data;
    FILE* f = NULL;
    s32 fileSize = 128 + m_dataPixels * 6;
    DataFrameHeader* dfh = m_data;
    s16* temp = (s16*)(m_data + 1);
    s32* bmp = (s32*)(temp + m_dataPixels);
    for (i = m_frameBegin; i <= m_frameEnd; i++) {
        offset = m_frame0Offset, i* m_frameSize;
        _fseeki64(m_file, offset, SEEK_SET);
        ret = fread(dfh, m_frameSize, 1, m_file);
        if (1 != ret) {
            ret = EError_FileRead;
            break;
        }

        strTemp2Bgra(m_alg, temp, dfh, (bgra*)bmp, palette);

        //
        snprintf(fn, 256, "%s-%05d.ir", fnPrefix, i);
        f = fopen(fn, "wb");
        if (f) {
            fwrite(dfh, fileSize, 1, f);
            fclose(f);
            frameCount++;
        }
        else {
            ret = EError_FileOpen;
            break;
        }
    }

    return frameCount;
}