#include "texturecrafter.h"

TextureCrafter::TextureCrafter(QObject *parent)
    : QObject{parent}
{}

QString TextureCrafter::getOutFilename() {
    QString outFileName;
    if (outDir.isValid()) {
        outFileName = outDir.path();
        outFileName.append("/out.png");
    } else {
        return QString();
    }

    return outFileName;
}

QUrl TextureCrafter::packChannels(QVector<QUrl> imagePaths) {

    QVector<QImage> sourceImages;
    int width = 0, height = 0;
    QImage::Format format = QImage::Format_RGB888;

    for (int i = 0; i < imagePaths.length(); i++) {
        // if the ui layer did its job this will always be a file:// url
        QString rawPath = imagePaths[i].toLocalFile();
        QImage newImage(rawPath); // would this cause a use after free idk

        // we just use the first image's dimensions and force the others to conform hehe
        if (width == 0) {
            width = newImage.width();
        }
        if (height == 0) {
            height = newImage.height();
        }

        sourceImages.append(newImage);
    }

    png_structp outPng;
    png_infop outInfo;
    FILE *outFile;
    QString outFilename = getOutFilename();
    unsigned char *rowBuffer;

    // maybe abstract this?
    outFile = fopen(outFilename.toLatin1().data(), "wb");

    if (!outFile) {
        return QUrl();
    }

    outPng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    outInfo = png_create_info_struct(outPng);
    rowBuffer = (unsigned char*)malloc(sizeof(char) * 3 * width);

    png_init_io(outPng, outFile);

    png_set_IHDR (outPng,
                outInfo,
                width,
                height,
                8, // TODO: support other bit depths someday
                PNG_COLOR_TYPE_RGB,
                PNG_INTERLACE_NONE,
                PNG_COMPRESSION_TYPE_DEFAULT,
                PNG_FILTER_TYPE_DEFAULT);

    png_write_info(outPng, outInfo);

    // do the channel packing!!
    // theres probably a faster way to do this but eh
    for (int i = 0; i < height; i++) {
        memset(rowBuffer, 0, sizeof(char) * 3 * width);
        for (int j = 0; j < width; j++) {
            unsigned char r, g, b;

            // too eepy for dry
            r = sourceImages.at(0).pixelColor(j, i).red();
            g = sourceImages.at(1).pixelColor(j, i).green();
            b = sourceImages.at(2).pixelColor(j, i).blue();

            rowBuffer[j*3+0] = r;
            rowBuffer[j*3+1] = g;
            rowBuffer[j*3+2] = b;
        }

        png_write_row(outPng, rowBuffer);
    }

    png_write_end(outPng, NULL);

    // good soldiers free their memory
    free(rowBuffer);
    png_destroy_write_struct(&outPng, &outInfo);
    fclose(outFile);
    return QUrl::fromLocalFile(outFilename);

 //    // write it to a temp file
 //    if (outDir.isValid()) {
 //        QString outFileName = outDir.path();
 //        outFileName.append("/out.png");

 //        printf("wrote to %s\n", outFileName.toLatin1().data());

    // //TODO: use libpng and do progressive write to update the progress bar
 //        if (outImage.save(outFileName)) {
 //            printf("cool ^-^\n");
 //            return QUrl::fromLocalFile(outFileName);
 //        } else {
 //            //TODO: return some error value to show the user
 //            printf("that dream is fucked it is fucking fucked\n");
 //        }
 //    } else {
 //        printf("chat its so over\n");
 //    }

    return QUrl();
    //do we need to close these??? idk lets hope qt handles it
}