//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

#include "giofx.h"

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
cFramebuffer::cFramebuffer(cScene* engine,float size,float worldSizeH,float worldSizeV)
{
	m_engine        = engine;
	m_texsize       = size;
	m_worldsizeH    = 
    m_worldsizeV    = worldSizeH;
    
    if (worldSizeV > 0)
        m_worldsizeV = worldSizeV;
    
	m_success	= false;
	m_active	= false;
	m_prerender = false;
    
	m_position.Clear();
            
#if TARGET_OS_IPHONE

	glGenFramebuffersOES(1, &m_framebuffer);
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
    
#else

	glGenFramebuffersEXT(1, &m_framebuffer);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_framebuffer);
    
#endif
	
	glGenTextures(1, &m_texture);
	glBindTexture(GL_TEXTURE_2D, m_texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //GL_NEAREST - GL_LINEAR
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_NEAREST - GL_LINEAR
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)m_texsize, (int)m_texsize, 0, GL_RGBA,GL_UNSIGNED_BYTE, NULL);
	
#if TARGET_OS_IPHONE
	
    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,GL_TEXTURE_2D, m_texture, 0);
	glGenRenderbuffersOES(1, &m_depthBuffer);
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_depthBuffer);
	glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, m_texsize,m_texsize);
	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES,GL_RENDERBUFFER_OES, m_depthBuffer);
	if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
		return;
#else
	
	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, m_texture, 0);
	glGenRenderbuffersEXT(1, &m_depthBuffer);
	glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer);
	glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, m_texsize,m_texsize);
	glFramebufferRenderbufferEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER_EXT, m_depthBuffer);
	if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) != GL_FRAMEBUFFER_COMPLETE_EXT)
		return;
		
