/*
 *  
 *  $Id: waveformview.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 <list>

#include <wx/wx.h>
#include <wx/checkbox.h>
#include <wx/filename.h>
#include <wx/file.h>
#include <wx/busyinfo.h>
#include <wx/msgdlg.h>
#include <wx/xml/xml.h>
#include <wx/utils.h>

#include <api/globals.h>
#include <api/math/geometry3d.h>
#include <api/toolsystem/itoolsregistry.h>
#include <api/controllers/icontroladorvistas.h>
#include <api/controllers/icontroladorcarga.h>
#include <api/dicom/imodelodicom.h>
#include <api/dicom/idicomizador.h>
#include <api/controllers/icontroladorpermisos.h>
#include <eventos/modificacionimagen.h>
#include <eventos/modificacionfichero.h>

#include <api/imodelointegracion.h>
#include <api/controllers/imodulecontroller.h>
#include <api/controllers/icontroladorpermisos.h>
#include "../eventos/visualizatorevents.h"
#include "../estudios/visualizatorstudy.h"

#include <visualizator/widgets/wecg.h>

#include "waveformview.h"
#include "../wxvtk/gwaveformview.h"
#include "../dialogos/contenedorherramientas.h"
#include <main/entorno.h>


#ifdef __DEPRECATED
#undef __DEPRECATED
#endif
#include <vtkDataSetAttributes.h>
#include <vtkAlgorithm.h>
#include <vtkAlgorithmOutput.h>
#include <vtkImageData.h>
#include <vtkAlgorithmOutput.h>
#include <vtkInformation.h>
#include <vtkCamera.h>

/* Constructor */

GNKVisualizator::WaveFormView::WaveFormView(const GNC::GCS::Ptr<GNKVisualizator::ECGStudy>& estudio) : GNC::GCS::IVista((GNC::GCS::Ptr<GNC::GCS::IStudyContext>)estudio), VisualizatorStudy(estudio)
{
	m_Cargada = false;
	
	VisualizatorStudy->Window = GVista = new GNKVisualizator::GUI::GWaveformView(this);
}


GNKVisualizator::WaveFormView::~WaveFormView()
{
	DetenerPipeline();
}

//----------------------------------------------------------------------------------------------------
//region Interfaz de Carga


// Comienzo de carga. Metodo sincrono con la interfaz.
void GNKVisualizator::WaveFormView::OnCargaIniciada()
{
}

// Paso 1: Cargar los ficheros en memoria. Metodo NO sincrono con la interfaz.
void GNKVisualizator::WaveFormView::CargarEstudio(GNC::GCS::IComando* /*pCmdInvocador*/)
{
}

// Finalizacion de la carga. Metodo sincrono con la interfaz.
void GNKVisualizator::WaveFormView::OnCargaFinalizada()
{
	GVista->OnFinishLoad();
}

// Paso 2: Inicializacion del pipeline. Metodo sincrono con la interfaz.
void GNKVisualizator::WaveFormView::IniciarPipeline()
{
	try {
		GVista->InitPipeline();
	}
	catch (const std::bad_alloc&) {
		DetenerPipeline();
		m_Cargada = false;
		throw GNC::GCS::VistaException(_Std("Error: System out of memory. Close some studies to free memory."));
	}
	catch (GNC::GCS::VistaException&) {
		DetenerPipeline();
		m_Cargada = false;
		throw;
	}

	m_Cargada = true;

	//se conecta el evento Ginkgo
	GNC::GCS::Events::EventoModificacionFichero evtModificado;
	evtModificado.SetVista(this);

	VisualizatorStudy->ActiveFileIndex = 0;
	
	typedef GNC::GCS::Vector3D Vec;

	GVista->ViewImage2D->UpdateImage();
	
	vtkSmartPointer<vtkCamera> cam = GVista->ViewImage2D->GetRenderer()->GetActiveCamera();
	
	Vec focalPoint;
	Vec camPos;
	Vec spacing;
	Vec dims;
	Vec winsize;
	int idims[3];
	int iwinsize[2];

	GVista->ViewInteractor2D->Layout();
	GVista->ViewInteractor2D->GetParent()->Layout();

	GVista->ViewImage2D->GetSpacing(spacing.v);
	GVista->ViewImage2D->GetDimensions(idims);
	GVista->ViewInteractor2D->GetClientSize(&iwinsize[0], &iwinsize[1]);
	//((wxWindowBase* )GVista->ViewInteractor2D)->GetSize();

	dims.x = idims[0];
	dims.y = idims[1];
	winsize.x = iwinsize[0];
	winsize.y = iwinsize[1];
	
	Vec worldViewPort = (spacing * (dims + Vec(1.0, 1.0, 0.0))); // + 1.0 cause pixel centers to pixels edges conversion

	double parallelScale = worldViewPort.y / 2.0;

	GVista->ViewImage2D->SetInitialParallelScale( parallelScale );

	double rel = (winsize.x / winsize.y); // Relación ancho/alto del viewPort
	
	focalPoint = Vec( rel * (parallelScale), parallelScale, 0.0);
	camPos = focalPoint - Vec(0.0, 0.0, 1.0);

	cam->SetPosition( camPos.v );
	cam->SetFocalPoint( focalPoint.v );	
	cam->SetViewUp(0.0, -1.0, 0.0);
	cam->SetClippingRange(-2.0, 2.0);	

	//lanzo el evento de imagen cargada
	GNC::GCS::IEntorno::Instance()->GetControladorEventos()->ProcesarEvento(new GNC::GCS::Events::EventoModificacionImagen(this,GNC::GCS::Events::EventoModificacionImagen::ImagenCargada));
	/*
	GNC::GCS::IEntorno::Instance()->GetControladorHerramientas()->RefrescarHerramientas();
	*/

	GenerarTitulo();
}

// Parada del pipeline. Metodo sincrono con la interfaz Se invoca en el caso de que ocurra un error de carga.
void GNKVisualizator::WaveFormView::DetenerPipeline()
{
	GVista->StopPipeline();
}

//endregion


bool GNKVisualizator::WaveFormView::SoportaGuardar()
{
	return false;
}

bool GNKVisualizator::WaveFormView::SoportaExportar()
{
	return false;
}

void GNKVisualizator::WaveFormView::Activar()
{
	GNC::GCS::IVista::Activar();
	GVista->SetFocus();
}


wxWindow* GNKVisualizator::WaveFormView::GetWindow()
{
	return GVista;
}

void GNKVisualizator::WaveFormView::GenerarTitulo()
{
	std::ostringstream ostr;
	std::string valor;

	VisualizatorStudy->GetTagActiveImage("0010|0010",valor);
	for (std::string::iterator it = valor.begin(); it != valor.end(); ++it) {
		if ( *it == '^') {
			*it = ' ';
		}
	}
	ostr << valor.c_str() << ", ";
	VisualizatorStudy->GetTagActiveImage("0008|1030",valor);
	ostr << valor.c_str();
	if (!valor.empty()) {
		ostr << "/";
	}
	VisualizatorStudy->GetTagActiveImage("0008|103e",valor);
	ostr << valor.c_str();
	m_Titulo = ostr.str();
}

GNC::GCS::IVista* GNKVisualizator::WaveFormView::GetView()
{
	return this;
}

