#include "pagenormalizer.h"
#include <iostream>
#include <fstream>

PageNormalizer::PageNormalizer() {
    width = height = 0;
    m_quiet = false;
}

PageNormalizer::PageNormalizer(const std::string inFile,const std::string outFile,const std::string whiteRef,const std::string blackRef,const std::string settingsFile, const bool quiet ) {

    m_quiet = quiet;
    
    // Read settings from text-file
    ReadSettings( settingsFile.c_str() );
    
    inImage = CImg<>( inFile.c_str() );      // Input image (Not manipulated)

    refImages[0] = CImg<>( whiteRef.c_str() );    // White
    refImages[1] = CImg<>( blackRef.c_str() );    // Black
    

    width = inImage.width();
    height = inImage.height();

    
    if( !m_quiet ) printf("Crop:%d,%d-%d,%d\n",cropX0,cropY0,cropX1,cropY1);
    
    outImage = CImg<>(cropX1-cropX0,cropY1-cropY0,1,3);

    NormalizeImage();

    outImage.save_bmp( outFile.c_str() );
}

void PageNormalizer::NormalizeImage()
{

    for(int y=cropY0;y<cropY1;y++)
    {
        for(int x=cropX0; x<cropX1;x++) {

            int wh = GetWhiteness(x,y);
            int bh = GetBlackness(x,y);

            double whiteFactor = 255.0 / ( wh - bh );

            int ch0 = ( inImage(x,y,0,0) - bh ) * whiteFactor;
            int ch1 = ( inImage(x,y,0,1) - bh ) * whiteFactor;
            int ch2 = ( inImage(x,y,0,2) - bh ) * whiteFactor;

            if( ch0 < 0 ) ch0=0; if( ch1 < 0 ) ch1=0; if( ch2 < 0 ) ch2=0;
            if( ch0 > 255 ) ch0=255; if( ch1 > 255 ) ch1=255; if( ch2 > 255 ) ch2=255;

            outImage(x-cropX0,y-cropY0,0,0) = (unsigned char) ch0;
            outImage(x-cropX0,y-cropY0,0,1) = (unsigned char) ch1;
            outImage(x-cropX0,y-cropY0,0,2) = (unsigned char) ch2;

        }
    }

}

int PageNormalizer::GetWhiteness(unsigned int x,unsigned int y) {
    return( refImages[0](x,y,0,0) );
}
int PageNormalizer::GetBlackness(unsigned int x,unsigned int y) {
    return( refImages[1](x,y,0,0) );
}

void PageNormalizer::ReadSettings(const std::string inFile)
{
    if( !m_quiet ) std::cout << "Reading settings from: " << inFile << std::endl;
    
    std::string line;
    std::ifstream myfile( inFile.c_str() );
    if (myfile.is_open())
    {
        auto rowNum = -1;
        while( std::getline( myfile,line ) )
        {
            switch( rowNum ) {
                case -1: if( line.find("START:") == 0 ) rowNum = 0; break;
                case 1: cropX0 = std::stoi(line);break;
                case 2: cropY0 = std::stoi(line);break;
                case 3: cropX1 = std::stoi(line);break;
                case 4: cropY1 = std::stoi(line);break;
            }
            if( rowNum >= 0 ) rowNum++;
        }
        myfile.close();
    }
    else std::cout << "Unable to open file";
}
