/*
 *  
 *  $Id: anonymizedialog.cpp $
 *  Ginkgo CADx Project
 *
 *  Copyright 2008-12 MetaEmotion S.L. All rights reserved.
 *  http://ginkgo-cadx.com
 *
 *  This file is licensed under LGPL v3 license.
 *  See License.txt for details
 *
 *
 */
#include "anonymizedialog.h"
#include <api/dicom/idicommanager.h>
#include <main/entorno.h>
#include <api/ientorno.h>
#include <api/controllers/icontroladorlog.h>
#include <api/controllers/ipacscontroller.h>
#include <api/controllers/ipacscontroller.h>
#include <api/controllers/icommandscontroller.h>
#include <main/controllers/historycontroller.h>
#include <commands/comandoexportacion.h>


GNC::GUI::AnonymizeDialog::AnonymizeDialog(wxWindow* pParent, const std::list<long>& seriesPk): GNC::GUI::AnonymizeDialogBase(pParent)
{
	m_pDatosPersistentes = new TipoWizardExportacion();
	m_pDatosPersistentes->ListOfSeriesPks = seriesPk;

	if (seriesPk.empty()) {
		LOG_ERROR("AnonymizeDialog", "you have to select at least one series to anonymize");
	} else {

		GNC::GCS::HistoryController::FileModelList fileModels;
		GNC::GCS::HistoryController::Instance()->GetSeriesSortedFileModels(seriesPk.front(), fileModels);

		GIL::DICOM::IDICOMManager*	pDICOMManager = GNC::GCS::IEntorno::Instance()->GetPACSController()->CrearInstanciaDeDICOMManager();
		pDICOMManager->CargarFichero(fileModels.front().real_path, m_base);
		SetTags(m_base, m_pTagsList->GetRoot(), pDICOMManager);
		GNC::Entorno::Instance()->GetPACSController()->LiberarInstanciaDeDICOMManager(pDICOMManager);
	}

	wxCommandEvent evt;
	OnCheckNombreApellidos(evt);
	OnCheckIdPaciente(evt);
	OnCheckInstituciones(evt);
	OnCheckPhysician(evt);
	OnCheckComentarios(evt);

	m_pTagsList->Connect(wxEVT_PG_CHANGED,wxPropertyGridEventHandler(AnonymizeDialog::OnPropertyChanged),NULL,this);
	m_pTagsList->Connect(wxEVT_PG_DOUBLE_CLICK,wxPropertyGridEventHandler(AnonymizeDialog::OnPropertyDobleClick),NULL,this);
}

GNC::GUI::AnonymizeDialog::~AnonymizeDialog()
{
	m_pTagsList->Disconnect(wxEVT_PG_CHANGED,wxPropertyGridEventHandler(AnonymizeDialog::OnPropertyChanged),NULL,this);
	m_pTagsList->Disconnect(wxEVT_PG_DOUBLE_CLICK,wxPropertyGridEventHandler(AnonymizeDialog::OnPropertyDobleClick),NULL,this);
}

void GNC::GUI::AnonymizeDialog::SetTags(GIL::DICOM::DicomDataset & base,wxPGPropArg idPadre,GIL::DICOM::IDICOMManager*	pDICOMManager) 
{
	for(GIL::DICOM::ListaTags::iterator it = base.tags.begin(); it!= base.tags.end(); ++it){
		wxString helpString = wxString::FromUTF8(pDICOMManager->GetDescription((*it).first).c_str());
		wxStringProperty* prop = NULL;
		wxString valor;
		if((*it).second.size()>100) {
			valor=wxT("Datos");
		} else {
			valor = wxString::FromUTF8((*it).second.c_str());
		}

		if(helpString.size()>0){
			helpString = wxT("(") + wxString::FromUTF8((*it).first.c_str()) + wxT(") ") + helpString;
			prop = new wxStringProperty(helpString,
				wxPG_LABEL,valor);
		}else{
			prop = new wxStringProperty(wxString::FromUTF8((*it).first.c_str()),
				wxPG_LABEL,valor);
		}
		prop->SetHelpString(wxString::FromUTF8((*it).first.c_str()));
		m_pTagsList->AppendIn(idPadre, prop);
	}

	for(GIL::DICOM::DicomDataset::DatasetList::iterator it = base.secuencias.begin(); it!=base.secuencias.end(); ++it){
		wxStringProperty* prop = NULL;
		wxString helpString = wxString::FromUTF8(pDICOMManager->GetDescription((*it).tagName).c_str());
		if(helpString.size()>0){
			helpString = wxT("(") + wxString::FromUTF8((*it).tagName.c_str()) + wxT(") ") + helpString;
			prop = new wxStringProperty(helpString,
				wxPG_LABEL,wxEmptyString);
		}else{
			prop = new wxStringProperty(wxString::FromUTF8((*it).tagName.c_str()),
				wxPG_LABEL,wxEmptyString);
		}
		prop->SetHelpString(wxString::FromUTF8((*it).tagName.c_str()));
		if(m_pTagsList->GetProperty(prop->GetName()) != NULL) {
			////////////////////////////////////std::cout<<"hasdfasdf";
		}
		wxPGId pIdSequencia = m_pTagsList->AppendIn(idPadre,prop);

		//recursion
		int i=0;
		for(GIL::DICOM::DicomDataset::DatasetList::iterator it2 = (*it).items.begin(); it2!= (*it).items.end(); ++it2, ++i) {
			wxPGPropArg pIdItem = m_pTagsList->AppendIn(pIdSequencia,new wxStringProperty(wxString::Format(wxT("Item %d"),i),wxPG_LABEL,wxEmptyString));
			SetTags((*it2),pIdItem,pDICOMManager);
		}
	}
}

