/*
* Author: Chris Campbell - www.iforce2d.net
*
* This software is provided 'as-is', without any express or implied
* warranty.  In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/

#include <cstring>
#include "b2dJsonImage_OpenGL.h"
#include "bitmap.h"

using namespace std;

#ifndef DEGTORAD
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
#endif

b2dJsonImage_OpenGL::b2dJsonImage_OpenGL(const b2dJsonImage *other) : b2dJsonImage(other)
{
    m_textureId = 0;
    loadImage();
}

bool checkFileExtension(string s, string ext) 
{
	int extStartPos = s.length() - ext.length();
	if ( extStartPos <= 0 )
		return false;
	return s.substr( extStartPos ) == ext;	
}

bool b2dJsonImage_OpenGL::loadImage()
{
    //clear any existing texture
    if ( m_textureId ) {
        glDeleteTextures(1, &m_textureId);
        m_textureId = 0;
    }

    if ( checkFileExtension(m_file, ".bmp") || checkFileExtension(m_file, ".BMP") )
    {
        //use bitmap.h to load bitmap with transparency (https://bugreports.qt-project.org/browse/QTBUG-22031)
        CBitmap bitmap;
        if ( ! bitmap.Load(m_file.c_str()) ) {
            printf("Could not load image file '%s'\n", m_file.c_str());
            return false;
        }

        int width = bitmap.GetWidth();
        int height = bitmap.GetHeight();
        unsigned int size = 0;
        bitmap.GetBits(NULL, size, 0,0,0,0);//get necessary buffer size
        GLubyte* pixels = new unsigned char[bitmap.GetWidth()*bitmap.GetHeight()*size];
        bitmap.GetBits(pixels, size, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000);
        glGenTextures(1, &m_textureId);
        glBindTexture(GL_TEXTURE_2D, m_textureId);
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        if ( m_filter == FT_LINEAR )
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        else
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

		//flip image vertically
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height/2; y++) {
                int indA = y * width + x;
                int indB = (height-y-1) * width + x;
                b2Swap( pixels[ indA*4 + 0 ], pixels[ indB*4 + 0] );
                b2Swap( pixels[ indA*4 + 1 ], pixels[ indB*4 + 1] );
                b2Swap( pixels[ indA*4 + 2 ], pixels[ indB*4 + 2] );
                b2Swap( pixels[ indA*4 + 3 ], pixels[ indB*4 + 3] );
            }
        }
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmap.GetWidth(), bitmap.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
        delete[] pixels;

        return true;
    }
    /*else
    {
        //use Qt to load PNG
        QImage image( file.c_str() );
        if ( image.isNull() ) {
            printf("Could not load image file '%s'\n", file.c_str());
            return false;
        }

        glGenTextures(1, &m_textureId);
        glBindTexture(GL_TEXTURE_2D, m_textureId);
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        if ( filter == FT_LINEAR )
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        else
            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

        GLubyte* pixels = new GLubyte[image.width() * image.height() * 4];
        for (int x = 0; x < image.width(); x++) {
            for (int y = 0; y < image.height(); y++) {
                int dstInd = y * image.width() + x;
                QRgb rgb = image.pixel(x, y);
                pixels[ dstInd*4 + 0 ] = qRed(rgb);
                pixels[ dstInd*4 + 1 ] = qGreen(rgb);
                pixels[ dstInd*4 + 2 ] = qBlue(rgb);
                pixels[ dstInd*4 + 3 ] = qAlpha(rgb);
            }
        }
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
        delete[] pixels;
        return true;
    }*/

    return false;
}

void b2dJsonImage_OpenGL::renderUsingCorners()
{
    glEnable(GL_TEXTURE_2D);

    glEnable(GL_BLEND);

    glBindTexture(GL_TEXTURE_2D, m_textureId);
    //glColor4f(1,1,1,opacity); //this will use opacity defined in RUBE
    glColor3f(1,1,1);

    glPushMatrix();

    if ( m_body ) {
        b2Vec2 bodyPos = m_body->GetPosition();
        glTranslatef(bodyPos.x, bodyPos.y, 0);
        glRotatef(m_body->GetAngle()*RADTODEG, 0,0,1);
    }

    float lx = 0, ux = 1;
    if ( m_flip ) {
        lx = 1;
        ux = 0;
    }

    glBegin(GL_TRIANGLE_FAN);
    glTexCoord2f(lx,1);
    glVertex2f(m_corners[0].x, m_corners[0].y);
    glTexCoord2f(ux,1);
    glVertex2f(m_corners[1].x, m_corners[1].y);
    glTexCoord2f(ux,0);
    glVertex2f(m_corners[2].x, m_corners[2].y);
    glTexCoord2f(lx,0);
    glVertex2f(m_corners[3].x, m_corners[3].y);
    glEnd();

    glPopMatrix();

    glDisable(GL_TEXTURE_2D);
}

void b2dJsonImage_OpenGL::renderUsingArrays()
{
}




