/*
*  
*  $Id: icontexto.cpp $
*  Ginkgo CADx Project
*
*  Copyright 2008-14 MetaEmotion S.L. All rights reserved.
*  http://ginkgo-cadx.com
*
*  This file is licensed under LGPL v3 license.
*  See License.txt for details
*
*/

#include <cstdlib>

#include "icontexto.h"
#include <api/math/geometry3d.h>
#include <vtk/vtkginkgoimageviewer.h>

#include <cairo/cairo.h>


#ifdef __DEPRECATED
#undef __DEPRECATED
#endif

GNC::GCS::Contexto3D::Contexto3D(TipoProyeccion proyeccion)
{
	
	tipoProyeccion = proyeccion;
	pWindow = NULL;
	pRenderer = NULL;
	pixelData = NULL;
	cr = NULL;
	cs = NULL;
	pOffscrenViewer = NULL;
	offscreenCreado = false;
	OVID = 0;
	Reset();
	
}
GNC::GCS::Contexto3D::~Contexto3D()
{
	Reset();
}

void GNC::GCS::Contexto3D::Reset()
{
	
	ancho           = 0;
	flipHorizontal  = false;
	flipVertical    = false;
	alto            = 0;
	rotacion        = 0;
	spacing[0] = spacing[1] = spacing[2] = 1.0f;
	origin[0] = origin[1] = origin[2] = 0.0f;
	m_RelacionMundoPantallaOffscreen.Asignar(1.0f, 1.0f);
	m_RelacionImagenPantalla.Asignar(1.0f, 1.0f);
	ScreenDirectionCosines[0].Asignar(1.0, 0.0);
	ScreenDirectionCosines[1].Asignar(0.0, 1.0);

	OVID            = 0;
	if ( offscreenCreado) {
		DestruirOffscreen();
	}
}

void GNC::GCS::Contexto3D::SetupImageScreenRel(double relX, double relY, double /*relZ*/)
{
	//GNC::GCS::Vector3D vrel(relX, relY, relZ);
	//std::cout << "Rel : " << vrel << std::endl;
	m_RelacionImagenPantalla.Asignar(relX, relY);
}

GNC::GCS::Vector& GNC::GCS::Contexto3D::RefRelacionImagenPantalla() {
	return m_RelacionImagenPantalla;
}

const GNC::GCS::Vector& GNC::GCS::Contexto3D::RelacionImagenPantalla() const {
	return m_RelacionImagenPantalla;
}

GNC::GCS::Vector& GNC::GCS::Contexto3D::RefRelacionMundoPantallaOffscreen() {
	return m_RelacionMundoPantallaOffscreen;
}

const GNC::GCS::Vector& GNC::GCS::Contexto3D::RelacionMundoPantallaOffscreen() const {
	return m_RelacionMundoPantallaOffscreen;
}

bool GNC::GCS::Contexto3D::IsOk() const {
	return ancho > 0 && alto > 0 && pWindow != NULL && pRenderer != NULL;
}

GNC::GCS::IWidgetsRenderer* GNC::GCS::Contexto3D::GetRenderer() const {
	return pRenderer;
}


void GNC::GCS::Contexto3D::CrearOffscreen()
{
	
	if (offscreenCreado) {
		DestruirOffscreen();
	}

	if (ancho == 0 || alto == 0) {
		return;
	}
	

	const int numCanales = 4;
	int rowStride = ancho * numCanales;
	pixelData = (unsigned char*)std::calloc(rowStride, alto);

	if (pixelData == NULL) {
		return;
	}

	cs = cairo_image_surface_create_for_data(pixelData, CAIRO_FORMAT_ARGB32, ancho, alto, rowStride);
	if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
		std::cerr << "Error al crear surface" << std::endl;
		cairo_surface_destroy(cs);
		cs =  NULL;
		free(pixelData);
		pixelData = NULL;
		return;
	}
	
	else {
		cr = cairo_create(cs);
		if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
			cairo_destroy(cr);
			cr = NULL;
			cairo_surface_destroy(cs);
			cs = NULL;
			free(pixelData);
			pixelData = NULL;
			return;
		}
	}
	
	//relacion mundo/pantalla
	m_RelacionMundoPantallaOffscreen = GNC::GCS::Vector( ancho, alto) * (1.0f/720.0f);
	
	factorReescalado = GNC::GCS::Vector::Unidad();
	offscreenCreado = true;
}

void GNC::GCS::Contexto3D::DestruirOffscreen()
{
	
	if (!offscreenCreado) {
		return;
	}
	if (cr != NULL) {
		cairo_destroy(cr);
		cr = NULL;
	}
	if (cs != NULL) {
		cairo_surface_destroy(cs);
		cs = NULL;
	}
	if (pixelData != NULL) {
		free(pixelData);
		pixelData = NULL;
	}

	offscreenCreado = false;
	
}

GNC::GCS::Vector GNC::GCS::Contexto3D::Reproyectar(const GNC::GCS::Vector& v)
{

	GNC::GCS::Vector vp = v;

	return vp;
}