void GNC::GUI::AnonymizeDialog::OnCheckNombreApellidos( wxCommandEvent& /*event*/ )
{
	//se anonimiza 0010|0010 (nombre del paciente)
	std::string clave("0010|0010");
	Anonymize(clave,m_pCheckNombrePaciente->IsChecked());
}

void GNC::GUI::AnonymizeDialog::OnCheckIdPaciente( wxCommandEvent& /*event*/ )
{
	//se anonimiza 0010|0020" (id del paciente)
	std::string clave("0010|0020");
	Anonymize(clave,m_pCheckIdPaciente->IsChecked());
}

void GNC::GUI::AnonymizeDialog::OnCheckInstituciones( wxCommandEvent& /*event*/ )
{
	//se anonimiza (0008,0080) Institution Name
	std::string clave("0008|0080");
	Anonymize(clave,m_pCheckInstituciones->IsChecked());
}

void GNC::GUI::AnonymizeDialog::OnCheckPhysician( wxCommandEvent& /*event*/ )
{
	//referring physician name
	std::string clave("0008|0090");
	Anonymize(clave,m_pReferringPhysician->IsChecked());
}

void GNC::GUI::AnonymizeDialog::OnCheckComentarios( wxCommandEvent& /*event*/ )
{
	//descripcion del estudio, serie e imagenes
	//estudio
	{
		std::string clave("0008|1030");
		Anonymize(clave,m_pCheckComentarios->IsChecked());
	}
	//serie
	{
		std::string clave("0008|103e");
		Anonymize(clave,m_pCheckComentarios->IsChecked());
	}
	//imagen
	{
		std::string clave("0020|4000");
		Anonymize(clave,m_pCheckComentarios->IsChecked());
	}
}

void GNC::GUI::AnonymizeDialog::Anonymize(std::string& clave, bool anonimizar)
{
	wxString value = wxEmptyString;

	if(!anonimizar){
		std::string tmp;
		if(m_base.getTag(clave,tmp)){
			value = wxString::FromUTF8(tmp.c_str());
		}
	}

	for(wxPGProperty* it=m_pTagsList->GetFirst();it!=NULL;it=m_pTagsList->GetNextSiblingProperty(it)){
		if(it->GetHelpString() == wxString::FromUTF8(clave.c_str())){
			it->SetValueFromString(value);
			if(anonimizar){
				m_pTagsList->SetPropertyCell(it->GetId(),0,it->GetLabel(),wxNullBitmap,*wxWHITE,*wxRED);
				m_pTagsList->SetPropertyCell(it->GetId(),1,it->GetValue(),wxNullBitmap,*wxWHITE,*wxRED);
			}else{
				m_pTagsList->SetPropertyCell(it->GetId(),0,it->GetLabel());
				m_pTagsList->SetPropertyCell(it->GetId(),1,it->GetValue());
			}
			it->ChangeFlag(wxPG_PROP_MODIFIED,anonimizar);
			m_pTagsList->RefreshProperty(it);
			return;
		}
	}
}

void GNC::GUI::AnonymizeDialog::GetTagsAnonymized(GIL::DICOM::DicomDataset & base)
{
	base.tags.clear();
	for(wxPGProperty* it=m_pTagsList->GetFirst();it!=NULL;it=m_pTagsList->GetNextSiblingProperty(it)){
		if(it->IsFlagSet(wxPG_PROP_MODIFIED)){
			std::string clave(it->GetHelpString().ToUTF8());
			std::string valor(it->GetValueAsString().ToUTF8());
			base.tags[clave] = valor;
		}
	}
}

void GNC::GUI::AnonymizeDialog::OnPropertyChanged(wxPropertyGridEvent& event)
{
	wxPGProperty* selected= event.GetProperty();
	m_pTagsList->SetPropertyCell(selected->GetId(),0,selected->GetLabel(),wxNullBitmap,*wxWHITE,*wxRED);
	m_pTagsList->SetPropertyCell(selected->GetId(),1,selected->GetValue(),wxNullBitmap,*wxWHITE,*wxRED);
}

void GNC::GUI::AnonymizeDialog::OnPropertyDobleClick(wxPropertyGridEvent& event)
{
	std::string clave(event.GetProperty()->GetHelpString().ToUTF8());
	Anonymize(clave,!event.GetProperty()->IsFlagSet(wxPG_PROP_MODIFIED));
}

void GNC::GUI::AnonymizeDialog::OnOverwriteClick(wxCommandEvent &)
{
	LaunchCommand(true);
}

void GNC::GUI::AnonymizeDialog::OnCreateNewClick(wxCommandEvent &)
{
	LaunchCommand(false);
}

void GNC::GUI::AnonymizeDialog::LaunchCommand(bool overwrite)
{
	if (overwrite) {
		m_pDatosPersistentes->m_target = GNC::GUI::TipoWizardExportacion::OVERWRITE;
	} else {
		m_pDatosPersistentes->m_target = GNC::GUI::TipoWizardExportacion::NEW_STUDY;
	}
	m_pDatosPersistentes->m_formatoDestino = DICOM;
	GetTagsAnonymized(m_pDatosPersistentes->m_base);
	m_pDatosPersistentes->m_incluirTagsGinkgo = !m_pCheckAtributosPrivadosGinkgo->IsChecked();

	m_pDatosPersistentes->m_incluirWidgets = false;

	GADAPI::ComandoExportacionParams* pParams = new GADAPI::ComandoExportacionParams(m_pDatosPersistentes);
	GADAPI::ComandoExportacion* pCmd = new GADAPI::ComandoExportacion(pParams);
	GNC::GCS::IControladorComandos::Instance()->ProcessAsync(_Std("Exporting images ..."), pCmd, NULL);
	this->Close();
}