#endif
	
	m_success = true;

}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cFramebuffer::CopyTextureInto(char* preloadTexName)
{
	float z = 0;
	float ctexCoord[]={0,1 ,1,1 ,1,0 ,0,1 ,1,0 ,0,0 };
	float cvertCoord[]={	
		0,			m_texsize,	z,
		m_texsize,	m_texsize,	z,
		m_texsize,	0,			z,
		0,			m_texsize,	z,
		m_texsize,	0,			z,
		0,			0,			z};
	
	GLuint tID = m_engine->LoadTexture(preloadTexName);
	
	SwitchToFBO(true);
	
	glEnable(GL_TEXTURE_2D);
	glColor4f(1,1,1,1);
	glBindTexture(GL_TEXTURE_2D,m_engine->pTexture[tID]->memAddr);	
	glTexCoordPointer(2, GL_FLOAT, 0, ctexCoord);
	glVertexPointer(3, GL_FLOAT, 0, cvertCoord);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	
	SwitchToMain();
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

cFramebuffer::~cFramebuffer()
{	
	m_active = false;
	glDeleteTextures(1, &m_texture);
	
#if TARGET_OS_IPHONE

	glDeleteRenderbuffersOES(1, &m_depthBuffer);
	glDeleteFramebuffersOES(1, &m_framebuffer);
    
#else

	glDeleteRenderbuffersEXT(1, &m_depthBuffer); 
	glDeleteFramebuffersEXT(1, &m_framebuffer);
    
#endif
	
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::SetActive(bool tActive)
{
	m_active = (m_success) ? tActive : false;
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::SetPrerender(bool preRendered)
{
	m_prerender = preRendered;
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::SetPosition(float px,float py,float pz)
{
	m_position.Set(px,py,pz);
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::SwitchToFBO(bool clear)
{
	if (!m_active)
		return;
	
#if TARGET_OS_IPHONE
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer);
#else
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_framebuffer);
#endif
	
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    if (clear)
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::SwitchToMain()
{

#if TARGET_OS_IPHONE
	extern GLuint	viewFramebuffer;    //da eglview
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
#else
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
#endif

}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

void cFramebuffer::Render()
{
	if (!m_active)
		return;

	float texCoord[]={0,1 ,1,1 ,1,0 ,0,1 ,1,0 ,0,0 };
	float vertCoord[]={
            -m_worldsizeH + m_position.x,	+m_worldsizeV + m_position.y,	m_position.z,
            +m_worldsizeH + m_position.x,	+m_worldsizeV + m_position.y,	m_position.z,
            +m_worldsizeH + m_position.x,	-m_worldsizeV + m_position.y,	m_position.z,
					   
            -m_worldsizeH + m_position.x,	+m_worldsizeV + m_position.y,	m_position.z,
            +m_worldsizeH + m_position.x,	-m_worldsizeV + m_position.y,	m_position.z,
            -m_worldsizeH + m_position.x,	-m_worldsizeV + m_position.y,	m_position.z};
    
    /*
    glPushMatrix();
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    m_position.x = (m_worldsize/2.0);
    m_position.y = 1.2;
    float texCoord[]={0,1 ,1,1 ,1,0 ,0,1 ,1,0 ,0,0 };
    
    float vertCoord[]={
        -m_worldsize+m_position.x,	+m_worldsize+m_position.y,	m_position.z,
        +m_worldsize+m_position.x,	+m_worldsize+m_position.y,	m_position.z,
        +m_worldsize+m_position.x,	-m_worldsize+m_position.y,	m_position.z,
					   
        -m_worldsize+m_position.x,	+m_worldsize+m_position.y,	m_position.z,
        +m_worldsize+m_position.x,	-m_worldsize+m_position.y,	m_position.z,
        -m_worldsize+m_position.x,	-m_worldsize+m_position.y,	m_position.z};
        
    //glMatrixMode(GL_MODELVIEW);
    //glPopMatrix();
    */
    
    glEnable(GL_TEXTURE_2D);
    glColor4f(1,1,1,1);
	glBindTexture(GL_TEXTURE_2D, m_texture);
	glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
    glVertexPointer(3, GL_FLOAT, 0, vertCoord);
    glDrawArrays(GL_TRIANGLES, 0, 6);

}

//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
int NewFrameBuffer(cScene* scene,float zDepth)
{
    int fbo = scene->totFrameBuffers++;

#ifdef FULLRES_DEVICE
#ifdef FULLRES_DEVICE_DEPRECATED
    
    if (scene->resolutionX == 2048)         //IPAD3/4/AIR/MINI RETINA,PRO9.7
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,1.5);
        scene->pFramebuffer[fbo]->SetPosition(0,0.375,zDepth);
	}
    else if (scene->resolutionX == 1024)    //IPAD1/2/MINI
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,1024,1.5);
        scene->pFramebuffer[fbo]->SetPosition(0,0.375,zDepth);
	}
    else if (scene->resolutionX == 2732)    //PRO12.9
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,1.5);
        scene->pFramebuffer[fbo]->SetPosition(0,0.375,zDepth);
    }
    else if (scene->resolutionX == 2224)    //PRO10.5
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,1.5);
        scene->pFramebuffer[fbo]->SetPosition(0,0.375,zDepth);
    }
    else if (scene->resolutionX == 960)    //IPHONE4 4S
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,1024,1.7);
        scene->pFramebuffer[fbo]->SetPosition(0.60,0.2,0);
    }
    else if (scene->resolutionX == 1136)    //IPHONE5 5C 5S SE
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,3.63);
        scene->pFramebuffer[fbo]->SetPosition(1.62,2.487,zDepth);
	}
    else if (scene->resolutionX == 1334)    //IPHONE6 6S 7 8
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,3.63);
        scene->pFramebuffer[fbo]->SetPosition(1.62,2.487,zDepth);
    }
    else if (scene->resolutionX == 1920)    //IPHONE6+ 7+ 8+
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,3.63);
        scene->pFramebuffer[fbo]->SetPosition(1.62,2.487,zDepth);
    }
    else if (scene->resolutionX == 1704 || scene->resolutionX == 2436)    //IPHONEX
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,4096,3.63,4.3);
        scene->pFramebuffer[fbo]->SetPosition(1.62,3.10,zDepth);
    }
    else
    {
        scene->pFramebuffer[fbo] = new cFramebuffer(scene,2048,3.63);
        scene->pFramebuffer[fbo]->SetPosition(1.62,2.487,zDepth);
	}

    //TODO
    //printf("device %d x %d FBO %d\n", scene->resolutionX, scene->resolutionY, fbo);
    
    scene->pFramebuffer[fbo]->SetPrerender(true);
    scene->pFramebuffer[fbo]->SetActive(true);
    
#endif
#endif

    return fbo;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------



